diff mbox series

[committed] d: Merge upstream dmd, druntime 26f049fb26, phobos 330d6a4fd.

Message ID 20230820092054.380256-1-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] d: Merge upstream dmd, druntime 26f049fb26, phobos 330d6a4fd. | expand

Commit Message

Iain Buclaw Aug. 20, 2023, 9:20 a.m. UTC
Hi,

This patch merges the D front-end and run-time library with upstream dmd
26f049fb26, and standard library with phobos 330d6a4fd.

Synchronizing with the latest bug fixes in the v2.105.0-beta.1 release.

D front-end changes:

	- Import dmd v2.105.0-beta.1.
	- Added predefined version identifier VisionOS (ignored by GDC).
	- Functions can no longer have `enum` storage class.
	- The deprecation of the `body` keyword has been reverted, it is
	  now an obsolete feature.
	- The error for `scope class` has been reverted, it is now an
	  obsolete feature.

D runtime changes:

	- Import druntime v2.105.0-beta.1.

Phobos changes:

	- Import phobos v2.105.0-beta.1.
	- AliasSeq has been removed from std.math.
	- extern(C) getdelim and getline have been removed from
	  std.stdio.

gcc/d/ChangeLog:

	* dmd/MERGE: Merge upstream dmd 26f049fb26.
	* dmd/VERSION: Bump version to v2.105.0-beta.1.
	* d-codegen.cc (get_frameinfo): Check useGC in condition.
	* d-lang.cc (d_handle_option): Set obsolete parameter when compiling
	with -Wall.
	(d_post_options): Set useGC to false when compiling with
	-fno-druntime.  Propagate obsolete flag to compileEnv.
	* expr.cc (ExprVisitor::visit (CatExp *)): Check useGC in condition.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32, committed
to mainline.

Regards,
Iain.

---
libphobos/ChangeLog:

	* libdruntime/MERGE: Merge upstream druntime 26f049fb26.
	* src/MERGE: Merge upstream phobos 330d6a4fd.
---
 gcc/d/d-codegen.cc                            |   2 +-
 gcc/d/d-lang.cc                               |   3 +
 gcc/d/dmd/MERGE                               |   2 +-
 gcc/d/dmd/VERSION                             |   2 +-
 gcc/d/dmd/clone.d                             |   2 +-
 gcc/d/dmd/common/string.d                     |   2 +-
 gcc/d/dmd/cond.d                              |   1 +
 gcc/d/dmd/cparse.d                            |  10 +-
 gcc/d/dmd/dsymbolsem.d                        | 194 ++++++++++--------
 gcc/d/dmd/errors.d                            |  34 +--
 gcc/d/dmd/expression.d                        |  24 ++-
 gcc/d/dmd/expression.h                        |   6 +-
 gcc/d/dmd/expressionsem.d                     |   4 +-
 gcc/d/dmd/func.d                              |  18 +-
 gcc/d/dmd/globals.d                           |  10 +-
 gcc/d/dmd/globals.h                           |  11 +-
 gcc/d/dmd/initsem.d                           |  25 ++-
 gcc/d/dmd/lexer.d                             |   1 +
 gcc/d/dmd/nogc.d                              |   2 +-
 gcc/d/dmd/parse.d                             |  86 +++++---
 gcc/d/dmd/semantic3.d                         |   3 +-
 gcc/d/dmd/target.d                            |   4 +-
 gcc/d/dmd/target.h                            |   2 +-
 gcc/d/dmd/traits.d                            |  23 ++-
 gcc/d/expr.cc                                 |   2 +-
 gcc/testsuite/gdc.test/compilable/cppmangle.d |   1 -
 .../gdc.test/compilable/deprecate14283.d      |   8 +-
 .../gdc.test/compilable/emptystatement.d      |  19 ++
 .../gdc.test/compilable/imports/imp24022.c    |   5 +
 .../gdc.test/compilable/parens_inc.d          |  23 +++
 gcc/testsuite/gdc.test/compilable/test23951.d |  10 +
 gcc/testsuite/gdc.test/compilable/test23966.d |  19 ++
 gcc/testsuite/gdc.test/compilable/test24022.d |  30 +++
 gcc/testsuite/gdc.test/compilable/test7172.d  |   6 +-
 .../gdc.test/fail_compilation/biterrors3.d    |   2 +-
 .../gdc.test/fail_compilation/body.d          |  11 +
 .../gdc.test/fail_compilation/ccast.d         |  21 +-
 .../gdc.test/fail_compilation/diag4596.d      |   4 +-
 .../gdc.test/fail_compilation/enum_function.d |  13 ++
 .../gdc.test/fail_compilation/fail10285.d     |  12 +-
 .../gdc.test/fail_compilation/fail13116.d     |   2 +-
 .../gdc.test/fail_compilation/fail15896.d     |   1 +
 .../gdc.test/fail_compilation/fail22729.d     |   2 +-
 .../gdc.test/fail_compilation/fail22780.d     |   2 +-
 .../gdc.test/fail_compilation/fail4559.d      |  22 --
 .../gdc.test/fail_compilation/format.d        |  21 +-
 .../fail_compilation/reserved_version.d       |   2 +
 .../gdc.test/fail_compilation/scope_class.d   |   2 +-
 .../gdc.test/fail_compilation/scope_type.d    |  16 --
 .../gdc.test/fail_compilation/test23279.d     |  14 ++
 .../gdc.test/fail_compilation/typeerrors.d    |   2 +-
 gcc/testsuite/gdc.test/runnable/betterc.d     |  11 +
 gcc/testsuite/gdc.test/runnable/sctor2.d      |   5 -
 gcc/testsuite/gdc.test/runnable/test24029.c   |  23 +++
 .../gdc.test/runnable/testcontracts.d         |  16 --
 libphobos/libdruntime/MERGE                   |   2 +-
 libphobos/libdruntime/core/int128.d           |   8 +-
 .../core/internal/array/comparison.d          |  25 ++-
 libphobos/libdruntime/core/lifetime.d         |   6 +-
 libphobos/src/MERGE                           |   2 +-
 libphobos/src/std/algorithm/searching.d       |  17 ++
 libphobos/src/std/bigint.d                    |  23 ++-
 libphobos/src/std/json.d                      |   4 +
 libphobos/src/std/math/package.d              |   6 -
 libphobos/src/std/stdio.d                     |  15 --
 65 files changed, 598 insertions(+), 308 deletions(-)
 create mode 100644 gcc/testsuite/gdc.test/compilable/emptystatement.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/imports/imp24022.c
 create mode 100644 gcc/testsuite/gdc.test/compilable/parens_inc.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test23951.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test23966.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test24022.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/body.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/enum_function.d
 delete mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail4559.d
 delete mode 100644 gcc/testsuite/gdc.test/fail_compilation/scope_type.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test23279.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/test24029.c
diff mbox series

Patch

diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 2738958fde1..155f5d0d618 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -2850,7 +2850,7 @@  get_frameinfo (FuncDeclaration *fd)
       /* This can shift due to templates being expanded that access alias
          symbols, give it a decent error for now.  */
       if (requiresClosure != fd->requiresClosure
-	  && (fd->nrvo_var || global.params.betterC))
+	  && (fd->nrvo_var || !global.params.useGC))
 	fd->checkClosure ();
 
       /* Set-up a closure frame, this will be allocated on the heap.  */
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index 7cb86bf268f..10b9000119e 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -779,6 +779,7 @@  d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
     case OPT_Wall:
       if (value)
 	global.params.warnings = DIAGNOSTICinform;
+      global.params.obsolete = value;
       break;
 
     case OPT_Wdeprecated:
@@ -894,6 +895,7 @@  d_post_options (const char ** fn)
 	  flag_exceptions = false;
 	}
 
+      global.params.useGC = false;
       global.params.checkAction = CHECKACTION_C;
     }
 
@@ -939,6 +941,7 @@  d_post_options (const char ** fn)
   global.compileEnv.previewIn = global.params.previewIn;
   global.compileEnv.ddocOutput = global.params.ddoc.doOutput;
   global.compileEnv.shortenedMethods = global.params.shortenedMethods;
+  global.compileEnv.obsolete = global.params.obsolete;
 
   /* Add in versions given on the command line.  */
   if (global.params.versionids)
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 308d51b55d0..a02a8cbaba5 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@ 
-a88e1335f7ea767ef438c34998f5d1f26008c586
+26f049fb26e755096dea3f1474decea7c0fef187
 
 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 9c46eea2d8c..6faa8d801e6 100644
--- a/gcc/d/dmd/VERSION
+++ b/gcc/d/dmd/VERSION
@@ -1 +1 @@ 
-v2.104.1
+v2.105.0-beta.1
diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d
index 3586f20ddbe..4cff1ecf49c 100644
--- a/gcc/d/dmd/clone.d
+++ b/gcc/d/dmd/clone.d
@@ -1263,7 +1263,7 @@  FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc)
         // block to destroy any prior successfully postblitted fields should
         // this field's postblit fail.
         // Don't generate it for betterC code since it cannot throw exceptions.
