diff mbox series

[committed] d: Merge upstream dmd, druntime a45f4e9f43, phobos 106038f2e.

Message ID 20230626000415.277265-1-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] d: Merge upstream dmd, druntime a45f4e9f43, phobos 106038f2e. | expand

Commit Message

Iain Buclaw June 26, 2023, 12:04 a.m. UTC
Hi,

This patch merges the D front-end and run-time library with upstream dmd
5f7552bb28, and standard library with phobos 106038f2e.

Synchronizing with the latest bug fixes in the v2.103.1 release.

D front-end changes:

	- Import dmd v2.103.1.
	- Deprecated invalid special token sequences inside token strings.

D runtime changes:

	- Import druntime v2.103.1.

Phobos changes:

	- Import phobos v2.103.1.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32,
committed to mainline, and backported to releases/gcc-13.

Regards,
Iain.

---
gcc/d/ChangeLog:

	* dmd/MERGE: Merge upstream dmd a45f4e9f43.
	* dmd/VERSION: Bump version to v2.103.1.

libphobos/ChangeLog:

	* libdruntime/MERGE: Merge upstream druntime a45f4e9f43.
	* src/MERGE: Merge upstream phobos 106038f2e.
---
 gcc/d/dmd/MERGE                               |   2 +-
 gcc/d/dmd/VERSION                             |   2 +-
 gcc/d/dmd/aggregate.h                         |  10 +-
 gcc/d/dmd/attrib.h                            |  12 +-
 gcc/d/dmd/common/outbuffer.h                  |   6 +-
 gcc/d/dmd/cond.d                              |   3 -
 gcc/d/dmd/cond.h                              |   2 +-
 gcc/d/dmd/cppmangle.d                         |  11 +-
 gcc/d/dmd/declaration.h                       |  12 +-
 gcc/d/dmd/dsymbol.h                           |   4 +-
 gcc/d/dmd/dsymbolsem.d                        |  13 +-
 gcc/d/dmd/expression.h                        |  50 ++++----
 gcc/d/dmd/expressionsem.d                     |  22 +++-
 gcc/d/dmd/globals.h                           | 112 +++++++++---------
 gcc/d/dmd/hdrgen.d                            |   5 +-
 gcc/d/dmd/identifier.h                        |   2 +-
 gcc/d/dmd/init.h                              |   8 +-
 gcc/d/dmd/lexer.d                             |  26 +++-
 gcc/d/dmd/module.h                            |   8 +-
 gcc/d/dmd/mtype.h                             |   4 +-
 gcc/d/dmd/objc.h                              |   6 +-
 gcc/d/dmd/root/dcompat.h                      |  10 +-
 gcc/d/dmd/root/optional.h                     |   4 +-
 gcc/d/dmd/scope.h                             |   4 +-
 gcc/d/dmd/statement.h                         |  24 ++--
 gcc/d/dmd/statementsem.d                      |   8 +-
 gcc/d/dmd/target.h                            |  20 ++--
 gcc/d/dmd/template.h                          |  14 +--
 gcc/d/dmd/visitor.h                           |   3 +-
 gcc/testsuite/gdc.test/compilable/shared.d    |  66 +++++++----
 gcc/testsuite/gdc.test/compilable/test22739.d |  10 ++
 gcc/testsuite/gdc.test/compilable/test23799.d |  37 ++++++
 .../gdc.test/fail_compilation/bug9631.d       |   2 +-
 .../gdc.test/fail_compilation/cerrors.d       |  16 ++-
 .../gdc.test/fail_compilation/fail17646.d     |   2 +-
 .../gdc.test/fail_compilation/fail19948.d     |   2 +-
 .../gdc.test/fail_compilation/fail22857.d     |  18 +++
 .../gdc.test/fail_compilation/fail23816.d     |  16 +++
 .../fail_compilation/imports/import22857.d    |   4 +
 .../gdc.test/fail_compilation/shared.d        |  19 +++
 .../gdc.test/fail_compilation/test21164.d     |   3 +-
 gcc/testsuite/gdc.test/runnable/complex3.d    |  31 +++++
 libphobos/libdruntime/MERGE                   |   2 +-
 .../libdruntime/core/sys/windows/stacktrace.d |   2 +
 libphobos/src/MERGE                           |   2 +-
 libphobos/src/std/functional.d                |   3 +
 46 files changed, 435 insertions(+), 207 deletions(-)
 create mode 100644 gcc/testsuite/gdc.test/compilable/test22739.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test23799.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail22857.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23816.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/import22857.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/complex3.d
diff mbox series

Patch

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 986925e8bdc..1205cd941b7 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@ 
-5f7552bb2829b75d5e36cc767a476e1ab35147b7
+a45f4e9f43e9fdbf0b666175e5e66b1ce4f561f6
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION
index da496a2ceeb..8316aafdaca 100644
--- a/gcc/d/dmd/VERSION
+++ b/gcc/d/dmd/VERSION
@@ -1 +1 @@ 
-v2.103.0-rc.1
+v2.103.1
diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h
index 04e5eb2f0d9..03fe478685c 100644
--- a/gcc/d/dmd/aggregate.h
+++ b/gcc/d/dmd/aggregate.h
@@ -108,8 +108,8 @@  public:
     Expression *getRTInfo;      // pointer to GC info generated by object.RTInfo(this)
 
     Visibility visibility;
-    bool noDefaultCtor;         // no default construction
-    bool disableNew;            // disallow allocations using `new`
+    d_bool noDefaultCtor;         // no default construction
+    d_bool disableNew;            // disallow allocations using `new`
     Sizeok sizeok;              // set when structsize contains valid data
 
     virtual Scope *newScope(Scope *sc);
@@ -269,10 +269,10 @@  public:
                                         // their own vtbl[]
 
     TypeInfoClassDeclaration *vclassinfo;       // the ClassInfo object for this ClassDeclaration
-    bool com;                           // true if this is a COM class (meaning it derives from IUnknown)
-    bool stack;                         // true if this is a scope class
+    d_bool com;                           // true if this is a COM class (meaning it derives from IUnknown)
+    d_bool stack;                         // true if this is a scope class
     int cppDtorVtblIndex;               // slot reserved for the virtual destructor [extern(C++)]
-    bool inuse;                         // to prevent recursive attempts
+    d_bool inuse;                         // to prevent recursive attempts
 
     ThreeState isabstract;              // if abstract class
     Baseok baseok;                      // set the progress of base classes resolving
diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h
index 44ceb12e0d0..113653e9d7c 100644
--- a/gcc/d/dmd/attrib.h
+++ b/gcc/d/dmd/attrib.h
@@ -132,7 +132,7 @@  public:
 class AnonDeclaration final : public AttribDeclaration
 {
 public:
-    bool isunion;
+    d_bool isunion;
     int sem;                    // 1 if successful semantic()
     unsigned anonoffset;        // offset of anonymous struct
     unsigned anonstructsize;    // size of anonymous struct
@@ -175,8 +175,8 @@  class StaticIfDeclaration final : public ConditionalDeclaration
 {
 public:
     ScopeDsymbol *scopesym;
-    bool addisdone;
-    bool onStack;
+    d_bool addisdone;
+    d_bool onStack;
 
     StaticIfDeclaration *syntaxCopy(Dsymbol *s) override;
     Dsymbols *include(Scope *sc) override;
@@ -193,8 +193,8 @@  class StaticForeachDeclaration final : public AttribDeclaration
 public:
     StaticForeach *sfe;
     ScopeDsymbol *scopesym;
-    bool onStack;
-    bool cached;
+    d_bool onStack;
+    d_bool cached;
     Dsymbols *cache;
 
     StaticForeachDeclaration *syntaxCopy(Dsymbol *s) override;
@@ -227,7 +227,7 @@  public:
     Expressions *exps;
 
     ScopeDsymbol *scopesym;
-    bool compiled;
+    d_bool compiled;
 
     CompileDeclaration *syntaxCopy(Dsymbol *s) override;
     void addMember(Scope *sc, ScopeDsymbol *sds) override;
diff --git a/gcc/d/dmd/common/outbuffer.h b/gcc/d/dmd/common/outbuffer.h
index b672842e74d..4c1dceea3f6 100644
--- a/gcc/d/dmd/common/outbuffer.h
+++ b/gcc/d/dmd/common/outbuffer.h
@@ -21,11 +21,11 @@  struct OutBuffer
 private:
     DArray<unsigned char> data;
     d_size_t offset;
-    bool notlinehead;
+    d_bool notlinehead;
     void *fileMapping;  // pointer to a file mapping object not used on the C++ side
 public:
-    bool doindent;
-    bool spaces;
+    d_bool doindent;
+    d_bool spaces;
     int level;
 
     OutBuffer()
diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d
index c0c4cf1ce82..c40936c78d1 100644
--- a/gcc/d/dmd/cond.d
+++ b/gcc/d/dmd/cond.d
@@ -935,9 +935,6 @@  extern (C++) final class StaticIfCondition : Condition
             import dmd.staticcond;
             bool errors;
 
-            if (!exp)
-                return errorReturn();
-
             bool result = evalStaticCondition(sc, exp, exp, errors);
 
             // Prevent repeated condition evaluation.
diff --git a/gcc/d/dmd/cond.h b/gcc/d/dmd/cond.h
index 422a715bdba..45094d14991 100644
--- a/gcc/d/dmd/cond.h
+++ b/gcc/d/dmd/cond.h
@@ -52,7 +52,7 @@  public:
     ForeachStatement *aggrfe;
     ForeachRangeStatement *rangefe;
 
-    bool needExpansion;
+    d_bool needExpansion;
 
     StaticForeach *syntaxCopy();
 };
diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d
index b015a642b90..32b38518953 100644
--- a/gcc/d/dmd/cppmangle.d
+++ b/gcc/d/dmd/cppmangle.d
@@ -213,6 +213,11 @@  private final class CppMangleVisitor : Visitor
     {
         auto tf = cast(TypeFunction)this.context.res.asFuncDecl().type;
         Type rt = preSemantic.nextOf();
+        // https://issues.dlang.org/show_bug.cgi?id=22739
+        // auto return type means that rt is null.
+        // if so, just pick up the type from the instance
+        if (!rt)
+            rt = tf.nextOf();
         if (tf.isref)
             rt = rt.referenceTo();
         auto prev = this.context.push(tf.nextOf());
@@ -560,7 +565,11 @@  private final class CppMangleVisitor : Visitor
                 foreach (j; i .. (*ti.tiargs).length)
                 {
                     Type t = isType((*ti.tiargs)[j]);
-                    assert(t);
+                    if (t is null)
+                    {
+                        ti.error("internal compiler error: C++ `%s` template value parameter is not supported", (*ti.tiargs)[j].toChars());
+                        fatal();
+                    }
                     t.accept(this);
                 }
 
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index cd4155d0fbb..d75f64f0766 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -167,8 +167,8 @@  class TupleDeclaration final : public Declaration
 public:
     Objects *objects;
     TypeTuple *tupletype;       // !=NULL if this is a type tuple
-    bool isexp;                 // true: expression tuple
-    bool building;              // it's growing in AliasAssign semantic
+    d_bool isexp;                 // true: expression tuple
+    d_bool building;              // it's growing in AliasAssign semantic
 
     TupleDeclaration *syntaxCopy(Dsymbol *) override;
     const char *kind() const override;
@@ -607,7 +607,7 @@  public:
 
     // set if someone took the address of this function
     int tookAddressOf;
-    bool requiresClosure;               // this function needs a closure
+    d_bool requiresClosure;               // this function needs a closure
 
     // local variables in this function which are referenced by nested functions
     VarDeclarations closureVars;
@@ -742,7 +742,7 @@  class FuncAliasDeclaration final : public FuncDeclaration
 {
 public:
     FuncDeclaration *funcalias;
-    bool hasOverloads;
+    d_bool hasOverloads;
 
     FuncAliasDeclaration *isFuncAliasDeclaration() override { return this; }
     const char *kind() const override;
@@ -758,7 +758,7 @@  public:
     Type *treq;                         // target of return type inference
 
     // backend
-    bool deferToObj;
+    d_bool deferToObj;
 
     FuncLiteralDeclaration *syntaxCopy(Dsymbol *) override;
     bool isNested() const override;
@@ -778,7 +778,7 @@  public:
 class CtorDeclaration final : public FuncDeclaration
 {
 public:
-    bool isCpCtor;
+    d_bool isCpCtor;
     CtorDeclaration *syntaxCopy(Dsymbol *) override;
     const char *kind() const override;
     const char *toChars() const override;
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index 1cee456aa10..039a28871b3 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -172,7 +172,7 @@  struct FieldState
     unsigned fieldAlign;
     unsigned bitOffset;
 
-    bool inFlight;
+    d_bool inFlight;
 };
 
 struct DsymbolAttributes;
@@ -189,7 +189,7 @@  public:
 private:
     DsymbolAttributes* atts;
 public:
-    bool errors;                // this symbol failed to pass semantic()
+    d_bool errors;                // this symbol failed to pass semantic()
     PASS semanticRun;
     unsigned short localNum;        // perturb mangled name to avoid collisions with those in FuncDeclaration.localsymtab
     static Dsymbol *create(Identifier *);
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 6697ad6d4d6..0f0ed2adec7 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -1383,10 +1383,14 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
         imp.semanticRun = PASS.semantic;
 
         // Load if not already done so
-        bool loadErrored = false;
         if (!imp.mod)
         {
-            loadErrored = imp.load(sc);
+            // https://issues.dlang.org/show_bug.cgi?id=22857
+            // if parser errors occur when loading a module
+            // we should just stop compilation
+            if (imp.load(sc))
+                return;
+
             if (imp.mod)
             {
                 imp.mod.importAll(null);
@@ -1427,10 +1431,7 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
                 imp.addPackageAccess(scopesym);
             }
 
-            if (!loadErrored)
-            {
-                imp.mod.dsymbolSemantic(null);
-            }
+            imp.mod.dsymbolSemantic(null);
 
             if (imp.mod.needmoduleinfo)
             {
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index e4716c8dfcf..1bc78e7ef2a 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -81,7 +81,7 @@  class Expression : public ASTNode
 public:
     EXP op;                     // to minimize use of dynamic_cast
     unsigned char size;         // # of bytes in Expression so we can copy() it
-    bool parens;                // if this is a parenthesized expression
+    d_bool parens;                // if this is a parenthesized expression
     Type *type;                 // !=NULL means that semantic() has been run
     Loc loc;                    // file location
 
@@ -331,7 +331,7 @@  class DsymbolExp final : public Expression
 {
 public:
     Dsymbol *s;
-    bool hasOverloads;
+    d_bool hasOverloads;
 
     DsymbolExp *syntaxCopy() override;
     bool isLvalue() override;
@@ -422,7 +422,7 @@  public:
     Expression *basis;
     Expressions *elements;
     OwnedBy ownedByCtfe;
-    bool onstack;
+    d_bool onstack;
 
     static ArrayLiteralExp *create(const Loc &loc, Expressions *elements);
     static void emplace(UnionExp *pue, const Loc &loc, Expressions *elements);
@@ -476,8 +476,8 @@  public:
      */
     int stageflags;
 
-    bool useStaticInit;         // if this is true, use the StructDeclaration's init symbol
-    bool isOriginal;            // used when moving instances to indicate `this is this.origin`
+    d_bool useStaticInit;         // if this is true, use the StructDeclaration's init symbol
+    d_bool isOriginal;            // used when moving instances to indicate `this is this.origin`
     OwnedBy ownedByCtfe;
 
     static StructLiteralExp *create(const Loc &loc, StructDeclaration *sd, void *elements, Type *stype = NULL);
@@ -537,8 +537,8 @@  public:
     Expression *argprefix;      // expression to be evaluated just before arguments[]
 
     CtorDeclaration *member;    // constructor function
-    bool onstack;               // allocate on stack
-    bool thrownew;              // this NewExp is the expression of a ThrowStatement
+    d_bool onstack;               // allocate on stack
+    d_bool thrownew;              // this NewExp is the expression of a ThrowStatement
 
     Expression *lowering;       // lowered druntime hook: `_d_newclass`
 
@@ -566,7 +566,7 @@  class SymbolExp : public Expression
 public:
     Declaration *var;
     Dsymbol *originalScope;
-    bool hasOverloads;
+    d_bool hasOverloads;
 
     void accept(Visitor *v) override { v->visit(this); }
 };
@@ -588,7 +588,7 @@  public:
 class VarExp final : public SymbolExp
 {
 public:
-    bool delegateWasExtracted;
+    d_bool delegateWasExtracted;
     static VarExp *create(const Loc &loc, Declaration *var, bool hasOverloads = true);
     bool equals(const RootObject * const o) const override;
     bool isLvalue() override;
@@ -764,9 +764,9 @@  class DotIdExp final : public UnaExp
 {
 public:
     Identifier *ident;
-    bool noderef;       // true if the result of the expression will never be dereferenced
-    bool wantsym;       // do not replace Symbol with its initializer during semantic()
-    bool arrow;         // ImportC: if -> instead of .
+    d_bool noderef;       // true if the result of the expression will never be dereferenced
+    d_bool wantsym;       // do not replace Symbol with its initializer during semantic()
+    d_bool arrow;         // ImportC: if -> instead of .
 
     static DotIdExp *create(const Loc &loc, Expression *e, Identifier *ident);
     void accept(Visitor *v) override { v->visit(this); }
@@ -786,7 +786,7 @@  class DotVarExp final : public UnaExp
 {
 public:
     Declaration *var;
-    bool hasOverloads;
+    d_bool hasOverloads;
 
     bool isLvalue() override;
     Expression *toLvalue(Scope *sc, Expression *e) override;
@@ -810,7 +810,7 @@  class DelegateExp final : public UnaExp
 {
 public:
     FuncDeclaration *func;
-    bool hasOverloads;
+    d_bool hasOverloads;
     VarDeclaration *vthis2;  // container for multi-context
 
 
@@ -831,9 +831,9 @@  public:
     Expressions *arguments;     // function arguments
     Identifiers *names;
     FuncDeclaration *f;         // symbol to call
-    bool directcall;            // true if a virtual call is devirtualized
-    bool inDebugStatement;      // true if this was in a debug statement
-    bool ignoreAttributes;      // don't enforce attributes (e.g. call @gc function in @nogc code)
+    d_bool directcall;            // true if a virtual call is devirtualized
+    d_bool inDebugStatement;      // true if this was in a debug statement
+    d_bool ignoreAttributes;      // don't enforce attributes (e.g. call @gc function in @nogc code)
     VarDeclaration *vthis2;     // container for multi-context
 
     static CallExp *create(const Loc &loc, Expression *e, Expressions *exps);
@@ -892,7 +892,7 @@  public:
 class DeleteExp final : public UnaExp
 {
 public:
-    bool isRAII;
+    d_bool isRAII;
     void accept(Visitor *v) override { v->visit(this); }
 };
 
@@ -937,9 +937,9 @@  public:
     Expression *upr;            // NULL if implicit 0
     Expression *lwr;            // NULL if implicit [length - 1]
     VarDeclaration *lengthVar;
-    bool upperIsInBounds;       // true if upr <= e1.length
-    bool lowerIsLessThanUpper;  // true if lwr <= upr
-    bool arrayop;               // an array operation, rather than a slice
+    d_bool upperIsInBounds;       // true if upr <= e1.length
+    d_bool lowerIsLessThanUpper;  // true if lwr <= upr
+    d_bool arrayop;               // an array operation, rather than a slice
 
     SliceExp *syntaxCopy() override;
     bool isLvalue() override;
@@ -1011,8 +1011,8 @@  public:
 class CommaExp final : public BinExp
 {
 public:
-    bool isGenerated;
-    bool allowCommaExp;
+    d_bool isGenerated;
+    d_bool allowCommaExp;
     bool isLvalue() override;
     Expression *toLvalue(Scope *sc, Expression *e) override;
     Expression *modifiableLvalue(Scope *sc, Expression *e) override;
@@ -1025,8 +1025,8 @@  class IndexExp final : public BinExp
 {
 public:
     VarDeclaration *lengthVar;
-    bool modifiable;
-    bool indexIsInBounds;       // true if 0 <= e2 && e2 <= e1.length - 1
+    d_bool modifiable;
+    d_bool indexIsInBounds;       // true if 0 <= e2 && e2 <= e1.length - 1
 
     IndexExp *syntaxCopy() override;
     bool isLvalue() override;
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index 632ea11cdc0..45dcb9739f2 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -12158,6 +12158,9 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
 
         if (!needsArrayLowering)
         {
+            // https://issues.dlang.org/show_bug.cgi?id=23783
+            if (exp.e1.checkSharedAccess(sc) || exp.e2.checkSharedAccess(sc))
+                return setError();
             if (auto e = typeCombine(exp, sc))
             {
                 result = e;
@@ -13372,6 +13375,12 @@  bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)
 
         bool visitVar(VarExp e)
         {
+            // https://issues.dlang.org/show_bug.cgi?id=20908
+            // direct access to init symbols is ok as they
+            // cannot be modified.
+            if (e.var.isSymbolDeclaration())
+                return false;
+
             // https://issues.dlang.org/show_bug.cgi?id=22626
             // Synchronized functions don't need to use core.atomic
             // when accessing `this`.
@@ -13409,9 +13418,16 @@  bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)
             //printf("dotvarexp = %s\n", e.toChars());
             if (e.type.isShared())
             {
-                // / https://issues.dlang.org/show_bug.cgi?id=22626
-                if (e.e1.isThisExp() && sc.func && sc.func.isSynchronized())
-                    return false;
+                if (e.e1.isThisExp())
+                {
+                    // https://issues.dlang.org/show_bug.cgi?id=22626
+                    if (sc.func && sc.func.isSynchronized())
+                        return false;
+
+                    // https://issues.dlang.org/show_bug.cgi?id=23790
+                    if (e.e1.type.isTypeStruct())
+                        return false;
+                }
 
                 auto fd = e.var.isFuncDeclaration();
                 const sharedFunc = fd && fd.type.isShared;
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index ec8fc32ed0f..84fbec6977d 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -85,8 +85,8 @@  enum class FeatureState : signed char
 struct Output
 {
     /// Configuration for the compiler generator
-    bool doOutput;      // Output is enabled
-    bool fullOutput;    // Generate comments for hidden declarations (for -HC),
+    d_bool doOutput;      // Output is enabled
+    d_bool fullOutput;    // Generate comments for hidden declarations (for -HC),
                         // and don't strip the bodies of plain (non-template) functions (for -H)
     DString dir;   // write to directory 'dir'
     DString name;  // write to file 'name'
@@ -99,71 +99,71 @@  struct Output
 // Put command line switches in here
 struct Param
 {
-    bool obj;           // write object file
-    bool multiobj;      // break one object file into multiple ones
-    bool trace;         // insert profiling hooks
-    bool tracegc;       // instrument calls to 'new'
-    bool verbose;       // verbose compile
-    bool vcg_ast;       // write-out codegen-ast
-    bool showColumns;   // print character (column) numbers in diagnostics
-    bool vtls;          // identify thread local variables
-    bool vtemplates;    // collect and list statistics on template instantiations
-    bool vtemplatesListInstances; // collect and list statistics on template instantiations origins
-    bool vgc;           // identify gc usage
-    bool vfield;        // identify non-mutable field variables
-    bool vcomplex;      // identify complex/imaginary type usage
-    bool vin;           // identify 'in' parameters
+    d_bool obj;           // write object file
+    d_bool multiobj;      // break one object file into multiple ones
+    d_bool trace;         // insert profiling hooks
+    d_bool tracegc;       // instrument calls to 'new'
+    d_bool verbose;       // verbose compile
+    d_bool vcg_ast;       // write-out codegen-ast
+    d_bool showColumns;   // print character (column) numbers in diagnostics
+    d_bool vtls;          // identify thread local variables
+    d_bool vtemplates;    // collect and list statistics on template instantiations
+    d_bool vtemplatesListInstances; // collect and list statistics on template instantiations origins
+    d_bool vgc;           // identify gc usage
+    d_bool vfield;        // identify non-mutable field variables
+    d_bool vcomplex;      // identify complex/imaginary type usage
+    d_bool vin;           // identify 'in' parameters
     Diagnostic useDeprecated;
-    bool useUnitTests;  // generate unittest code
-    bool useInline;     // inline expand functions
-    bool release;       // build release version
-    bool preservePaths; // true means don't strip path from source file
+    d_bool useUnitTests;  // generate unittest code
+    d_bool useInline;     // inline expand functions
+    d_bool release;       // build release version
+    d_bool preservePaths; // true means don't strip path from source file
     Diagnostic warnings;
-    bool color;         // use ANSI colors in console output
-    bool cov;           // generate code coverage data
+    d_bool color;         // use ANSI colors in console output
+    d_bool cov;           // generate code coverage data
     unsigned char covPercent;   // 0..100 code coverage percentage required
-    bool ctfe_cov;      // generate coverage data for ctfe
-    bool ignoreUnsupportedPragmas;      // rather than error on them
-    bool useModuleInfo; // generate runtime module information
-    bool useTypeInfo;   // generate runtime type information
-    bool useExceptions; // support exception handling
-    bool betterC;       // be a "better C" compiler; no dependency on D runtime
-    bool addMain;       // add a default main() function
-    bool allInst;       // generate code for all template instantiations
-    bool bitfields;         // support C style bit fields
+    d_bool ctfe_cov;      // generate coverage data for ctfe
+    d_bool ignoreUnsupportedPragmas;      // rather than error on them
+    d_bool useModuleInfo; // generate runtime module information
+    d_bool useTypeInfo;   // generate runtime type information
+    d_bool useExceptions; // support exception handling
+    d_bool betterC;       // be a "better C" compiler; no dependency on D runtime
+    d_bool addMain;       // add a default main() function
+    d_bool allInst;       // generate code for all template instantiations
+    d_bool bitfields;         // support C style bit fields
     CppStdRevision cplusplus;  // version of C++ name mangling to support
-    bool showGaggedErrors;  // print gagged errors anyway
-    bool printErrorContext;  // print errors with the error context (the error line in the source file)
-    bool manual;            // open browser on compiler manual
-    bool usage;             // print usage and exit
-    bool mcpuUsage;         // print help on -mcpu switch
-    bool transitionUsage;   // print help on -transition switch
-    bool checkUsage;        // print help on -check switch
-    bool checkActionUsage;  // print help on -checkaction switch
-    bool revertUsage;       // print help on -revert switch
-    bool previewUsage;      // print help on -preview switch
-    bool externStdUsage;    // print help on -extern-std switch
-    bool hcUsage;           // print help on -HC switch
-    bool logo;              // print logo;
+    d_bool showGaggedErrors;  // print gagged errors anyway
+    d_bool printErrorContext;  // print errors with the error context (the error line in the source file)
+    d_bool manual;            // open browser on compiler manual
+    d_bool usage;             // print usage and exit
+    d_bool mcpuUsage;         // print help on -mcpu switch
+    d_bool transitionUsage;   // print help on -transition switch
+    d_bool checkUsage;        // print help on -check switch
+    d_bool checkActionUsage;  // print help on -checkaction switch
+    d_bool revertUsage;       // print help on -revert switch
+    d_bool previewUsage;      // print help on -preview switch
+    d_bool externStdUsage;    // print help on -extern-std switch
+    d_bool hcUsage;           // print help on -HC switch
+    d_bool logo;              // print logo;
 
     // Options for `-preview=/-revert=`
     FeatureState useDIP25;       // implement https://wiki.dlang.org/DIP25
     FeatureState useDIP1000;     // implement https://dlang.org/spec/memory-safe-d.html#scope-return-params
-    bool ehnogc;                 // use @nogc exception handling
-    bool useDIP1021;             // implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md
-    bool fieldwise;              // do struct equality testing field-wise rather than by memcmp()
-    bool fixAliasThis;           // if the current scope has an alias this, check it before searching upper scopes
+    d_bool ehnogc;                 // use @nogc exception handling
+    d_bool useDIP1021;             // implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md
+    d_bool fieldwise;              // do struct equality testing field-wise rather than by memcmp()
+    d_bool fixAliasThis;           // if the current scope has an alias this, check it before searching upper scopes
     FeatureState rvalueRefParam; // allow rvalues to be arguments to ref parameters
                                  // https://dconf.org/2019/talks/alexandrescu.html
                                  // https://gist.github.com/andralex/e5405a5d773f07f73196c05f8339435a
                                  // https://digitalmars.com/d/archives/digitalmars/D/Binding_rvalues_to_ref_parameters_redux_325087.html
                                  // Implementation: https://github.com/dlang/dmd/pull/9817
     FeatureState noSharedAccess; // read/write access to shared memory objects
-    bool previewIn;              // `in` means `[ref] scope const`, accepts rvalues
-    bool inclusiveInContracts;   // 'in' contracts of overridden methods must be a superset of parent contract
-    bool shortenedMethods;       // allow => in normal function declarations
-    bool fixImmutableConv;       // error on unsound immutable conversion - https://github.com/dlang/dmd/pull/14070
-    bool fix16997;               // fix integral promotions for unary + - ~ operators
+    d_bool previewIn;              // `in` means `[ref] scope const`, accepts rvalues
+    d_bool inclusiveInContracts;   // 'in' contracts of overridden methods must be a superset of parent contract
+    d_bool shortenedMethods;       // allow => in normal function declarations
+    d_bool fixImmutableConv;       // error on unsound immutable conversion - https://github.com/dlang/dmd/pull/14070
+    d_bool fix16997;               // fix integral promotions for unary + - ~ operators
                                  // https://issues.dlang.org/show_bug.cgi?id=16997
     FeatureState dtorFields;     // destruct fields of partially constructed objects
                                  // https://issues.dlang.org/show_bug.cgi?id=14246
@@ -208,7 +208,7 @@  struct Param
 
     MessageStyle messageStyle;  // style of file/line annotations on messages
 
-    bool run;           // run resulting executable
+    d_bool run;           // run resulting executable
     Strings runargs;    // arguments for executable
 
     Array<const char *> cppswitches; // preprocessor switches
@@ -228,7 +228,7 @@  struct Param
 struct structalign_t
 {
     unsigned short value;
-    bool pack;
+    d_bool pack;
 
     bool isDefault() const;
     void setDefault();
@@ -275,7 +275,7 @@  struct Global
     Array<class Identifier*>* versionids; // command line versions and predefined versions
     Array<class Identifier*>* debugids;   // command line debug versions and predefined versions
 
-    bool hasMainFunction;
+    d_bool hasMainFunction;
     unsigned varSequenceNumber;
 
     FileManager* fileManager;
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index c7e5690bc0a..e0684e6b365 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -1586,7 +1586,10 @@  public:
         if (hgs.hdrgen)
         {
             // if the return type is missing (e.g. ref functions or auto)
-            if (!tf.next || f.storage_class & STC.auto_)
+            // https://issues.dlang.org/show_bug.cgi?id=20090
+            // constructors are an exception: they don't have an explicit return
+            // type but we still don't output the body.
+            if ((!f.isCtorDeclaration() && !tf.next) || f.storage_class & STC.auto_)
             {
                 hgs.autoMember++;
                 bodyToBuffer(f);
diff --git a/gcc/d/dmd/identifier.h b/gcc/d/dmd/identifier.h
index c12c3554c1b..e7b3ba60b0f 100644
--- a/gcc/d/dmd/identifier.h
+++ b/gcc/d/dmd/identifier.h
@@ -17,7 +17,7 @@  class Identifier final : public RootObject
 {
 private:
     int value;
-    bool isAnonymous_;
+    d_bool isAnonymous_;
     DString string;
 
 public:
diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h
index 66b874c91b5..9a6a56b68bb 100644
--- a/gcc/d/dmd/init.h
+++ b/gcc/d/dmd/init.h
@@ -77,8 +77,8 @@  public:
     Initializers value; // of Initializer *'s
     unsigned dim;       // length of array being initialized
     Type *type;         // type that array will be used to initialize
-    bool sem;           // true if semantic() is run
-    bool isCarray;      // C array semantics
+    d_bool sem;           // true if semantic() is run
+    d_bool isCarray;      // C array semantics
 
     bool isAssociativeArray() const;
     Expression *toAssocArrayLiteral();
@@ -89,7 +89,7 @@  public:
 class ExpInitializer final : public Initializer
 {
 public:
-    bool expandTuples;
+    d_bool expandTuples;
     Expression *exp;
 
     void accept(Visitor *v) override { v->visit(this); }
@@ -112,7 +112,7 @@  class CInitializer final : public Initializer
 public:
     DesigInits initializerList;
     Type *type;         // type that array will be used to initialize
-    bool sem;           // true if semantic() is run
+    d_bool sem;           // true if semantic() is run
 
     void accept(Visitor *v) override { v->visit(this); }
 };
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index c9ed35ffa6d..f0f7872c2b2 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -2664,14 +2664,19 @@  class Lexer
         eSink.error(loc, format, args);
     }
 
-    final void deprecation(const(char)* format)
+    void deprecation(T...)(const ref Loc loc, const(char)* format, T args)
     {
-        eSink.deprecation(token.loc, format);
+        eSink.deprecation(loc, format, args);
     }
 
-    final void deprecationSupplemental(const(char)* format)
+    void deprecation(T...)(const(char)* format, T args)
     {
-        eSink.deprecationSupplemental(token.loc, format);
+        eSink.deprecation(token.loc, format, args);
+    }
+
+    void deprecationSupplemental(T...)(const(char)* format, T args)
+    {
+        eSink.deprecationSupplemental(token.loc, format, args);
     }
 
     /***************************************
@@ -2695,12 +2700,21 @@  class Lexer
             else
             {
                 const locx = loc();
-                eSink.warning(locx, "C preprocessor directive `#%s` is not supported", n.ident.toChars());
+                // @@@DEPRECATED_2.103@@@
+                // Turn into an error in 2.113
+                if (inTokenStringConstant)
+                    deprecation(locx, "token string requires valid D tokens, not `#%s`", n.ident.toChars());
+                else
+                    error(locx, "C preprocessor directive `#%s` is not supported", n.ident.toChars());
             }
         }
         else if (n.value == TOK.if_)
         {
-            error("C preprocessor directive `#if` is not supported, use `version` or `static if`");
+            const locx = loc();
+            if (inTokenStringConstant)
+                error(locx, "token string requires valid D tokens, not `#if`");
+            else
+                error(locx, "C preprocessor directive `#if` is not supported, use `version` or `static if`");
         }
         return false;
     }
diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h
index 002bb1a875b..8b481108f8c 100644
--- a/gcc/d/dmd/module.h
+++ b/gcc/d/dmd/module.h
@@ -74,8 +74,8 @@  public:
     unsigned errors;    // if any errors in file
     unsigned numlines;  // number of lines in source file
     FileType filetype;  // source file type
-    bool hasAlwaysInlines; // contains references to functions that must be inlined
-    bool isPackageFile; // if it is a package.d
+    d_bool hasAlwaysInlines; // contains references to functions that must be inlined
+    d_bool isPackageFile; // if it is a package.d
     Package *pkg;       // if isPackageFile is true, the Package that contains this package.d
     Strings contentImportedFiles;  // array of files whose content was imported
     int needmoduleinfo;
@@ -90,7 +90,7 @@  public:
     Identifier *searchCacheIdent;
     Dsymbol *searchCacheSymbol; // cached value of search
     int searchCacheFlags;       // cached flags
-    bool insearch;
+    d_bool insearch;
 
     // module from command line we're imported from,
     // i.e. a module that will be taken all the
@@ -165,7 +165,7 @@  struct ModuleDeclaration
     Loc loc;
     Identifier *id;
     DArray<Identifier*> packages;  // array of Identifier's representing packages
-    bool isdeprecated;  // if it is a deprecated module
+    d_bool isdeprecated;  // if it is a deprecated module
     Expression *msg;
 
     const char *toChars() const;
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index d0775f2f5fb..fbfd766fa94 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -589,7 +589,7 @@  struct ParameterList
     Parameters* parameters;
     StorageClass stc;
     VarArg varargs;
-    bool hasIdentifierList; // true if C identifier-list style
+    d_bool hasIdentifierList; // true if C identifier-list style
 
     size_t length();
     Parameter *operator[](size_t i) { return Parameter::getNth(parameters, i); }
@@ -779,7 +779,7 @@  class TypeStruct final : public Type
 public:
     StructDeclaration *sym;
     AliasThisRec att;
-    bool inuse;
+    d_bool inuse;
 
     static TypeStruct *create(StructDeclaration *sym);
     const char *kind() override;
diff --git a/gcc/d/dmd/objc.h b/gcc/d/dmd/objc.h
index 305ce812487..a5cc6f1b089 100644
--- a/gcc/d/dmd/objc.h
+++ b/gcc/d/dmd/objc.h
@@ -37,8 +37,8 @@  struct ObjcSelector
 
 struct ObjcClassDeclaration
 {
-    bool isMeta;
-    bool isExtern;
+    d_bool isMeta;
+    d_bool isExtern;
 
     Identifier* identifier;
     ClassDeclaration* classDeclaration;
@@ -52,7 +52,7 @@  struct ObjcFuncDeclaration
 {
     ObjcSelector* selector;
     VarDeclaration* selectorParameter;
-    bool isOptional;
+    d_bool isOptional;
 };
 
 class Objc
diff --git a/gcc/d/dmd/root/dcompat.h b/gcc/d/dmd/root/dcompat.h
index 0bc23b7a8b3..1a496880100 100644
--- a/gcc/d/dmd/root/dcompat.h
+++ b/gcc/d/dmd/root/dcompat.h
@@ -36,7 +36,7 @@  struct DString : public DArray<const char>
 };
 
 /// Corresponding C++ type that maps to D size_t
-#if __APPLE__ && __i386__
+#if __APPLE__ && (__i386__ || __ppc__)
 // size_t is 'unsigned long', which makes it mangle differently than D's 'uint'
 typedef unsigned d_size_t;
 #elif MARS && DMD_VERSION >= 2079 && DMD_VERSION <= 2081 && \
@@ -49,3 +49,11 @@  typedef unsigned d_size_t;
 #else
 typedef size_t d_size_t;
 #endif
+
+/// Corresponding C++ type that maps to D bool
+#if __APPLE__ && __ppc__
+// bool is defined as an 'int', which does not match same size as D
+typedef uint8_t d_bool;
+#else
+typedef bool d_bool;
+#endif
diff --git a/gcc/d/dmd/root/optional.h b/gcc/d/dmd/root/optional.h
index cc2ee79edeb..353332c2199 100644
--- a/gcc/d/dmd/root/optional.h
+++ b/gcc/d/dmd/root/optional.h
@@ -11,6 +11,8 @@ 
  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/optional.h
  */
 
+#include "dcompat.h"    // for d_bool
+
 /// Optional type that is either `empty` or contains a value of type `T`
 template<typename T>
 struct Optional final
@@ -20,7 +22,7 @@  private:
     T value;
 
     /** whether `value` is set **/
-    bool present;
+    d_bool present;
 
 public:
     /** Creates an `Optional` with the given value **/
diff --git a/gcc/d/dmd/scope.h b/gcc/d/dmd/scope.h
index b25c26afff2..da114289850 100644
--- a/gcc/d/dmd/scope.h
+++ b/gcc/d/dmd/scope.h
@@ -81,8 +81,8 @@  struct Scope
     ForeachStatement *fes;      // if nested function for ForeachStatement, this is it
     Scope *callsc;              // used for __FUNCTION__, __PRETTY_FUNCTION__ and __MODULE__
     Dsymbol *inunion;           // !=null if processing members of a union
-    bool nofree;                // true if shouldn't free it
-    bool inLoop;                // true if inside a loop (where constructor calls aren't allowed)
+    d_bool nofree;                // true if shouldn't free it
+    d_bool inLoop;                // true if inside a loop (where constructor calls aren't allowed)
     int intypeof;               // in typeof(exp)
     VarDeclaration *lastVar;    // Previous symbol used to prevent goto-skips-init
 
diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h
index 46cc4dadf64..6d1f85b38d9 100644
--- a/gcc/d/dmd/statement.h
+++ b/gcc/d/dmd/statement.h
@@ -433,7 +433,7 @@  class SwitchStatement final : public Statement
 public:
     Expression *condition;
     Statement *_body;
-    bool isFinal;
+    d_bool isFinal;
 
     DefaultStatement *sdefault;
     Statement *tryBody;            // set to TryCatchStatement or TryFinallyStatement if in _body portion
@@ -600,11 +600,11 @@  public:
 
     VarDeclaration *var;
     // set if semantic processing errors
-    bool errors;
+    d_bool errors;
 
     // was generated by the compiler,
     // wasn't present in source code
-    bool internalCatch;
+    d_bool internalCatch;
 
     Catch *syntaxCopy();
 };
@@ -616,7 +616,7 @@  public:
     Statement *finalbody;
 
     Statement *tryBody;   // set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion
-    bool bodyFallsThru;   // true if _body falls through to finally
+    d_bool bodyFallsThru;   // true if _body falls through to finally
 
     static TryFinallyStatement *create(const Loc &loc, Statement *body, Statement *finalbody);
     TryFinallyStatement *syntaxCopy() override;
@@ -643,7 +643,7 @@  public:
     Expression *exp;
     // was generated by the compiler,
     // wasn't present in source code
-    bool internalThrow;
+    d_bool internalThrow;
 
     ThrowStatement *syntaxCopy() override;
 
@@ -668,7 +668,7 @@  public:
     TryFinallyStatement *tf;
     ScopeGuardStatement *os;
     VarDeclaration *lastVar;
-    bool inCtfeBlock;
+    d_bool inCtfeBlock;
     GotoStatement *syntaxCopy() override;
 
     void accept(Visitor *v) override { v->visit(this); }
@@ -685,8 +685,8 @@  public:
     VarDeclaration *lastVar;
     Statement *gotoTarget;      // interpret
     void* extra;                // used by Statement_toIR()
-    bool breaks;                // someone did a 'break ident'
-    bool inCtfeBlock;
+    d_bool breaks;                // someone did a 'break ident'
+    d_bool inCtfeBlock;
     LabelStatement *syntaxCopy() override;
 
     void accept(Visitor *v) override { v->visit(this); }
@@ -697,8 +697,8 @@  class LabelDsymbol final : public Dsymbol
 public:
     LabelStatement *statement;
 
-    bool deleted;           // set if rewritten to return in foreach delegate
-    bool iasm;              // set if used by inline assembler
+    d_bool deleted;           // set if rewritten to return in foreach delegate
+    d_bool iasm;              // set if used by inline assembler
 
     static LabelDsymbol *create(Identifier *ident);
     LabelDsymbol *isLabel() override;
@@ -722,8 +722,8 @@  public:
     code *asmcode;
     unsigned asmalign;          // alignment of this statement
     unsigned regs;              // mask of registers modified (must match regm_t in back end)
-    bool refparam;              // true if function parameter is referenced
-    bool naked;                 // true if function is to be naked
+    d_bool refparam;              // true if function parameter is referenced
+    d_bool naked;                 // true if function is to be naked
 
     InlineAsmStatement *syntaxCopy() override;
     void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index bbaee8e6152..694db28b56c 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -1941,7 +1941,6 @@  package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
         }
         if (checkNonAssignmentArrayOp(ifs.condition))
             ifs.condition = ErrorExp.get();
-        ifs.condition = checkGC(scd, ifs.condition);
 
         // Convert to boolean after declaring prm so this works:
         //  if (S prm = S()) {}
@@ -1953,6 +1952,10 @@  package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
         // This feature allows a limited form of conditional compilation.
         ifs.condition = ifs.condition.optimize(WANTvalue);
 
+        // checkGC after optimizing the condition so that
+        // compile time constants are reduced.
+        ifs.condition = checkGC(scd, ifs.condition);
+
         // Save 'root' of two branches (then and else) at the point where it forks
         CtorFlow ctorflow_root = scd.ctorflow.clone();
 
@@ -4525,8 +4528,7 @@  public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
             decls.append(Dsymbol.arraySyntaxCopy(dbody));
         else
         {
-            if (fs._body) // https://issues.dlang.org/show_bug.cgi?id=17646
-                stmts.push(fs._body.syntaxCopy());
+            stmts.push(fs._body.syntaxCopy());
             s = new CompoundStatement(loc, stmts);
         }
 
diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h
index ef2c09d4147..561afa18d42 100644
--- a/gcc/d/dmd/target.h
+++ b/gcc/d/dmd/target.h
@@ -92,11 +92,11 @@  struct TargetCPP
         Microsoft,
         Sun
     };
-    bool reverseOverloads;    // with dmc and cl, overloaded functions are grouped and in reverse order
-    bool exceptions;          // set if catching C++ exceptions is supported
-    bool twoDtorInVtable;     // target C++ ABI puts deleting and non-deleting destructor into vtable
-    bool splitVBasetable;     // set if C++ ABI uses separate tables for virtual functions and virtual bases
-    bool wrapDtorInExternD;   // set if C++ dtors require a D wrapper to be callable from runtime
+    d_bool reverseOverloads;    // with dmc and cl, overloaded functions are grouped and in reverse order
+    d_bool exceptions;          // set if catching C++ exceptions is supported
+    d_bool twoDtorInVtable;     // target C++ ABI puts deleting and non-deleting destructor into vtable
+    d_bool splitVBasetable;     // set if C++ ABI uses separate tables for virtual functions and virtual bases
+    d_bool wrapDtorInExternD;   // set if C++ dtors require a D wrapper to be callable from runtime
     Runtime runtime;
 
     const char *toMangle(Dsymbol *s);
@@ -110,7 +110,7 @@  struct TargetCPP
 
 struct TargetObjC
 {
-    bool supported;     // set if compiler can interface with Objective-C
+    d_bool supported;     // set if compiler can interface with Objective-C
 };
 
 struct Target
@@ -156,15 +156,15 @@  struct Target
 
     DString architectureName;    // name of the platform architecture (e.g. X86_64)
     CPU cpu;                // CPU instruction set to target
-    bool is64bit;           // generate 64 bit code for x86_64; true by default for 64 bit dmd
-    bool isLP64;            // pointers are 64 bits
+    d_bool is64bit;           // generate 64 bit code for x86_64; true by default for 64 bit dmd
+    d_bool isLP64;            // pointers are 64 bits
 
     // Environmental
     DString obj_ext;    /// extension for object files
     DString lib_ext;    /// extension for static library files
     DString dll_ext;    /// extension for dynamic library files
-    bool run_noext;     /// allow -run sources without extensions
-    bool omfobj;        /// for Win32: write OMF object files instead of COFF
+    d_bool run_noext;     /// allow -run sources without extensions
+    d_bool omfobj;        /// for Win32: write OMF object files instead of COFF
 
     template <typename T>
     struct FPTypeProperties
diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h
index 12b21207b8e..8622b5c6483 100644
--- a/gcc/d/dmd/template.h
+++ b/gcc/d/dmd/template.h
@@ -78,12 +78,12 @@  public:
 
     Dsymbol *onemember;         // if !=NULL then one member of this template
 
-    bool literal;               // this template declaration is a literal
-    bool ismixin;               // template declaration is only to be used as a mixin
-    bool isstatic;              // this is static template declaration
-    bool isTrivialAliasSeq;     // matches `template AliasSeq(T...) { alias AliasSeq = T; }
-    bool isTrivialAlias;        // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
-    bool deprecated_;           // this template declaration is deprecated
+    d_bool literal;               // this template declaration is a literal
+    d_bool ismixin;               // template declaration is only to be used as a mixin
+    d_bool isstatic;              // this is static template declaration
+    d_bool isTrivialAliasSeq;     // matches `template AliasSeq(T...) { alias AliasSeq = T; }
+    d_bool isTrivialAlias;        // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
+    d_bool deprecated_;           // this template declaration is deprecated
     Visibility visibility;
 
     TemplatePrevious *previous;         // threaded list of previous instantiation attempts on stack
@@ -133,7 +133,7 @@  public:
      * A dependent template parameter should return MATCHexact in matchArg()
      * to respect the match level of the corresponding precedent parameter.
      */
-    bool dependent;
+    d_bool dependent;
 
     virtual TemplateTypeParameter  *isTemplateTypeParameter();
     virtual TemplateValueParameter *isTemplateValueParameter();
diff --git a/gcc/d/dmd/visitor.h b/gcc/d/dmd/visitor.h
index f8cbdb48c92..ed9f9ce1f6f 100644
--- a/gcc/d/dmd/visitor.h
+++ b/gcc/d/dmd/visitor.h
@@ -10,6 +10,7 @@ 
 #pragma once
 
 #include "root/dsystem.h"
+#include "root/dcompat.h"   // for d_bool
 
 class Statement;
 class ErrorStatement;
@@ -663,6 +664,6 @@  public:
 class StoppableVisitor : public Visitor
 {
 public:
-    bool stop;
+    d_bool stop;
     StoppableVisitor() : stop(false) {}
 };
diff --git a/gcc/testsuite/gdc.test/compilable/shared.d b/gcc/testsuite/gdc.test/compilable/shared.d
index 695083a5476..647910ecf16 100644
--- a/gcc/testsuite/gdc.test/compilable/shared.d
+++ b/gcc/testsuite/gdc.test/compilable/shared.d
@@ -11,34 +11,48 @@  ref shared(int) f(return shared ref int y)
 }
 
 // https://issues.dlang.org/show_bug.cgi?id=20908
+struct S
+{
+    int i = 2;
+}
+
+union U
+{
+    int i = 1;
+    bool b;
+}
+
 void test20908()
 {
-  // shared locals (or struct members) should be able to be initialised:
-  shared int x;
+    // shared locals (or struct members) should be able to be initialised:
+    shared int x;
 
-  ref shared(int) fun()
-  {
-    static shared(int) val;
+    ref shared(int) fun()
+    {
+        static shared(int) val;
 
-    // return by reference
-    return val;
-  }
+        // return by reference
+        return val;
+    }
 
-  ref shared(int) fun2()
-  {
-    static shared(int)* val;
+    ref shared(int) fun2()
+    {
+        static shared(int)* val;
 
-    // transfer pointer to reference
-    return *val;
-  }
+        // transfer pointer to reference
+        return *val;
+    }
 
-  ref shared(int) fun3()
-  {
-    static shared(int)*** val;
+    ref shared(int) fun3()
+    {
+        static shared(int)*** val;
+
+        // Multiple indirections
+        return ***val;
+    }
 
-    // Multiple indirections
-    return ***val;
-  }
+    shared S s;
+    shared U u;
 }
 
 // Simple tests for `DotVarExp`
@@ -130,3 +144,15 @@  void main()
 {
     auto b = new shared Class();
 }
+
+// https://issues.dlang.org/show_bug.cgi?id=23790
+bool cas(shared bool*, bool, bool) { return true; }
+
+struct Argh
+{
+    bool locked;
+    void lock() shared
+    {
+        while(!cas(&locked, false, true)) {}
+    }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test22739.d b/gcc/testsuite/gdc.test/compilable/test22739.d
new file mode 100644
index 00000000000..6aeb5d60fd7
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22739.d
@@ -0,0 +1,10 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22739
+
+extern(C++) auto f(T)()
+{
+    return T.init;
+}
+void main()
+{
+    f!int;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23799.d b/gcc/testsuite/gdc.test/compilable/test23799.d
new file mode 100644
index 00000000000..007351602a3
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23799.d
@@ -0,0 +1,37 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23799
+
+// REQUIRED_ARGS: -betterC
+
+struct Data
+{
+	Data[] range;
+	string test;
+}
+
+Data[] foo()
+{
+	Data[] ret;
+	if (__ctfe)
+	{
+		Data tmp;
+		tmp.range ~= Data.init;
+		ret ~= tmp;
+	}
+	return ret;
+}
+
+void func(Data dat)()
+{
+}
+
+void bar(Data dat)()
+{
+	if (dat.test.length)
+		func!(dat.range[0])();
+}
+
+extern (C) void main()
+{
+	static immutable data = foo();
+	bar!(data[0])();
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d
index f456454fe87..c980d76a73d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d
@@ -4,7 +4,7 @@  TEST_OUTPUT:
 fail_compilation/bug9631.d(20): Error: cannot implicitly convert expression `F()` of type `bug9631.T1!().F` to `bug9631.T2!().F`
 ---
 */
-
+// DISABLED: win32
 template T1()
 {
     struct F { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/cerrors.d b/gcc/testsuite/gdc.test/fail_compilation/cerrors.d
index 3d69d415e2b..db306c1f213 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/cerrors.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/cerrors.d
@@ -1,10 +1,12 @@ 
 /* REQUIRED_ARGS: -wi
 TEST_OUTPUT:
 ---
-fail_compilation/cerrors.d(11): Error: C preprocessor directive `#if` is not supported, use `version` or `static if`
-fail_compilation/cerrors.d(11): Error: declaration expected, not `#`
-fail_compilation/cerrors.d(15): Warning: C preprocessor directive `#endif` is not supported
-fail_compilation/cerrors.d(15): Error: declaration expected, not `#`
+fail_compilation/cerrors.d(13): Error: C preprocessor directive `#if` is not supported, use `version` or `static if`
+fail_compilation/cerrors.d(13): Error: declaration expected, not `#`
+fail_compilation/cerrors.d(17): Error: C preprocessor directive `#endif` is not supported
+fail_compilation/cerrors.d(17): Error: declaration expected, not `#`
+fail_compilation/cerrors.d(21): Error: token string requires valid D tokens, not `#if`
+fail_compilation/cerrors.d(22): Deprecation: token string requires valid D tokens, not `#include`
 ---
 */
 
@@ -13,3 +15,9 @@  fail_compilation/cerrors.d(15): Error: declaration expected, not `#`
 void test(wchar_t u);
 
 #endif
+
+// https://issues.dlang.org/show_bug.cgi?id=23792
+enum s1 = q{
+#if 1
+#include <test>
+};
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17646.d b/gcc/testsuite/gdc.test/fail_compilation/fail17646.d
index 39e7cb9eb73..2074b472a1e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail17646.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail17646.d
@@ -4,7 +4,7 @@  EXTRA_FILES: imports/fail17646.d
 TEST_OUTPUT:
 ---
 fail_compilation/imports/fail17646.d(10): Error: found `}` instead of statement
-fail_compilation/fail17646.d(11): Error: function `fail17646.runTests!"".runTests` has no `return` statement, but is expected to return a value of type `int`
+fail_compilation/fail17646.d(15): Error: template instance `allTestData!Modules` template `allTestData` is not defined
 fail_compilation/fail17646.d(18): Error: template instance `fail17646.runTests!""` error instantiating
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19948.d b/gcc/testsuite/gdc.test/fail_compilation/fail19948.d
index 6122e418339..e8a9e777904 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail19948.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19948.d
@@ -7,7 +7,7 @@  fail_compilation/fail19948.d(15): Error: function `fail19948.func(const(X))` is
 fail_compilation/fail19948.d(15):        cannot pass argument `X()` of type `fail19948.main.X` to parameter `const(fail19948.X)`
 ---
 */
-
+// DISABLED: win32
 struct X {}
 void main()
 {
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22857.d b/gcc/testsuite/gdc.test/fail_compilation/fail22857.d
new file mode 100644
index 00000000000..061eb62d49e
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22857.d
@@ -0,0 +1,18 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22857
+// EXTRA_FILES: imports/import22857.d
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/imports/import22857.d(4): Error: (expression) expected following `static if`
+fail_compilation/imports/import22857.d(4): Error: declaration expected, not `}`
+fail_compilation/fail22857.d(17): Error: template instance `unaryFun!()` template `unaryFun` is not defined
+---
+*/
+
+void isPrettyPropertyName()
+{
+    import imports.import22857;
+
+    unaryFun!();
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23816.d b/gcc/testsuite/gdc.test/fail_compilation/fail23816.d
new file mode 100644
index 00000000000..574a7122eb9
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23816.d
@@ -0,0 +1,16 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23816
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail23816.d(14): Error: opcode expected, not `NOP`
+---
+*/
+
+void main()
+{
+    asm
+    {
+        NOP;
+    }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/import22857.d b/gcc/testsuite/gdc.test/fail_compilation/imports/import22857.d
new file mode 100644
index 00000000000..280c2eb10ff
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/import22857.d
@@ -0,0 +1,4 @@ 
+template unaryFun()
+{
+    static if
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/shared.d b/gcc/testsuite/gdc.test/fail_compilation/shared.d
index afdea64c744..8b94a7981a1 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/shared.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/shared.d
@@ -259,3 +259,22 @@  void test_casting_safe() @safe
     auto x1 = cast(int*)s;
     auto x2 = cast(const(shared(int*)))s;
 }
+
+#line 3100
+
+// https://issues.dlang.org/show_bug.cgi?id=23783
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/shared.d(3114): Error: direct access to shared `x` is not allowed, see `core.atomic`
+fail_compilation/shared.d(3115): Error: direct access to shared `x` is not allowed, see `core.atomic`
+---
+*/
+
+void test23783()
+{
+    shared int x = 3;
+    assert(x == 3);
+    bool b = x == 3;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21164.d b/gcc/testsuite/gdc.test/fail_compilation/test21164.d
index f42c4bc9d15..a12002488ed 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test21164.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21164.d
@@ -3,7 +3,8 @@  TEST_OUTPUT:
 ---
 fail_compilation/imports/test21164d.d(3): Error: (expression) expected following `static if`
 fail_compilation/imports/test21164d.d(3): Error: found `}` instead of statement
-fail_compilation/test21164.d(11): Error: template instance `test21164a.D!(R!(O(), 1))` error instantiating
+fail_compilation/imports/test21164a.d(5): Error: undefined identifier `I`
+fail_compilation/test21164.d(12): Error: template instance `test21164a.D!(R!(O(), 1))` error instantiating
 ---
 */
 import imports.test21164a;
diff --git a/gcc/testsuite/gdc.test/runnable/complex3.d b/gcc/testsuite/gdc.test/runnable/complex3.d
new file mode 100644
index 00000000000..7167b0b6ff8
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/complex3.d
@@ -0,0 +1,31 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23778
+
+
+enum __c_long_double : double;
+
+alias __c_long_double c_long_double;
+
+struct _Complex
+{
+    c_long_double re;
+    c_long_double im;
+}
+
+version (all) // bug to test
+{
+    enum __c_complex_real   : _Complex;
+    alias c_complex_real = __c_complex_real;
+}
+else // works
+    enum c_complex_real   : _Complex;
+
+c_complex_real toNative2(real re, real im)
+{
+    return c_complex_real(re, im);
+}
+
+void main()
+{
+    c_complex_real n = toNative2(123, 456);
+    assert(123 == n.re && 456 == n.im);
+}
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 986925e8bdc..1205cd941b7 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@ 
-5f7552bb2829b75d5e36cc767a476e1ab35147b7
+a45f4e9f43e9fdbf0b666175e5e66b1ce4f561f6
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/libphobos/libdruntime/core/sys/windows/stacktrace.d b/libphobos/libdruntime/core/sys/windows/stacktrace.d
index c10a9175b4d..a73fc9ce4d2 100644
--- a/libphobos/libdruntime/core/sys/windows/stacktrace.d
+++ b/libphobos/libdruntime/core/sys/windows/stacktrace.d
@@ -239,6 +239,8 @@  private:
             if (frameNum >= skip)
             {
                 buffer[nframes++] = stackframe.AddrPC.Offset;
+                if (nframes >= buffer.length)
+                    break;
             }
             frameNum++;
         }
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index e72db81b710..2b6bc3e6190 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@ 
-67a47cf39d52b3cb3ae4117c0237415e03737f8a
+106038f2eaa70045bf25b29bb1c789304a6065f7
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/phobos repository.
diff --git a/libphobos/src/std/functional.d b/libphobos/src/std/functional.d
index 70aaee39aeb..588a9c8a547 100644
--- a/libphobos/src/std/functional.d
+++ b/libphobos/src/std/functional.d
@@ -48,6 +48,9 @@  $(TR $(TH Function Name) $(TH Description)
         $(TD Create a unary or binary function from a string. Most often
         used when defining algorithms on ranges.
     ))
+    $(TR $(TD $(LREF bind))
+        $(TD Passes the fields of a struct as arguments to a function.
+    ))
 ))
 
 Copyright: Copyright Andrei Alexandrescu 2008 - 2009.