-        if (fieldsToDestroy.length > 0 && !(cast(TypeFunction)sdv.postblit.type).isnothrow && !global.params.betterC)
+        if (fieldsToDestroy.length > 0 && !(cast(TypeFunction)sdv.postblit.type).isnothrow && global.params.useExceptions)
         {
              // create a list of destructors that need to be called
             Expression[] dtorCalls;
diff --git a/gcc/d/dmd/common/string.d b/gcc/d/dmd/common/string.d
index a1614fd907c..6de921e3d7a 100644
--- a/gcc/d/dmd/common/string.d
+++ b/gcc/d/dmd/common/string.d
@@ -48,7 +48,7 @@  struct SmallBuffer(Element)
         }
         else
         {
-            assert(len < sizeof.max / Element.sizeof);
+            assert(len < sizeof.max / (2 * Element.sizeof));
             _extent = (cast(typeof(_extent.ptr)) malloc(len * Element.sizeof))[0 .. len];
             _extent.ptr || assert(0, "Out of memory.");
             needsFree = true;
diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d
index fcb50e0a648..467f9f1a990 100644
--- a/gcc/d/dmd/cond.d
+++ b/gcc/d/dmd/cond.d
@@ -733,6 +733,7 @@  extern (C++) final class VersionCondition : DVCondition
             case "SysV4":
             case "TVOS":
             case "unittest":
+            case "VisionOS":
             case "WASI":
             case "WatchOS":
             case "WebAssembly":
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index 1b6b2bb4b1b..03383d13fd5 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -1911,14 +1911,12 @@  final class CParser(AST) : Parser!AST
                     if (tt.id || tt.tok == TOK.enum_)
                     {
                         if (!tt.id && id)
+                            /* This applies for enums declared as
+                             * typedef enum {A} E;
+                             */
                             tt.id = id;
                         Specifier spec;
-                        auto stag = declareTag(tt, spec);
-                        if (tt.tok == TOK.enum_)
-                        {
-                            isalias = false;
-                            s = new AST.AliasDeclaration(token.loc, id, stag);
-                        }
+                        declareTag(tt, spec);
                     }
                 }
                 if (isalias)
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 622e28691a6..7a800bddd02 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -1459,9 +1459,12 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
                 if (sym)
                 {
                     import dmd.access : symbolIsVisible;
-                    if (!symbolIsVisible(sc, sym))
+                    if (!symbolIsVisible(sc, sym) && !sym.errors)
+                    {
                         imp.mod.error(imp.loc, "member `%s` is not visible from module `%s`",
                             imp.names[i].toChars(), sc._module.toChars());
+                        sym.errors = true;
+                    }
                     ad.dsymbolSemantic(sc);
                     // If the import declaration is in non-root module,
                     // analysis of the aliased symbol is deferred.
@@ -2231,11 +2234,14 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
         if (!(sc.flags & SCOPE.Cfile))  // C enum remains incomplete until members are done
             ed.semanticRun = PASS.semanticdone;
 
-        // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
-        // Deprecated in 2.100
-        // Make an error in 2.110
-        if (sc.stc & STC.scope_)
-            deprecation(ed.loc, "`scope` as a type constraint is deprecated.  Use `scope` at the usage site.");
+        version (none)
+        {
+            // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
+            // Deprecated in 2.100
+            // Make an error in 2.110
+            if (sc.stc & STC.scope_)
+                deprecation(ed.loc, "`scope` as a type constraint is deprecated.  Use `scope` at the usage site.");
+        }
 
         Scope* sce;
         if (ed.isAnonymous())
@@ -3176,6 +3182,9 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
             funcdecl.skipCodegen = true;
 
         funcdecl._linkage = sc.linkage;
+        if (sc.flags & SCOPE.Cfile && funcdecl.isFuncLiteralDeclaration())
+            funcdecl._linkage = LINK.d; // so they are uniquely mangled
+
         if (auto fld = funcdecl.isFuncLiteralDeclaration())
         {
             if (fld.treq)
@@ -3460,77 +3469,10 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
 
         if (funcdecl.isAbstract() && funcdecl.isFinalFunc())
             funcdecl.error("cannot be both `final` and `abstract`");
-        version (none)
-        {
-            if (funcdecl.isAbstract() && funcdecl.fbody)
-                funcdecl.error("`abstract` functions cannot have bodies");
-        }
-
-        version (none)
-        {
-            if (funcdecl.isStaticConstructor() || funcdecl.isStaticDestructor())
-            {
-                if (!funcdecl.isStatic() || funcdecl.type.nextOf().ty != Tvoid)
-                    funcdecl.error("static constructors / destructors must be `static void`");
-                if (f.arguments && f.arguments.length)
-                    funcdecl.error("static constructors / destructors must have empty parameter list");
-                // BUG: check for invalid storage classes
-            }
-        }
 
         if (funcdecl.printf || funcdecl.scanf)
         {
-            /* printf/scanf-like functions must be of the form:
-             *    extern (C/C++) T printf([parameters...], const(char)* format, ...);
-             * or:
-             *    extern (C/C++) T vprintf([parameters...], const(char)* format, va_list);
-             */
-
-            static bool isPointerToChar(Parameter p)
-            {
-                if (auto tptr = p.type.isTypePointer())
-                {
-                    return tptr.next.ty == Tchar;
-                }
-                return false;
-            }
-
-            bool isVa_list(Parameter p)
-            {
-                return p.type.equals(target.va_listType(funcdecl.loc, sc));
-            }
-
-            const nparams = f.parameterList.length;
-            if ((f.linkage == LINK.c || f.linkage == LINK.cpp) &&
-
-                (f.parameterList.varargs == VarArg.variadic &&
-                 nparams >= 1 &&
-                 isPointerToChar(f.parameterList[nparams - 1]) ||
-
-                 f.parameterList.varargs == VarArg.none &&
-                 nparams >= 2 &&
-                 isPointerToChar(f.parameterList[nparams - 2]) &&
-                 isVa_list(f.parameterList[nparams - 1])
-                )
-               )
-            {
-                // the signature is valid for printf/scanf, no error
-            }
-            else
-            {
-                const p = (funcdecl.printf ? Id.printf : Id.scanf).toChars();
-                if (f.parameterList.varargs == VarArg.variadic)
-                {
-                    funcdecl.error("`pragma(%s)` functions must be `extern(C) %s %s([parameters...], const(char)*, ...)`"
-                                   ~ " not `%s`",
-                        p, f.next.toChars(), funcdecl.toChars(), funcdecl.type.toChars());
-                }
-                else
-                {
-                    funcdecl.error("`pragma(%s)` functions must be `extern(C) %s %s([parameters...], const(char)*, va_list)`",
-                        p, f.next.toChars(), funcdecl.toChars());
-                }
-            }
+            checkPrintfScanfSignature(funcdecl, f, sc);
         }
 
         if (auto id = parent.isInterfaceDeclaration())
@@ -4869,11 +4811,14 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
             sd.deferred.semantic3(sc);
         }
 
-        // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
-        // Deprecated in 2.100
-        // Make an error in 2.110
-        if (sd.storage_class & STC.scope_)
-            deprecation(sd.loc, "`scope` as a type constraint is deprecated.  Use `scope` at the usage site.");
+        version (none)
+        {
+            // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
+            // Deprecated in 2.100
+            // Make an error in 2.110
+            if (sd.storage_class & STC.scope_)
+                deprecation(sd.loc, "`scope` as a type constraint is deprecated.  Use `scope` at the usage site.");
+        }
         //printf("-StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", sd, sd.toPrettyChars(), sd.sizeok);
     }
 
@@ -5538,12 +5483,15 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
         }
         //printf("-ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
 
-        // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
-        // Deprecated in 2.100
-        // Make an error in 2.110
-        // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036
-        if (cldec.storage_class & STC.scope_)
-            deprecation(cldec.loc, "`scope` as a type constraint is deprecated.  Use `scope` at the usage site.");
+        version (none)
+        {
+            // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
+            // Deprecated in 2.100
+            // Make an error in 2.110
+            // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036
+            if (cldec.storage_class & STC.scope_)
+                deprecation(cldec.loc, "`scope` as a type constraint is deprecated.  Use `scope` at the usage site.");
+        }
     }
 
     override void visit(InterfaceDeclaration idec)
@@ -5844,12 +5792,15 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
         }
         assert(idec.type.ty != Tclass || (cast(TypeClass)idec.type).sym == idec);
 
-        // @@@DEPRECATED_2.120@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
-        // Deprecated in 2.087
-        // Made an error in 2.100, but removal depends on `scope class` being removed too
-        // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036
-        if (idec.storage_class & STC.scope_)
-            error(idec.loc, "`scope` as a type constraint is obsolete.  Use `scope` at the usage site.");
+        version (none)
+        {
+            // @@@DEPRECATED_2.120@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
+            // Deprecated in 2.087
+            // Made an error in 2.100, but removal depends on `scope class` being removed too
+            // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036
+            if (idec.storage_class & STC.scope_)
+                error(idec.loc, "`scope` as a type constraint is obsolete.  Use `scope` at the usage site.");
+        }
     }
 }
 
@@ -7386,3 +7337,64 @@  private void writeMixin(const(char)[] s, ref const Loc loc, ref int lines, ref O
     buf.writenl();
     ++lines;
 }
+
+/**
+ * Check signature of `pragma(printf)` function, print error if invalid.
+ *
+ * printf/scanf-like functions must be of the form:
+ *    extern (C/C++) T printf([parameters...], const(char)* format, ...);
+ * or:
+ *    extern (C/C++) T vprintf([parameters...], const(char)* format, va_list);
+ *
+ * Params:
+ *      funcdecl = function to check
+ *      f = function type
+ *      sc = scope
+ */
+void checkPrintfScanfSignature(FuncDeclaration funcdecl, TypeFunction f, Scope* sc)
+{
+    static bool isPointerToChar(Parameter p)
+    {
+        if (auto tptr = p.type.isTypePointer())
+        {
+            return tptr.next.ty == Tchar;
+        }
+        return false;
+    }
+
+    bool isVa_list(Parameter p)
+    {
+        return p.type.equals(target.va_listType(funcdecl.loc, sc));
+    }
+
+    const nparams = f.parameterList.length;
+    const p = (funcdecl.printf ? Id.printf : Id.scanf).toChars();
+    if (!(f.linkage == LINK.c || f.linkage == LINK.cpp))
+    {
+        .error(funcdecl.loc, "`pragma(%s)` function `%s` must have `extern(C)` or `extern(C++)` linkage,"
+            ~" not `extern(%s)`",
+            p, funcdecl.toChars(), f.linkage.linkageToChars());
+    }
+    if (f.parameterList.varargs == VarArg.variadic)
+    {
+        if (!(nparams >= 1 && isPointerToChar(f.parameterList[nparams - 1])))
+        {
+            .error(funcdecl.loc, "`pragma(%s)` function `%s` must have"
+                ~ " signature `%s %s([parameters...], const(char)*, ...)` not `%s`",
+                p, funcdecl.toChars(), f.next.toChars(), funcdecl.toChars(), funcdecl.type.toChars());
+        }
+    }
+    else if (f.parameterList.varargs == VarArg.none)
+    {
+        if(!(nparams >= 2 && isPointerToChar(f.parameterList[nparams - 2]) &&
+            isVa_list(f.parameterList[nparams - 1])))
+            .error(funcdecl.loc, "`pragma(%s)` function `%s` must have"~
+                " signature `%s %s([parameters...], const(char)*, va_list)`",
+                p, funcdecl.toChars(), f.next.toChars(), funcdecl.toChars());
+    }
+    else
+    {
+        .error(funcdecl.loc, "`pragma(%s)` function `%s` must have C-style variadic `...` or `va_list` parameter",
+            p, funcdecl.toChars());
+    }
+}
diff --git a/gcc/d/dmd/errors.d b/gcc/d/dmd/errors.d
index 287dc4963e9..1f7a78eb6a2 100644
--- a/gcc/d/dmd/errors.d
+++ b/gcc/d/dmd/errors.d
@@ -119,22 +119,32 @@  else
 
 package auto previewErrorFunc(bool isDeprecated, FeatureState featureState) @safe @nogc pure nothrow
 {
-    if (featureState == FeatureState.enabled)
-        return &error;
-    else if (featureState == FeatureState.disabled || isDeprecated)
-        return &noop;
-    else
-        return &deprecation;
+    with (FeatureState) final switch (featureState)
+    {
+        case enabled:
+            return &error;
+
+        case disabled:
+            return &noop;
+
+        case default_:
+            return isDeprecated ? &noop : &deprecation;
+    }
 }
 
 package auto previewSupplementalFunc(bool isDeprecated, FeatureState featureState) @safe @nogc pure nothrow
 {
-    if (featureState == FeatureState.enabled)
-        return &errorSupplemental;
-    else if (featureState == FeatureState.disabled || isDeprecated)
-        return &noop;
-    else
-        return &deprecationSupplemental;
+    with (FeatureState) final switch (featureState)
+    {
+        case enabled:
+            return &errorSupplemental;
+
+        case disabled:
+            return &noop;
+
+        case default_:
+            return isDeprecated ? &noop : &deprecationSupplemental;
+    }
 }
 
 
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 35f11afdc93..9477867e929 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -2468,19 +2468,13 @@  extern (C++) class ThisExp : Expression
         return typeof(return)(true);
     }
 
-    override final bool isLvalue()
+    override bool isLvalue()
     {
-        // Class `this` should be an rvalue; struct `this` should be an lvalue.
-        return type.toBasetype().ty != Tclass;
+        return true;
     }
 
-    override final Expression toLvalue(Scope* sc, Expression e)
+    override Expression toLvalue(Scope* sc, Expression e)
     {
-        if (type.toBasetype().ty == Tclass)
-        {
-            // Class `this` is an rvalue; struct `this` is an lvalue.
-            return Expression.toLvalue(sc, e);
-        }
         return this;
     }
 
@@ -2500,6 +2494,18 @@  extern (C++) final class SuperExp : ThisExp
         super(loc, EXP.super_);
     }
 
+    override bool isLvalue()
+    {
+        // Class `super` should be an rvalue
+        return false;
+    }
+
+    override Expression toLvalue(Scope* sc, Expression e)
+    {
+        // Class `super` is an rvalue
+        return Expression.toLvalue(sc, e);
+    }
+
     override void accept(Visitor v)
     {
         v.visit(this);
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index 770c3e7ae3d..8c6393fb6e1 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -348,8 +348,8 @@  public:
 
     ThisExp *syntaxCopy() override;
     Optional<bool> toBool() override;
-    bool isLvalue() override final;
-    Expression *toLvalue(Scope *sc, Expression *e) override final;
+    bool isLvalue() override;
+    Expression *toLvalue(Scope *sc, Expression *e) override;
 
     void accept(Visitor *v) override { v->visit(this); }
 };
@@ -357,6 +357,8 @@  public:
 class SuperExp final : public ThisExp
 {
 public:
+    bool isLvalue() override;
+    Expression* toLvalue(Scope* sc, Expression* e) final override;
     void accept(Visitor *v) override { v->visit(this); }
 };
 
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index be597dfa90f..25f755bdf0e 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -3556,7 +3556,7 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
      */
     private void tryLowerToNewItem(NewExp ne)
     {
-        if (global.params.betterC || !sc.needsCodegen())
+        if (!global.params.useGC || !sc.needsCodegen())
             return;
 
         auto hook = global.params.tracegc ? Id._d_newitemTTrace : Id._d_newitemT;
@@ -11069,7 +11069,7 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
         /* `_d_arraycatnTX` canot be used with `-betterC`, but `CatExp`s may be
          * used with `-betterC`, but only during CTFE.
          */
-        if (global.params.betterC || !sc.needsCodegen())
+        if (!global.params.useGC || !sc.needsCodegen())
             return;
 
         if (auto ce = exp.isCatExp())
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index a714d2d281a..60457351af6 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -2019,7 +2019,8 @@  extern (C++) class FuncDeclaration : Declaration
         overloadApply(cast() this, (Dsymbol s)
         {
             auto f = s.isFuncDeclaration();
-            if (!f)
+            auto td = s.isTemplateDeclaration();
+            if (!f && !td)
                 return 0;
             if (result)
             {
@@ -2243,7 +2244,7 @@  extern (C++) class FuncDeclaration : Declaration
             if (global.gag)     // need not report supplemental errors
                 return true;
         }
-        else if (global.params.betterC)
+        else if (!global.params.useGC)
         {
             error("is `-betterC` yet allocates closure for `%s()` with the GC", toChars());
             if (global.gag)     // need not report supplemental errors
@@ -4605,16 +4606,15 @@  bool setUnsafe(Scope* sc,
 bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)* msg,
     RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
 {
-    if (fs == FeatureState.disabled)
+    with (FeatureState) final switch (fs)
     {
+      case disabled:
         return false;
-    }
-    else if (fs == FeatureState.enabled)
-    {
+
+      case enabled:
         return sc.setUnsafe(gag, loc, msg, arg0, arg1, arg2);
-    }
-    else
-    {
+
+      case default_:
         if (!sc.func)
             return false;
         if (sc.func.isSafeBypassingInference())
diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d
index 0ac60420ef7..9071e6a58ca 100644
--- a/gcc/d/dmd/globals.d
+++ b/gcc/d/dmd/globals.d
@@ -81,11 +81,11 @@  enum CppStdRevision : uint
 }
 
 /// Trivalent boolean to represent the state of a `revert`able change
-enum FeatureState : byte
+enum FeatureState : ubyte
 {
-    default_ = -1, /// Not specified by the user
-    disabled = 0,  /// Specified as `-revert=`
-    enabled = 1    /// Specified as `-preview=`
+    default_ = 0,  /// Not specified by the user
+    disabled = 1,  /// Specified as `-revert=`
+    enabled  = 2,  /// Specified as `-preview=`
 }
 
 extern(C++) struct Output
@@ -124,6 +124,7 @@  extern (C++) struct Param
     bool release;           // build release version
     bool preservePaths;     // true means don't strip path from source file
     DiagnosticReporting warnings = DiagnosticReporting.off;  // how compiler warnings are handled
+    bool obsolete;          // enable warnings about use of obsolete messages
     bool color;             // use ANSI colors in console output
     bool cov;               // generate code coverage data
     ubyte covPercent;       // 0..100 code coverage percentage required
@@ -132,6 +133,7 @@  extern (C++) struct Param
     bool useModuleInfo = true;   // generate runtime module information
     bool useTypeInfo = true;     // generate runtime type information
     bool useExceptions = true;   // support exception handling
+    bool useGC = true;           // support features that require the GC
     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
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index 66345acc88b..0dad5dd12e7 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -75,11 +75,11 @@  enum CppStdRevision
 };
 
 /// Trivalent boolean to represent the state of a `revert`able change
-enum class FeatureState : signed char
+enum class FeatureState : unsigned char
 {
-    default_ = -1, /// Not specified by the user
-    disabled = 0,  /// Specified as `-revert=`
-    enabled = 1    /// Specified as `-preview=`
+    default_ = 0,  /// Not specified by the user
+    disabled = 1,  /// Specified as `-revert=`
+    enabled  = 2,  /// Specified as `-preview=`
 };
 
 struct Output
@@ -119,6 +119,7 @@  struct Param
     d_bool release;       // build release version
     d_bool preservePaths; // true means don't strip path from source file
     Diagnostic warnings;
+    d_bool obsolete;      // warn about use of obsolete features
     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
@@ -127,6 +128,7 @@  struct Param
     d_bool useModuleInfo; // generate runtime module information
     d_bool useTypeInfo;   // generate runtime type information
     d_bool useExceptions; // support exception handling
+    d_bool useGC;         // support features that require the GC
     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
@@ -263,6 +265,7 @@  struct CompileEnv
     bool previewIn;
     bool ddocOutput;
     bool shortenedMethods;
+    bool obsolete;
 };
 
 struct Global
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index ee288d1e474..c60b4311ff5 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -772,10 +772,13 @@  extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
             const nfields = sd.fields.length;
             size_t fieldi = 0;
 
+        Loop1:
             for (size_t index = 0; index < ci.initializerList.length; )
             {
-                auto di = ci.initializerList[index];
-                auto dlist = di.designatorList;
+                CInitializer cprev;
+             L1:
+                DesigInit di = ci.initializerList[index];
+                Designators* dlist = di.designatorList;
                 if (dlist)
                 {
                     const length = (*dlist).length;
@@ -798,9 +801,19 @@  extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
                             si.addInit(id, di.initializer);
                             ++fieldi;
                             ++index;
-                            break;
+                            continue Loop1;
                         }
                     }
+                    if (cprev)
+                    {
+                        /* The peeling didn't work, so unpeel it
+                         */
+                        ci = cprev;
+                        di = ci.initializerList[index];
+                        goto L2;
+                    }
+                    error(ci.loc, "`.%s` is not a field of `%s`\n", id.toChars(), sd.toChars());
+                    return err();
                 }
                 else
                 {
@@ -808,10 +821,14 @@  extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
                         break;
                     if (index == 0 && ci.initializerList.length == 1 && di.initializer.isCInitializer())
                     {
+                        /* Try peeling off this set of { } and see if it works
+                         */
+                        cprev = ci;
                         ci = di.initializer.isCInitializer();
-                        continue;
+                        goto L1;
                     }
 
+                L2:
                     VarDeclaration field;
                     while (1)   // skip field if it overlaps with previously seen fields
                     {
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index add1ce68468..9cce7c56723 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -51,6 +51,7 @@  struct CompileEnv
     bool previewIn;          /// `in` means `[ref] scope const`, accepts rvalues
     bool ddocOutput;         /// collect embedded documentation comments
     bool shortenedMethods = true;   /// allow => in normal function declarations
+    bool obsolete;           /// warn on use of legacy code
 }
 
 /***********************************************************
diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d
index 9a8f2422746..d7a28209b3e 100644
--- a/gcc/d/dmd/nogc.d
+++ b/gcc/d/dmd/nogc.d
@@ -219,7 +219,7 @@  Expression checkGC(Scope* sc, Expression e)
      * Just don't generate code for it.
      * Detect non-CTFE use of the GC in betterC code.
      */
-    const betterC = global.params.betterC;
+    const betterC = !global.params.useGC;
     FuncDeclaration f = sc.func;
     if (e && e.op != EXP.error && f && sc.intypeof != 1 &&
            (!(sc.flags & SCOPE.ctfe) || betterC) &&
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index eeaef8d7d8b..d15e448150f 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -718,13 +718,8 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                      tk.value == TOK.out_ || tk.value == TOK.do_ || tk.value == TOK.goesTo ||
                      tk.value == TOK.identifier && tk.ident == Id._body))
                 {
-                    // @@@DEPRECATED_2.117@@@
-                    // https://github.com/dlang/DIPs/blob/1f5959abe482b1f9094f6484a7d0a3ade77fc2fc/DIPs/accepted/DIP1003.md
-                    // Deprecated in 2.097 - Can be removed from 2.117
-                    // The deprecation period is longer than usual as `body`
-                    // was quite widely used.
                     if (tk.value == TOK.identifier && tk.ident == Id._body)
-                        deprecation("usage of the `body` keyword is deprecated. Use `do` instead.");
+                        usageOfBodyKeyword();
 
                     a = parseDeclarations(true, pAttrs, pAttrs.comment);
                     if (a && a.length)
@@ -1163,7 +1158,7 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                 a = parseDeclDefs(0, pLastDecl);
                 if (token.value != TOK.rightCurly)
                 {
-                    /* { */
+                    /* left curly brace */
                     error("matching `}` expected, not `%s`", token.toChars());
                     eSink.errorSupplemental(lcLoc, "unmatched `{`");
                 }
@@ -1505,7 +1500,7 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
         if (token.value != TOK.leftCurly)
         {
-            error("`{` expected after template parameter list, not `%s`", token.toChars());
+            error("`{` expected after template parameter list, not `%s`", token.toChars()); /* } */
             goto Lerr;
         }
         decldefs = parseBlock(null);
@@ -2724,7 +2719,7 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
         nextToken();
 
-        const(char)* begPtr = token.ptr + 1; // skip '{'
+        const(char)* begPtr = token.ptr + 1; // skip left curly brace
         const(char)* endPtr = null;
         AST.Statement sbody = parseStatement(ParseStatementFlags.curly, &endPtr);
 
@@ -3041,6 +3036,7 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
         }
 
         e = new AST.EnumDeclaration(loc, id, memtype);
+        // opaque type
         if (token.value == TOK.semicolon && id)
             nextToken();
         else if (token.value == TOK.leftCurly)
@@ -3073,7 +3069,7 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                     && token.value != TOK.comma
                     && token.value != TOK.assign)
                 {
-                    switch(token.value)
+                    switch (token.value)
                     {
                         case TOK.at:
                             if (StorageClass _stc = parseAttribute(udas))
@@ -3109,12 +3105,23 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                             }
                             else
                             {
-                                goto default;
+                                if (isAnonymousEnum)
+                                    goto default; // maybe `Type identifier`
+
+                                prevTOK = token.value;
+                                nextToken();
+                                error("expected `,` or `=` after identifier, not `%s`", token.toChars());
                             }
                             break;
                         default:
                             if (isAnonymousEnum)
                             {
+                                if (type)
+                                {
+                                    error("expected identifier after type, not `%s`", token.toChars());
+                                    type = null;
+                                    break;
+                                }
                                 type = parseType(&ident, null);
                                 if (type == AST.Type.terror)
                                 {
@@ -3125,6 +3132,11 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                                 else
                                 {
                                     prevTOK = TOK.identifier;
+                                    const tv = token.value;
+                                    if (ident && tv != TOK.assign && tv != TOK.comma && tv != TOK.rightCurly)
+                                    {
+                                        error("expected `,` or `=` after identifier, not `%s`", token.toChars());
+                                    }
                                 }
                             }
                             else
@@ -3166,7 +3178,7 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                 {
                     value = null;
                     if (type && type != AST.Type.terror && isAnonymousEnum)
-                        error("if type, there must be an initializer");
+                        error("initializer required after `%s` when type is specified", ident.toChars());
                 }
 
                 AST.DeprecatedDeclaration dd;
@@ -3471,6 +3483,11 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
         return decldefs;
     }
 
+    /* Parse a type and optional identifier
+     * Params:
+     *  pident       = set to Identifier if there is one, null if not
+     *  ptpl         = if !null, then set to TemplateParameterList
+     */
     AST.Type parseType(Identifier* pident = null, AST.TemplateParameters** ptpl = null)
     {
         /* Take care of the storage class prefixes that
@@ -4450,13 +4467,8 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                     (tk.value == TOK.leftParenthesis || tk.value == TOK.leftCurly || tk.value == TOK.in_ || tk.value == TOK.out_ || tk.value == TOK.goesTo ||
                      tk.value == TOK.do_ || tk.value == TOK.identifier && tk.ident == Id._body))
                 {
-                    // @@@DEPRECATED_2.117@@@
-                    // https://github.com/dlang/DIPs/blob/1f5959abe482b1f9094f6484a7d0a3ade77fc2fc/DIPs/accepted/DIP1003.md
-                    // Deprecated in 2.097 - Can be removed from 2.117
-                    // The deprecation period is longer than usual as `body`
-                    // was quite widely used.
                     if (tk.value == TOK.identifier && tk.ident == Id._body)
-                        deprecation("usage of the `body` keyword is deprecated. Use `do` instead.");
+                        usageOfBodyKeyword();
 
                     ts = null;
                 }
@@ -4569,6 +4581,9 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
             }
             else if (t.ty == Tfunction)
             {
+                if (storage_class & STC.manifest)
+                    error("function cannot have enum storage class");
+
                 AST.Expression constraint = null;
                 //printf("%s funcdecl t = %s, storage_class = x%lx\n", loc.toChars(), t.toChars(), storage_class);
                 auto f = new AST.FuncDeclaration(loc, Loc.initial, ident, storage_class | (disable ? STC.disable : 0), t);
@@ -5193,12 +5208,7 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
         case TOK.identifier:
             if (token.ident == Id._body)
             {
-                // @@@DEPRECATED_2.117@@@
-                // https://github.com/dlang/DIPs/blob/1f5959abe482b1f9094f6484a7d0a3ade77fc2fc/DIPs/accepted/DIP1003.md
-                // Deprecated in 2.097 - Can be removed from 2.117
-                // The deprecation period is longer than usual as `body`
-                // was quite widely used.
-                deprecation("usage of the `body` keyword is deprecated. Use `do` instead.");
+                usageOfBodyKeyword();
                 goto case TOK.do_;
             }
             goto default;
@@ -6027,7 +6037,7 @@  LagainStc:
                 auto statements = new AST.Statements();
                 while (token.value != TOK.rightCurly && token.value != TOK.endOfFile)
                 {
-                    statements.push(parseStatement(ParseStatementFlags.curlyScope));
+                    statements.push(parseStatement(ParseStatementFlags.curlyScope | ParseStatementFlags.semiOk));
                 }
                 if (endPtr)
                     *endPtr = token.ptr;
@@ -7572,12 +7582,7 @@  LagainStc:
             case TOK.identifier:
                 if (t.ident == Id._body)
                 {
-                    // @@@DEPRECATED_2.117@@@
-                    // https://github.com/dlang/DIPs/blob/1f5959abe482b1f9094f6484a7d0a3ade77fc2fc/DIPs/accepted/DIP1003.md
-                    // Deprecated in 2.097 - Can be removed from 2.117
-                    // The deprecation period is longer than usual as `body`
-                    // was quite widely used.
-                    deprecation("usage of the `body` keyword is deprecated. Use `do` instead.");
+                    usageOfBodyKeyword();
                     goto case TOK.do_;
                 }
                 goto default;
@@ -8806,6 +8811,7 @@  LagainStc:
                             {
                                 // (type) una_exp
                                 nextToken();
+                                // Note: `t` may be an expression that looks like a type
                                 auto t = parseType();
                                 check(TOK.rightParenthesis);
 
@@ -8823,6 +8829,16 @@  LagainStc:
                                     te.parens = true;
                                     e = parsePostExp(te);
                                 }
+                                else if (token.value == TOK.leftParenthesis ||
+                                    token.value == TOK.plusPlus || token.value == TOK.minusMinus)
+                                {
+                                    // (type)(expr)
+                                    // (callable)(args)
+                                    // (expr)++
+                                    auto te = new AST.TypeExp(loc, t);
+                                    te.parens = true;
+                                    e = parsePostExp(te);
+                                }
                                 else
                                 {
                                     e = parseUnaryExp();
@@ -9526,6 +9542,14 @@  LagainStc:
                 STC.live     |
                 /*STC.future   |*/ // probably should be included
                 STC.disable;
+
+    void usageOfBodyKeyword()
+    {
+        if (compileEnv.obsolete)
+        {
+            eSink.warning(token.loc, "usage of identifer `body` as a keyword is obsolete. Use `do` instead.");
+        }
+    }
 }
 
 enum PREC : int
diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d
index e4ca22a98b5..c7d12194820 100644
--- a/gcc/d/dmd/semantic3.d
+++ b/gcc/d/dmd/semantic3.d
@@ -1422,7 +1422,8 @@  private extern(C++) final class Semantic3Visitor : Visitor
          * https://issues.dlang.org/show_bug.cgi?id=14246
          */
         AggregateDeclaration ad = ctor.isMemberDecl();
-        if (!ctor.fbody || !ad || !ad.fieldDtor || !global.params.dtorFields || !global.params.useExceptions || ctor.type.toTypeFunction.isnothrow)
+        if (!ctor.fbody || !ad || !ad.fieldDtor ||
+	    global.params.dtorFields == FeatureState.disabled || !global.params.useExceptions || ctor.type.toTypeFunction.isnothrow)
             return visit(cast(FuncDeclaration)ctor);
 
         /* Generate:
diff --git a/gcc/d/dmd/target.d b/gcc/d/dmd/target.d
index fddfd546742..81ff84f361e 100644
--- a/gcc/d/dmd/target.d
+++ b/gcc/d/dmd/target.d
@@ -25,7 +25,7 @@ 
 
 module dmd.target;
 
-import dmd.globals : Param;
+import dmd.globals : Param, CHECKENABLE;
 
 enum CPU : ubyte
 {
@@ -111,7 +111,7 @@  extern (C++) struct Target
     /// Architecture name
     const(char)[] architectureName;
     CPU cpu = CPU.baseline; // CPU instruction set to target
-    bool is64bit;           // generate 64 bit code for x86_64; true by default for 64 bit dmd
+    bool isX86_64;          // generate 64 bit code for x86_64; true by default for 64 bit dmd
     bool isLP64;            // pointers are 64 bits
 
     // Environmental
diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h
index 561afa18d42..ca0e09c88e0 100644
--- a/gcc/d/dmd/target.h
+++ b/gcc/d/dmd/target.h
@@ -156,7 +156,7 @@  struct Target
 
     DString architectureName;    // name of the platform architecture (e.g. X86_64)
     CPU cpu;                // CPU instruction set to target
-    d_bool is64bit;           // generate 64 bit code for x86_64; true by default for 64 bit dmd
+    d_bool isX86_64;          // generate 64 bit code for x86_64; true by default for 64 bit dmd
     d_bool isLP64;            // pointers are 64 bits
 
     // Environmental
diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d
index caebf1cee25..0d9c95ff173 100644
--- a/gcc/d/dmd/traits.d
+++ b/gcc/d/dmd/traits.d
@@ -947,15 +947,24 @@  Expression semanticTraits(TraitsExp e, Scope* sc)
          */
 
         Dsymbol sym = getDsymbol(o);
+
+        if (sym && e.ident == Id.hasMember)
+        {
+            if (auto sm = sym.search(e.loc, id))
+                return True();
+
+            // https://issues.dlang.org/show_bug.cgi?id=23951
+            if (auto decl = sym.isDeclaration())
+            {
+                ex = typeDotIdExp(e.loc, decl.type, id);
+                goto doSemantic;
+            }
+        }
+
         if (auto t = isType(o))
             ex = typeDotIdExp(e.loc, t, id);
         else if (sym)
         {
-            if (e.ident == Id.hasMember)
-            {
-                if (auto sm = sym.search(e.loc, id))
-                    return True();
-            }
             ex = new DsymbolExp(e.loc, sym);
             ex = new DotIdExp(e.loc, ex, id);
         }
@@ -966,7 +975,7 @@  Expression semanticTraits(TraitsExp e, Scope* sc)
             e.error("invalid first argument");
             return ErrorExp.get();
         }
-
+    doSemantic:
         // ignore symbol visibility and disable access checks for these traits
         Scope* scx = sc.push();
         scx.flags |= SCOPE.ignoresymbolvisibility | SCOPE.noaccesscheck;
@@ -1223,7 +1232,7 @@  Expression semanticTraits(TraitsExp e, Scope* sc)
             // @@@DEPRECATION 2.100.2
             if (auto td = s.isTemplateDeclaration())
             {
-                if (td.overnext || td.funcroot)
+                if (td.overnext || td.overroot)
                 {
                     deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not the overload set `%s`", td.ident.toChars());
                     deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from");
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 8fb1eea65a6..7038655bc94 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -695,7 +695,7 @@  public:
   {
     /* This error is only emitted during the code generation pass because
        concatentation is allowed in CTFE.  */
-    if (global.params.betterC)
+    if (!global.params.useGC)
       {
 	error_at (make_location_t (e->loc),
 		  "array concatenation of expression %qs requires the GC and "
diff --git a/gcc/testsuite/gdc.test/compilable/cppmangle.d b/gcc/testsuite/gdc.test/compilable/cppmangle.d
index fc74c944cad..264b374dd55 100644
--- a/gcc/testsuite/gdc.test/compilable/cppmangle.d
+++ b/gcc/testsuite/gdc.test/compilable/cppmangle.d
@@ -528,7 +528,6 @@  version (CppMangle_Itanium)
     static assert(basic_ostream!(char, char_traits!char).food.mangleof == "_ZNSo4foodEv");
     static assert(basic_iostream!(char, char_traits!char).fooe.mangleof == "_ZNSd4fooeEv");
 
-    static assert(func_18957_2.mangleof == `_Z12func_18957_2PSaIiE`);
     static assert(func_18957_2!(allocator!int).mangleof == `_Z12func_18957_2ISaIiEET_PS1_`);
 
     static assert(func_20413.mangleof == `_Z10func_20413St4pairIifES_IfiE`);
diff --git a/gcc/testsuite/gdc.test/compilable/deprecate14283.d b/gcc/testsuite/gdc.test/compilable/deprecate14283.d
index e91db649cee..fc51cf3f0b6 100644
--- a/gcc/testsuite/gdc.test/compilable/deprecate14283.d
+++ b/gcc/testsuite/gdc.test/compilable/deprecate14283.d
@@ -1,12 +1,12 @@ 
-// REQUIRED_ARGS: -dw
+// REQUIRED_ARGS:
 // PERMUTE_ARGS:
 class C
 {
     void bug()
     {
-        autoref(this);  // 'auto ref' becomes non-ref parameter
-        autoref(super); // 'auto ref' becomes non-ref parameter
+        autoref!(true, C)(this);  // 'auto ref' becomes ref parameter
+        autoref!(false, Object)(super); // 'auto ref' becomes non-ref parameter
     }
 }
 
-void autoref(T)(auto ref T t) { static assert(__traits(isRef, t) == false); }
+void autoref(bool result, T)(auto ref T t) { static assert(__traits(isRef, t) == result); }
diff --git a/gcc/testsuite/gdc.test/compilable/emptystatement.d b/gcc/testsuite/gdc.test/compilable/emptystatement.d
new file mode 100644
index 00000000000..e6bfc27caa4
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/emptystatement.d
@@ -0,0 +1,19 @@ 
+/*
+REQUIRED_ARGS:
+TEST_OUTPUT:
+---
+---
+*/
+
+void foo()
+{
+    int x;;
+    enum A
+    {
+        a,
+        b,
+        c
+    };
+
+    void bar() {};
+}
diff --git a/gcc/testsuite/gdc.test/compilable/imports/imp24022.c b/gcc/testsuite/gdc.test/compilable/imports/imp24022.c
new file mode 100644
index 00000000000..b65e4e155bf
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/imp24022.c
@@ -0,0 +1,5 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=24022
+typedef enum {
+    A = 1,
+    B,
+} E;
diff --git a/gcc/testsuite/gdc.test/compilable/parens_inc.d b/gcc/testsuite/gdc.test/compilable/parens_inc.d
new file mode 100644
index 00000000000..b9d11eb9b8e
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/parens_inc.d
@@ -0,0 +1,23 @@ 
+// Test UnaryExp (expr)++ parsing
+
+void main(){
+    int[2] y;
+    int *x = y.ptr;
+    *(x)++=0;
+    (*(x)--)=0;
+    (*x++)=0; // ok
+    int*[] z;
+    *(z[0])++=0; //ok
+    (y[0])--;
+    *x++=0;
+}
+
+void f()
+{
+    int b;
+    (b)++;
+    int[] a;
+    b = (a)[0]++; //ok
+    (a[0])--;
+    b = (int).init; //ok
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23951.d b/gcc/testsuite/gdc.test/compilable/test23951.d
new file mode 100644
index 00000000000..e09a3d7b5d1
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23951.d
@@ -0,0 +1,10 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23951
+
+struct S { int x; }
+struct T { S a; alias a this; }
+struct U { T t; }
+static assert(__traits(hasMember, T, "x"));
+static assert(__traits(hasMember, T.init, "x"));
+static assert(__traits(hasMember, U.init.t, "x"));
+static assert(__traits(hasMember, U.t, "a"));
+static assert(__traits(hasMember, U.t, "x"));
diff --git a/gcc/testsuite/gdc.test/compilable/test23966.d b/gcc/testsuite/gdc.test/compilable/test23966.d
new file mode 100644
index 00000000000..71aa8ca229e
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23966.d
@@ -0,0 +1,19 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23966
+module test23966;
+
+@("gigi")
+void fun() {}
+@("mimi")
+void fun(int) {}
+@("hihi")
+void fun(int, int) {}
+@("bibi")
+void fun()(int, ulong) {}
+
+void main()
+{
+    static foreach (t; __traits(getOverloads, test23966, "fun", true))
+        static foreach(attr; __traits(getAttributes, t))
+        {}
+
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test24022.d b/gcc/testsuite/gdc.test/compilable/test24022.d
new file mode 100644
index 00000000000..f499636f126
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test24022.d
@@ -0,0 +1,30 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=24022
+// EXTRA_FILES: imports/imp24022.c
+import imports.imp24022;
+
+auto some_d_func(E v) {
+    return v;
+}
+
+auto some_d_other_func() {
+    const struct R {
+        E r;
+        this(in E vparam) { r = vparam; }
+    }
+    return R(A);
+}
+
+void main(string[] args) {
+    E expected = E.A;
+    E res = some_d_func(A);
+    assert (res == A);
+    assert (res == expected);
+
+    res = some_d_func(E.B);
+    assert (res == B);
+    assert (res == E.B);
+
+    auto res2 = some_d_other_func();
+    assert (res2.r == A);
+    assert (res2.r == expected);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test7172.d b/gcc/testsuite/gdc.test/compilable/test7172.d
index 013630bd483..49142d78988 100644
--- a/gcc/testsuite/gdc.test/compilable/test7172.d
+++ b/gcc/testsuite/gdc.test/compilable/test7172.d
@@ -1,8 +1,4 @@ 
-/* TEST_OUTPUT:
----
-compilable/test7172.d(14): Deprecation: `scope` as a type constraint is deprecated.  Use `scope` at the usage site.
----
-*/
+
 void main()
 {
     abstract class AbstractC{}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/biterrors3.d b/gcc/testsuite/gdc.test/fail_compilation/biterrors3.d
index f9e1df2b7b2..c5031a4db10 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/biterrors3.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/biterrors3.d
@@ -2,7 +2,7 @@ 
  * TEST_OUTPUT:
 ---
 fail_compilation/biterrors3.d(103): Error: storage class not allowed for bit-field declaration
-fail_compilation/biterrors3.d(106): Error: `d` is not a valid attribute for enum members
+fail_compilation/biterrors3.d(106): Error: expected `,` or `=` after identifier, not `:`
 fail_compilation/biterrors3.d(106): Error: `:` is not a valid attribute for enum members
 fail_compilation/biterrors3.d(106): Error: `3` is not a valid attribute for enum members
 ---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/body.d b/gcc/testsuite/gdc.test/fail_compilation/body.d
new file mode 100644
index 00000000000..7b718c25060
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/body.d
@@ -0,0 +1,11 @@ 
+/* REQUIRED_ARGS: -wo -w
+TEST_OUTPUT:
+---
+fail_compilation/body.d(11): Warning: usage of identifer `body` as a keyword is obsolete. Use `do` instead.
+Error: warnings are treated as errors
+       Use -wi if you wish to treat warnings only as informational.
+---
+*/
+
+void test()
+in { } body { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ccast.d b/gcc/testsuite/gdc.test/fail_compilation/ccast.d
index dab29844158..f1ca6c0fada 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ccast.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ccast.d
@@ -1,9 +1,28 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/ccast.d(9): Error: C style cast illegal, use `cast(byte)i`
+fail_compilation/ccast.d(11): Error: C style cast illegal, use `cast(byte)i`
+fail_compilation/ccast.d(24): Error: C style cast illegal, use `cast(foo)5`
+fail_compilation/ccast.d(26): Error: C style cast illegal, use `cast(void*)5`
 ---
 */
 
 int i;
 byte b = (byte)i;
+
+void bar(int x);
+
+void main()
+{
+    (&bar)(5); // ok
+    auto foo = &bar;
+    (foo = foo)(5); // ok
+    (*foo)(5); // ok
+
+    (foo)(5); // ok
+    (bar)(5); // ok
+    (foo)5;
+
+    (void*)5;
+    (void*)(5); // semantic implicit cast error
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag4596.d b/gcc/testsuite/gdc.test/fail_compilation/diag4596.d
index f6b49d6bd13..517b328e8d6 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag4596.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag4596.d
@@ -1,13 +1,13 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/diag4596.d(15): Error: `this` is not an lvalue and cannot be modified
-fail_compilation/diag4596.d(16): Error: conditional expression `1 ? this : this` is not a modifiable lvalue
 fail_compilation/diag4596.d(18): Error: `super` is not an lvalue and cannot be modified
 fail_compilation/diag4596.d(19): Error: conditional expression `1 ? super : super` is not a modifiable lvalue
 ---
 */
 
+
+
 class NoGo4596
 {
     void fun()
diff --git a/gcc/testsuite/gdc.test/fail_compilation/enum_function.d b/gcc/testsuite/gdc.test/fail_compilation/enum_function.d
new file mode 100644
index 00000000000..b22f2ceccef
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/enum_function.d
@@ -0,0 +1,13 @@ 
+/*
+TEST_OUTPUT:
+---
+fail_compilation/enum_function.d(10): Error: function cannot have enum storage class
+fail_compilation/enum_function.d(11): Error: function cannot have enum storage class
+fail_compilation/enum_function.d(12): Error: function cannot have enum storage class
+fail_compilation/enum_function.d(13): Error: function cannot have enum storage class
+---
+*/
+enum void f1() { return; }
+enum f2() { return 5; }
+enum f3() => 5;
+enum int f4()() => 5;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10285.d b/gcc/testsuite/gdc.test/fail_compilation/fail10285.d
index 3277b19e2aa..c88e30688f7 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail10285.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail10285.d
@@ -1,10 +1,18 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail10285.d(9): Error: no identifier for declarator `int`
+fail_compilation/fail10285.d(13): Error: no identifier for declarator `int`
+fail_compilation/fail10285.d(14): Error: expected `,` or `=` after identifier, not `y`
+fail_compilation/fail10285.d(15): Error: expected identifier after type, not `bool`
+fail_compilation/fail10285.d(16): Error: expected identifier after type, not `int`
+fail_compilation/fail10285.d(18): Error: initializer required after `z` when type is specified
 ---
 */
 enum
 {
-    int = 5
+    int = 5,
+    int x y,
+    int bool i = 3,
+    j int k = 3,
+    int z
 }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail13116.d b/gcc/testsuite/gdc.test/fail_compilation/fail13116.d
index ac520d79997..077fa75ac77 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail13116.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail13116.d
@@ -1,7 +1,7 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail13116.d(14): Error: `this` is not an lvalue and cannot be modified
+fail_compilation/fail13116.d(14): Error: returning `this` escapes a reference to parameter `this`
 fail_compilation/fail13116.d(23): Error: `super` is not an lvalue and cannot be modified
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail15896.d b/gcc/testsuite/gdc.test/fail_compilation/fail15896.d
index e52503d0975..3fdbf4e9f98 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail15896.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail15896.d
@@ -14,5 +14,6 @@  int func()
 {
     thebar +=1;
     packagebar += 1;
+    thebar +=1;
     return 0;
 }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22729.d b/gcc/testsuite/gdc.test/fail_compilation/fail22729.d
index 38bbfeeed2b..d0c8aa9c2f3 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail22729.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22729.d
@@ -22,7 +22,7 @@  class Form : WidgetI
 
 template Tuple(Specs)
 {
-    enum areCompatibleTuples(Tup2)(Tuple tup1, Tup2 tup2)
+    auto areCompatibleTuples(Tup2)(Tuple tup1, Tup2 tup2)
     {
         tup1.field == tup2;
     }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22780.d b/gcc/testsuite/gdc.test/fail_compilation/fail22780.d
index e22be9fe047..8d4c8a891f0 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail22780.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22780.d
@@ -1,10 +1,10 @@ 
 // https://issues.dlang.org/show_bug.cgi?id=22780
 /* TEST_OUTPUT:
 ---
-fail_compilation/fail22780.d(8): Deprecation: `scope` as a type constraint is deprecated.  Use `scope` at the usage site.
 fail_compilation/fail22780.d(12): Error: variable `fail22780.test10717.c` reference to `scope class` must be `scope`
 ---
 */
+
 scope class C10717 { }
 
 void test10717()
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4559.d b/gcc/testsuite/gdc.test/fail_compilation/fail4559.d
deleted file mode 100644
index 657c184d787..00000000000
--- a/gcc/testsuite/gdc.test/fail_compilation/fail4559.d
+++ /dev/null
@@ -1,22 +0,0 @@ 
-/*
-REQUIRED_ARGS:
-TEST_OUTPUT:
----
-fail_compilation/fail4559.d(13): Error: use `{ }` for an empty statement, not `;`
-fail_compilation/fail4559.d(19): Error: use `{ }` for an empty statement, not `;`
-fail_compilation/fail4559.d(21): Error: use `{ }` for an empty statement, not `;`
----
-*/
-
-void foo()
-{
-    int x;;
-    enum A
-    {
-        a,
-        b,
-        c
-    };
-
-    void bar() {};
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/format.d b/gcc/testsuite/gdc.test/fail_compilation/format.d
index bc40d9a527a..cfd30bfc82e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/format.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/format.d
@@ -1,10 +1,10 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/format.d(101): Error: function `format.printf1` `pragma(printf)` functions must be `extern(C) void printf1([parameters...], const(char)*, ...)` not `void(const(char)*, ...)`
-fail_compilation/format.d(102): Error: function `format.printf2` `pragma(printf)` functions must be `extern(C) int printf2([parameters...], const(char)*, ...)` not `extern (C) int(const(int)*, ...)`
-fail_compilation/format.d(103): Error: function `format.printf3` `pragma(printf)` functions must be `extern(C) int printf3([parameters...], const(char)*, va_list)`
-fail_compilation/format.d(104): Error: function `format.printf4` `pragma(printf)` functions must be `extern(C) int printf4([parameters...], const(char)*, ...)` not `extern (C) int(const(char)*, int, ...)`
+fail_compilation/format.d(101): Error: `pragma(printf)` function `printf1` must have `extern(C)` or `extern(C++)` linkage, not `extern(D)`
+fail_compilation/format.d(102): Error: `pragma(printf)` function `printf2` must have signature `int printf2([parameters...], const(char)*, ...)` not `extern (C) int(const(int)*, ...)`
+fail_compilation/format.d(103): Error: `pragma(printf)` function `printf3` must have signature `int printf3([parameters...], const(char)*, va_list)`
+fail_compilation/format.d(104): Error: `pragma(printf)` function `printf4` must have signature `int printf4([parameters...], const(char)*, ...)` not `extern (C) int(const(char)*, int, ...)`
 ---
  */
 
@@ -22,10 +22,13 @@  pragma(printf) extern (C) int printf7(char*, ...);
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/format.d(203): Error: function `format.vprintf1` `pragma(printf)` functions must be `extern(C) void vprintf1([parameters...], const(char)*, va_list)`
-fail_compilation/format.d(204): Error: function `format.vprintf2` `pragma(printf)` functions must be `extern(C) int vprintf2([parameters...], const(char)*, va_list)`
-fail_compilation/format.d(205): Error: function `format.vprintf3` `pragma(printf)` functions must be `extern(C) int vprintf3([parameters...], const(char)*, va_list)`
-fail_compilation/format.d(206): Error: function `format.vprintf4` `pragma(printf)` functions must be `extern(C) int vprintf4([parameters...], const(char)*, va_list)`
+fail_compilation/format.d(203): Error: `pragma(printf)` function `vprintf1` must have `extern(C)` or `extern(C++)` linkage, not `extern(D)`
+fail_compilation/format.d(204): Error: `pragma(printf)` function `vprintf2` must have signature `int vprintf2([parameters...], const(char)*, va_list)`
+fail_compilation/format.d(205): Error: `pragma(printf)` function `vprintf3` must have signature `int vprintf3([parameters...], const(char)*, va_list)`
+fail_compilation/format.d(206): Error: `pragma(printf)` function `vprintf4` must have signature `int vprintf4([parameters...], const(char)*, va_list)`
+fail_compilation/format.d(207): Error: `pragma(printf)` function `vprintf5` must have C-style variadic `...` or `va_list` parameter
+fail_compilation/format.d(208): Error: `pragma(scanf)` function `vscanf1` must have `extern(C)` or `extern(C++)` linkage, not `extern(Windows)`
+fail_compilation/format.d(208): Error: `pragma(scanf)` function `vscanf1` must have signature `int vscanf1([parameters...], const(char)*, va_list)`
 ---
  */
 
@@ -37,6 +40,8 @@  pragma(printf)           void vprintf1(const(char)*, va_list);
 pragma(printf) extern (C) int vprintf2(const(int )*, va_list);
 pragma(printf) extern (C) int vprintf3(const(char)*);
 pragma(printf) extern (C) int vprintf4(const(char)*, int, va_list);
+pragma(printf) extern (C) int vprintf5(char*, int[] a...);
+pragma(scanf)  extern (Windows) int vscanf1();
 
 pragma(printf) extern (C) int vprintf5(const(char)*, va_list);
 pragma(printf) extern (C) int vprintf6(immutable(char)*, va_list);
diff --git a/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d b/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d
index 29f96ece787..f7a554ce729 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d
@@ -118,6 +118,7 @@  fail_compilation/reserved_version.d(219): Error: version identifier `D_PostCondi
 fail_compilation/reserved_version.d(220): Error: version identifier `D_ProfileGC` is reserved and cannot be set
 fail_compilation/reserved_version.d(221): Error: version identifier `D_Invariants` is reserved and cannot be set
 fail_compilation/reserved_version.d(222): Error: version identifier `D_Optimized` is reserved and cannot be set
+fail_compilation/reserved_version.d(223): Error: version identifier `VisionOS` is reserved and cannot be set
 ---
 */
 
@@ -242,6 +243,7 @@  version = D_PostConditions;
 version = D_ProfileGC;
 version = D_Invariants;
 version = D_Optimized;
+version = VisionOS;
 
 // This should work though
 debug = DigitalMars;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/scope_class.d b/gcc/testsuite/gdc.test/fail_compilation/scope_class.d
index bba14908833..b5e1a54d71b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/scope_class.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/scope_class.d
@@ -1,12 +1,12 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/scope_class.d(10): Deprecation: `scope` as a type constraint is deprecated.  Use `scope` at the usage site.
 fail_compilation/scope_class.d(12): Error: functions cannot return `scope scope_class.C`
 ---
 */
 
 
+
 scope class C { int i; }    // Notice the use of `scope` here
 
 C increment(C c)
diff --git a/gcc/testsuite/gdc.test/fail_compilation/scope_type.d b/gcc/testsuite/gdc.test/fail_compilation/scope_type.d
deleted file mode 100644
index e0550138b7e..00000000000
--- a/gcc/testsuite/gdc.test/fail_compilation/scope_type.d
+++ /dev/null
@@ -1,16 +0,0 @@ 
-/*
-REQUIRED_ARGS: -de
-TEST_OUTPUT:
----
-fail_compilation/scope_type.d(13): Deprecation: `scope` as a type constraint is deprecated.  Use `scope` at the usage site.
-fail_compilation/scope_type.d(14): Error: `scope` as a type constraint is obsolete.  Use `scope` at the usage site.
-fail_compilation/scope_type.d(15): Deprecation: `scope` as a type constraint is deprecated.  Use `scope` at the usage site.
-fail_compilation/scope_type.d(16): Deprecation: `scope` as a type constraint is deprecated.  Use `scope` at the usage site.
----
-*/
-
-
-scope class C { }
-scope interface I { }
-scope struct S { }
-scope enum E { e }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23279.d b/gcc/testsuite/gdc.test/fail_compilation/test23279.d
new file mode 100644
index 00000000000..43f2d44a071
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test23279.d
@@ -0,0 +1,14 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23279
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test23279.d(13): Error: undefined identifier `Sth`
+---
+*/
+
+class Tester
+{
+    enum a = __traits(hasMember, Tester, "setIt");
+    void setIt(Sth sth){}
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d b/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d
index 404a4c0e3fe..4c8576c88d9 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d
@@ -1,7 +1,6 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/typeerrors.d(32): Deprecation: `scope` as a type constraint is deprecated.  Use `scope` at the usage site.
 fail_compilation/typeerrors.d(37): Error: sequence index `4` out of bounds `[0 .. 4]`
 fail_compilation/typeerrors.d(39): Error: variable `x` cannot be read at compile time
 fail_compilation/typeerrors.d(40): Error: cannot have array of `void()`
@@ -25,6 +24,7 @@  fail_compilation/typeerrors.d(57): Error: slice `[2..1]` is out of range of [0..
 
 
 
+
 template tuple(T...) { alias T tuple; }
 
 void bar();
diff --git a/gcc/testsuite/gdc.test/runnable/betterc.d b/gcc/testsuite/gdc.test/runnable/betterc.d
index 3d8f7da0fcc..0fc32c75a1f 100644
--- a/gcc/testsuite/gdc.test/runnable/betterc.d
+++ b/gcc/testsuite/gdc.test/runnable/betterc.d
@@ -210,3 +210,14 @@  int test20737()
     tlsVar = 123;
     return 0;
 }
+
+/*******************************************/
+// https://issues.dlang.org/show_bug.cgi?id=22427
+void test22427()
+{
+    if("a" == "a")
+        return;
+
+    char[] p;
+    auto a = cast(int[])p;
+}
diff --git a/gcc/testsuite/gdc.test/runnable/sctor2.d b/gcc/testsuite/gdc.test/runnable/sctor2.d
index bd820e498f4..a574c3e55f5 100644
--- a/gcc/testsuite/gdc.test/runnable/sctor2.d
+++ b/gcc/testsuite/gdc.test/runnable/sctor2.d
@@ -1,10 +1,5 @@ 
 // REQUIRED_ARGS: -w -dw
 // PERMUTE_ARGS:
-/* TEST_OUTPUT:
----
-runnable/sctor2.d(12): Deprecation: `scope` as a type constraint is deprecated.  Use `scope` at the usage site.
----
-*/
 
 /***************************************************/
 // 15665
diff --git a/gcc/testsuite/gdc.test/runnable/test24029.c b/gcc/testsuite/gdc.test/runnable/test24029.c
new file mode 100644
index 00000000000..145f2c28725
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test24029.c
@@ -0,0 +1,23 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=24029
+
+int x = 0;
+int y = 0;
+
+void a()
+{
+    (__extension__ ({ x += 2; })); // test.a.__dgliteral1
+}
+
+void b()
+{
+    (__extension__ ({ y += 1; })); // test.b.__dgliteral1
+}
+
+int main(void)
+{
+    a();
+    b();
+    __check(x == 2);
+    __check(y == 1);
+    return 0;
+}
diff --git a/gcc/testsuite/gdc.test/runnable/testcontracts.d b/gcc/testsuite/gdc.test/runnable/testcontracts.d
index 439040b7b38..63d18fcc627 100644
--- a/gcc/testsuite/gdc.test/runnable/testcontracts.d
+++ b/gcc/testsuite/gdc.test/runnable/testcontracts.d
@@ -1,20 +1,4 @@ 
 /* PERMUTE_ARGS: -inline -g -O
-TEST_OUTPUT:
----
-runnable/testcontracts.d(323): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead.
-runnable/testcontracts.d(324): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead.
-runnable/testcontracts.d(325): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead.
-runnable/testcontracts.d(326): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead.
-runnable/testcontracts.d(328): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead.
-runnable/testcontracts.d(329): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead.
-runnable/testcontracts.d(330): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead.
-runnable/testcontracts.d(331): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead.
-runnable/testcontracts.d(502): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead.
-runnable/testcontracts.d(503): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead.
-runnable/testcontracts.d(504): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead.
-runnable/testcontracts.d(505): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead.
-runnable/testcontracts.d(505): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead.
----
 */
 extern(C) int printf(const char*, ...);
 
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 308d51b55d0..a02a8cbaba5 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@ 
-a88e1335f7ea767ef438c34998f5d1f26008c586
+26f049fb26e755096dea3f1474decea7c0fef187
 
 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/int128.d b/libphobos/libdruntime/core/int128.d
index 20fa7dea170..4c88f15abfb 100644
--- a/libphobos/libdruntime/core/int128.d
+++ b/libphobos/libdruntime/core/int128.d
@@ -14,8 +14,8 @@  nothrow:
 @safe:
 @nogc:
 
-alias I = long;
-alias U = ulong;
+private alias I = long;
+private alias U = ulong;
 enum Ubits = uint(U.sizeof * 8);
 
 version (DigitalMars)
@@ -36,6 +36,10 @@  else
     else             private enum Cent_alignment = (size_t.sizeof * 2);
 }
 
+/**
+ * 128 bit integer type.
+ * See_also: $(REF Int128, std,int128).
+ */
 align(Cent_alignment) struct Cent
 {
     version (LittleEndian)
diff --git a/libphobos/libdruntime/core/internal/array/comparison.d b/libphobos/libdruntime/core/internal/array/comparison.d
index 821f96e25c0..94fa2433da8 100644
--- a/libphobos/libdruntime/core/internal/array/comparison.d
+++ b/libphobos/libdruntime/core/internal/array/comparison.d
@@ -83,7 +83,7 @@  int __cmp(T)(scope const T[] lhs, scope const T[] rhs) @trusted
 // This function is called by the compiler when dealing with array
 // comparisons in the semantic analysis phase of CmpExp. The ordering
 // comparison is lowered to a call to this template.
-int __cmp(T1, T2)(T1[] s1, T2[] s2)
+auto __cmp(T1, T2)(T1[] s1, T2[] s2)
 if (!__traits(isScalar, T1) && !__traits(isScalar, T2))
 {
     import core.internal.traits : Unqual;
@@ -237,3 +237,26 @@  if (!__traits(isScalar, T1) && !__traits(isScalar, T2))
     auto vb = [cast(void[])b[0], b[1]];
     assert(less2(va, vb));
 }
+
+// custom aggregate types
+@safe unittest
+{
+    // https://issues.dlang.org/show_bug.cgi?id=24044
+    // Support float opCmp(...) with array
+    static struct F
+    {
+        float f;
+        float opCmp(F other) const { return this.f - other.f; }
+    }
+
+    F[2] a = [F(1.0f), F(float.nan)];
+    F[2] b = [F(1.0f), F(1.0f)];
+    F[1] c = [F(1.0f)];
+
+    bool isNan(float f) { return f != f; }
+
+    assert(isNan(__cmp(a, b)));
+    assert(isNan(__cmp(a, a)));
+    assert(__cmp(b, b) == 0);
+    assert(__cmp(a, c) > 0);
+}
diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d
index 89236dbf4c1..3a55ca916c2 100644
--- a/libphobos/libdruntime/core/lifetime.d
+++ b/libphobos/libdruntime/core/lifetime.d
@@ -1570,7 +1570,11 @@  template forward(args...)
             alias fwd = arg;
         // (r)value
         else
-            @property auto fwd(){ pragma(inline, true); return move(arg); }
+            @property auto fwd()
+            {
+                version (DigitalMars) { /* @@BUG 23890@@ */ } else pragma(inline, true);
+                return move(arg);
+            }
     }
 
     alias Result = AliasSeq!();
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index e0011d7e7f7..a5414f16cd3 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@ 
-1921d29df25f2b44d6014c224e2018ce63ac2b71
+330d6a4fdbe82683e081959d0aeb53597b025bc4
 
 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/algorithm/searching.d b/libphobos/src/std/algorithm/searching.d
index f061915d582..37a08de7a8f 100644
--- a/libphobos/src/std/algorithm/searching.d
+++ b/libphobos/src/std/algorithm/searching.d
@@ -1528,6 +1528,23 @@  if (isInputRange!Range && !isInfinite!Range &&
     assert([S(5), S(6)].extremum!"a.value" == S(5));
 }
 
+// https://issues.dlang.org/show_bug.cgi?id=24027
+@safe nothrow unittest
+{
+    class A
+    {
+        int a;
+        this(int a)
+        {
+            this.a = a;
+        }
+    }
+
+    auto test = new A(5);
+    A[] arr = [test];
+    assert(maxElement!"a.a"(arr) is test);
+}
+
 // find
 /**
 Finds an individual element in an $(REF_ALTTEXT input range, isInputRange, std,range,primitives).
diff --git a/libphobos/src/std/bigint.d b/libphobos/src/std/bigint.d
index 50f88da6055..0240ea1d179 100644
--- a/libphobos/src/std/bigint.d
+++ b/libphobos/src/std/bigint.d
@@ -323,7 +323,15 @@  public:
         else static if (op=="^^")
         {
             sign = (y & 1) ? sign : false;
-            data = BigUint.pow(data, u);
+            if (y < 0)
+            {
+                checkDivByZero();
+                data = cast(ulong) (data == 1);
+            }
+            else
+            {
+                data = BigUint.pow(data, u);
+            }
         }
         else static if (op=="&")
         {
@@ -411,6 +419,19 @@  public:
         ));
     }
 
+    // https://issues.dlang.org/show_bug.cgi?id=24028
+    @system unittest
+    {
+        import std.exception : assertThrown;
+        import core.exception : AssertError;
+
+        assert(BigInt(100) ^^ -1 == BigInt(0));
+        assert(BigInt(1) ^^ -1 == BigInt(1));
+        assert(BigInt(-1) ^^ -1 == BigInt(-1));
+        assert(BigInt(-1) ^^ -2 == BigInt(1));
+        assertThrown!AssertError(BigInt(0) ^^ -1);
+    }
+
     /**
      * Implements assignment operators of the form `BigInt op= BigInt`.
      */
diff --git a/libphobos/src/std/json.d b/libphobos/src/std/json.d
index 219af714373..7d48890501f 100644
--- a/libphobos/src/std/json.d
+++ b/libphobos/src/std/json.d
@@ -6,6 +6,10 @@  Implements functionality to read and write JavaScript Object Notation values.
 JavaScript Object Notation is a lightweight data interchange format commonly used in web services and configuration files.
 It's easy for humans to read and write, and it's easy for machines to parse and generate.
 
+$(RED Warning: While $(LREF JSONValue) is fine for small-scale use, at the range of hundreds of megabytes it is
+known to cause and exacerbate GC problems. If you encounter problems, try replacing it with a stream parser. See
+also $(LINK https://forum.dlang.org/post/dzfyaxypmkdrpakmycjv@forum.dlang.org).)
+
 Copyright: Copyright Jeremie Pelletier 2008 - 2009.
 License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
 Authors:   Jeremie Pelletier, David Herberth
diff --git a/libphobos/src/std/math/package.d b/libphobos/src/std/math/package.d
index 19982ec216a..b5f914acf7c 100644
--- a/libphobos/src/std/math/package.d
+++ b/libphobos/src/std/math/package.d
@@ -168,12 +168,6 @@  public import std.math.rounding;
 public import std.math.traits;
 public import std.math.trigonometry;
 
-// @@@DEPRECATED_2.102@@@
-// Note: Exposed accidentally, should be deprecated / removed
-deprecated("std.meta.AliasSeq was unintentionally available from std.math "
-           ~ "and will be removed after 2.102. Please import std.meta instead")
-public import std.meta : AliasSeq;
-
 package(std): // Not public yet
 /* Return the value that lies halfway between x and y on the IEEE number line.
  *
diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d
index 19ce9880b89..d9291b11bde 100644
--- a/libphobos/src/std/stdio.d
+++ b/libphobos/src/std/stdio.d
@@ -425,21 +425,6 @@  private extern (C) @nogc nothrow
         pragma(mangle, _FPUTWC.mangleof) int trustedFPUTWC(wchar_t ch, _iobuf* h) @trusted;
 }
 
-static if (__traits(compiles, core.sys.posix.stdio.getdelim))
-{
-    extern(C) nothrow @nogc
-    {
-        // @@@DEPRECATED_2.104@@@
-        deprecated("To be removed after 2.104. Use core.sys.posix.stdio.getdelim instead.")
-        ptrdiff_t getdelim(char**, size_t*, int, FILE*);
-
-        // @@@DEPRECATED_2.104@@@
-        // getline() always comes together with getdelim()
-        deprecated("To be removed after 2.104. Use core.sys.posix.stdio.getline instead.")
-        ptrdiff_t getline(char**, size_t*, FILE*);
-    }
-}
-
 //------------------------------------------------------------------------------
 private struct ByRecordImpl(Fields...)
 {