diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in
index 4fbf2096416..264ae03a89e 100644
--- a/gcc/d/Make-lang.in
+++ b/gcc/d/Make-lang.in
@@ -81,7 +81,6 @@ D_FRONTEND_OBJS = \
 	d/access.o \
 	d/aggregate.o \
 	d/aliasthis.o \
-	d/apply.o \
 	d/arrayop.o \
 	d/arraytypes.o \
 	d/attrib.o \
@@ -160,6 +159,7 @@ D_FRONTEND_OBJS = \
 	d/parse.o \
 	d/parsetimevisitor.o \
 	d/permissivevisitor.o \
+	d/postordervisitor.o \
 	d/printast.o \
 	d/root-aav.o \
 	d/root-array.o \
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 689d1c5a0d4..2738958fde1 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -50,11 +50,11 @@ make_location_t (const Loc &loc)
 {
   location_t gcc_location = input_location;
 
-  if (loc.filename)
+  if (const char *filename = loc.filename ())
     {
-      linemap_add (line_table, LC_ENTER, 0, loc.filename, loc.linnum);
-      linemap_line_start (line_table, loc.linnum, 0);
-      gcc_location = linemap_position_for_column (line_table, loc.charnum);
+      linemap_add (line_table, LC_ENTER, 0, filename, loc.linnum ());
+      linemap_line_start (line_table, loc.linnum (), 0);
+      gcc_location = linemap_position_for_column (line_table, loc.charnum ());
       linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
     }
 
@@ -1872,8 +1872,10 @@ void_okay_p (tree t)
 static tree
 build_filename_from_loc (const Loc &loc)
 {
-  const char *filename = loc.filename
-    ? loc.filename : d_function_chain->module->srcfile.toChars ();
+  const char *filename = loc.filename ();
+
+  if (filename == NULL)
+    filename = d_function_chain->module->srcfile.toChars ();
 
   unsigned length = strlen (filename);
   tree str = build_string (length, filename);
@@ -1890,17 +1892,17 @@ tree
 build_assert_call (const Loc &loc, libcall_fn libcall, tree msg)
 {
   tree file;
-  tree line = size_int (loc.linnum);
+  tree line = size_int (loc.linnum ());
 
   switch (libcall)
     {
     case LIBCALL_ASSERT_MSG:
     case LIBCALL_UNITTEST_MSG:
       /* File location is passed as a D string.  */
-      if (loc.filename)
+      if (const char *filename = loc.filename ())
 	{
-	  unsigned len = strlen (loc.filename);
-	  tree str = build_string (len, loc.filename);
+	  unsigned len = strlen (filename);
+	  tree str = build_string (len, filename);
 	  TREE_TYPE (str) = make_array_type (Type::tchar, len);
 
 	  file = d_array_value (build_ctype (Type::tchar->arrayOf ()),
@@ -1939,7 +1941,7 @@ build_array_bounds_call (const Loc &loc)
     {
       return build_libcall (LIBCALL_ARRAYBOUNDSP, Type::tvoid, 2,
 			    build_filename_from_loc (loc),
-			    size_int (loc.linnum));
+			    size_int (loc.linnum ()));
     }
 }
 
@@ -1968,7 +1970,8 @@ build_bounds_index_condition (IndexExp *ie, tree index, tree length)
     {
       boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, Type::tvoid, 4,
 				 build_filename_from_loc (ie->e2->loc),
-				 size_int (ie->e2->loc.linnum), index, length);
+				 size_int (ie->e2->loc.linnum ()),
+				 index, length);
     }
 
   return build_condition (TREE_TYPE (index), condition, boundserr, index);
@@ -2017,7 +2020,7 @@ build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length)
 	      boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP,
 					 Type::tvoid, 5,
 					 build_filename_from_loc (se->loc),
-					 size_int (se->loc.linnum),
+					 size_int (se->loc.linnum ()),
 					 lower, upper, length);
 	    }
 
@@ -2659,8 +2662,8 @@ build_frame_type (tree ffi, FuncDeclaration *fd)
      of the calling function non-locally.  So we add all parameters with nested
      refs to the function frame, this should also mean overriding methods will
      have the same frame layout when inheriting a contract.  */
-  if ((global.params.useIn == CHECKENABLEon && fd->frequire)
-      || (global.params.useOut == CHECKENABLEon && fd->fensure))
+  if ((global.params.useIn == CHECKENABLEon && fd->frequire ())
+      || (global.params.useOut == CHECKENABLEon && fd->fensure ()))
     {
       if (fd->parameters)
 	{
@@ -2870,8 +2873,8 @@ get_frameinfo (FuncDeclaration *fd)
 
       /* In checkNestedReference, references from contracts are not added to the
 	 closureVars array, so assume all parameters referenced.  */
-      if ((global.params.useIn == CHECKENABLEon && fd->frequire)
-	  || (global.params.useOut == CHECKENABLEon && fd->fensure))
+      if ((global.params.useIn == CHECKENABLEon && fd->frequire ())
+	  || (global.params.useOut == CHECKENABLEon && fd->fensure ()))
 	FRAMEINFO_CREATES_FRAME (ffi) = 1;
 
       /* If however `fd` is nested (deeply) in a function that creates a
diff --git a/gcc/d/d-diagnostic.cc b/gcc/d/d-diagnostic.cc
index c3bde4651bf..7e5b17c46e5 100644
--- a/gcc/d/d-diagnostic.cc
+++ b/gcc/d/d-diagnostic.cc
@@ -189,7 +189,7 @@ d_diagnostic_report_diagnostic (const Loc &loc, int opt, const char *format,
   va_list argp;
   va_copy (argp, ap);
 
-  if (loc.filename || !verbatim)
+  if (loc.filename () || !verbatim)
     {
       rich_location rich_loc (line_table, make_location_t (loc));
       diagnostic_info diagnostic;
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index 0375ede082b..b866593880d 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -1083,7 +1083,7 @@ build_decl_tree (Dsymbol *d)
   location_t saved_location = input_location;
 
   /* Set input location, empty DECL_SOURCE_FILE can crash debug generator.  */
-  if (d->loc.filename)
+  if (d->loc.filename ())
     input_location = make_location_t (d->loc);
   else
     input_location = make_location_t (Loc ("<no_file>", 1, 0));
@@ -2064,7 +2064,7 @@ start_function (FuncDeclaration *fd)
   allocate_struct_function (fndecl, false);
 
   /* Store the end of the function.  */
-  if (fd->endloc.filename)
+  if (fd->endloc.filename ())
     cfun->function_end_locus = make_location_t (fd->endloc);
   else
     cfun->function_end_locus = DECL_SOURCE_LOCATION (fndecl);
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 95ea67d789b..1cff48a7b2a 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-28a3b24c2e45de39cd3df528142fd06b6456e8fd
+17ccd12af386543c0b9935bf7e0a8e701b903105
 
 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/README.md b/gcc/d/dmd/README.md
index 57f56f3f0f0..79215b7a0ea 100644
--- a/gcc/d/dmd/README.md
+++ b/gcc/d/dmd/README.md
@@ -99,7 +99,7 @@
 | [strictvisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/strictvisitor.d)                       | Visitor that forces derived classes to implement `visit` for every possible node |
 | [visitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/visitor.d)                                   | A visitor implementing `visit` for all nodes present in the compiler             |
 | [transitivevisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/transitivevisitor.d)               | Provide a mixin template with visit methods for the parse time AST               |
-| [apply.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/apply.d)                                       | Depth-first expression visitor                                                   |
+| [postordervisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/postordervisitor.d)                                       | Depth-first expression visitor                                                   |
 | [sapply.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/sapply.d)                                     | Depth-first statement visitor                                                    |
 | [statement_rewrite_walker.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/statement_rewrite_walker.d) | Statement visitor that allows replacing the currently visited node               |
 
diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION
index 7cf912726b7..d5aee89f2cb 100644
--- a/gcc/d/dmd/VERSION
+++ b/gcc/d/dmd/VERSION
@@ -1 +1 @@
-v2.104.0-beta.1
+v2.104.0
diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d
index 1306a104fff..42b926be453 100644
--- a/gcc/d/dmd/aggregate.d
+++ b/gcc/d/dmd/aggregate.d
@@ -18,7 +18,6 @@ import core.stdc.stdio;
 import core.checkedint;
 
 import dmd.aliasthis;
-import dmd.apply;
 import dmd.arraytypes;
 import dmd.astenums;
 import dmd.attrib;
@@ -764,21 +763,18 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
         if (s)
         {
             // Finish all constructors semantics to determine this.noDefaultCtor.
-            struct SearchCtor
+            static int searchCtor(Dsymbol s, void*)
             {
-                extern (C++) static int fp(Dsymbol s, void* ctxt)
-                {
-                    auto f = s.isCtorDeclaration();
-                    if (f && f.semanticRun == PASS.initial)
-                        f.dsymbolSemantic(null);
-                    return 0;
-                }
+                auto f = s.isCtorDeclaration();
+                if (f && f.semanticRun == PASS.initial)
+                    f.dsymbolSemantic(null);
+                return 0;
             }
 
             for (size_t i = 0; i < members.length; i++)
             {
                 auto sm = (*members)[i];
-                sm.apply(&SearchCtor.fp, null);
+                sm.apply(&searchCtor, null);
             }
         }
         return s;
@@ -814,3 +810,36 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
         v.visit(this);
     }
 }
+
+/*********************************
+ * Iterate this dsymbol or members of this scoped dsymbol, then
+ * call `fp` with the found symbol and `params`.
+ * Params:
+ *  symbol = the dsymbol or parent of members to call fp on
+ *  fp = function pointer to process the iterated symbol.
+ *       If it returns nonzero, the iteration will be aborted.
+ *  ctx = context parameter passed to fp.
+ * Returns:
+ *  nonzero if the iteration is aborted by the return value of fp,
+ *  or 0 if it's completed.
+ */
+int apply(Dsymbol symbol, int function(Dsymbol, void*) fp, void* ctx)
+{
+    if (auto nd = symbol.isNspace())
+    {
+        return nd.members.foreachDsymbol( (s) { return s && s.apply(fp, ctx); } );
+    }
+    if (auto ad = symbol.isAttribDeclaration())
+    {
+        return ad.include(ad._scope).foreachDsymbol( (s) { return s && s.apply(fp, ctx); } );
+    }
+    if (auto tm = symbol.isTemplateMixin())
+    {
+        if (tm._scope) // if fwd reference
+            dsymbolSemantic(tm, null); // try to resolve it
+
+        return tm.members.foreachDsymbol( (s) { return s && s.apply(fp, ctx); } );
+    }
+
+    return fp(symbol, ctx);
+}
diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d
index 7dfec8a043a..09d39ca6f1c 100644
--- a/gcc/d/dmd/canthrow.d
+++ b/gcc/d/dmd/canthrow.d
@@ -14,7 +14,6 @@
 module dmd.canthrow;
 
 import dmd.aggregate;
-import dmd.apply;
 import dmd.arraytypes;
 import dmd.attrib;
 import dmd.astenums;
@@ -26,6 +25,7 @@ import dmd.func;
 import dmd.globals;
 import dmd.init;
 import dmd.mtype;
+import dmd.postordervisitor;
 import dmd.root.rootobject;
 import dmd.tokens;
 import dmd.visitor;
@@ -133,16 +133,9 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN
              */
             if (ce.f && ce.f == func)
                 return;
-            Type t = ce.e1.type.toBasetype();
-            auto tf = t.isTypeFunction();
+            const tf = ce.calledFunctionType();
             if (tf && tf.isnothrow)
                 return;
-            else
-            {
-                auto td = t.isTypeDelegate();
-                if (td && td.nextOf().isTypeFunction().isnothrow)
-                    return;
-            }
 
             if (ce.f)
                 checkFuncThrows(ce, ce.f);
diff --git a/gcc/d/dmd/chkformat.d b/gcc/d/dmd/chkformat.d
index 21a1b5e6def..feaa3c7ee6b 100644
--- a/gcc/d/dmd/chkformat.d
+++ b/gcc/d/dmd/chkformat.d
@@ -177,6 +177,8 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
                         errorMsg(null, e, (c_longsize == 4 ? "uint" : "ulong"), t);
                     else
                         errorMsg(null, e, (c_longsize == 4 ? "int" : "long"), t);
+                    if (t.isintegral() && t.size() != c_longsize)
+                        errorSupplemental(e.loc, "C `long` is %d bytes on your system", c_longsize);
                 }
                 break;
 
diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d
index 60e373c502b..3586f20ddbe 100644
--- a/gcc/d/dmd/clone.d
+++ b/gcc/d/dmd/clone.d
@@ -106,18 +106,18 @@ FuncDeclaration hasIdentityOpAssign(AggregateDeclaration ad, Scope* sc)
         scope er = new NullExp(ad.loc, ad.type);    // dummy rvalue
         scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue
         el.type = ad.type;
-        auto a = Expressions(1);
+        auto a = new Expressions(1);
         const errors = global.startGagging(); // Do not report errors, even if the template opAssign fbody makes it.
         sc = sc.push();
         sc.tinst = null;
         sc.minst = null;
 
-        a[0] = er;
-        auto f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(&a), FuncResolveFlag.quiet);
+        (*a)[0] = er;
+        auto f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(a), FuncResolveFlag.quiet);
         if (!f)
         {
-            a[0] = el;
-            f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(&a), FuncResolveFlag.quiet);
+            (*a)[0] = el;
+            f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(a), FuncResolveFlag.quiet);
         }
 
         sc = sc.pop();
@@ -465,7 +465,7 @@ private FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc)
          */
         scope er = new NullExp(ad.loc, null); // dummy rvalue
         scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue
-        auto a = Expressions(1);
+        auto a = new Expressions(1);
 
         bool hasIt(Type tthis)
         {
@@ -476,9 +476,9 @@ private FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc)
 
             FuncDeclaration rfc(Expression e)
             {
-                a[0] = e;
-                a[0].type = tthis;
-                return resolveFuncCall(ad.loc, sc, eq, null, tthis, ArgumentList(&a), FuncResolveFlag.quiet);
+                (*a)[0] = e;
+                (*a)[0].type = tthis;
+                return resolveFuncCall(ad.loc, sc, eq, null, tthis, ArgumentList(a), FuncResolveFlag.quiet);
             }
 
             f = rfc(er);
diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d
index c40936c78d1..fcb50e0a648 100644
--- a/gcc/d/dmd/cond.d
+++ b/gcc/d/dmd/cond.d
@@ -259,7 +259,7 @@ extern (C++) final class StaticForeach : RootObject
         auto sdecl = new StructDeclaration(loc, sid, false);
         sdecl.storage_class |= STC.static_;
         sdecl.members = new Dsymbols();
-        auto fid = Identifier.idPool(tupleFieldName.ptr, tupleFieldName.length);
+        auto fid = Identifier.idPool(tupleFieldName);
         auto ty = new TypeTypeof(loc, new TupleExp(loc, e));
         sdecl.members.push(new VarDeclaration(loc, ty, fid, null, 0));
         auto r = cast(TypeStruct)sdecl.type;
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index 9b7db1f33f4..33669e38c41 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -324,6 +324,8 @@ final class CParser(AST) : Parser!AST
         // atomic-type-specifier or type_qualifier
         case TOK._Atomic:
 
+        case TOK.__attribute__:
+
         Ldeclaration:
         {
             cparseDeclaration(LVL.local);
@@ -2356,6 +2358,8 @@ final class CParser(AST) : Parser!AST
                             cparseGnuAttributes(tagSpecifier);
                         else if (token.value == TOK.__declspec)
                             cparseDeclspec(tagSpecifier);
+                        else if (token.value == TOK.__pragma)
+                            uupragmaDirective(sloc);
                         else
                             break;
                     }
@@ -2710,7 +2714,7 @@ final class CParser(AST) : Parser!AST
      *
      * Params:
      *  declarator   = declarator kind
-     *  t            = base type to start with
+     *  tbase        = base type to start with
      *  pident       = set to Identifier if there is one, null if not
      *  specifier    = specifiers in and out
      * Returns:
@@ -2718,12 +2722,26 @@ final class CParser(AST) : Parser!AST
      *  symbol table for the parameter-type-list, which will contain any
      *  declared struct, union or enum tags.
      */
-    private AST.Type cparseDeclarator(DTR declarator, AST.Type t,
+    private AST.Type cparseDeclarator(DTR declarator, AST.Type tbase,
         out Identifier pident, ref Specifier specifier)
     {
         //printf("cparseDeclarator(%d, %p)\n", declarator, t);
         AST.Types constTypes; // all the Types that will need `const` applied to them
 
+        /* Insert tx -> t into
+         *   ts -> ... -> t
+         * so that
+         *   ts -> ... -> tx -> t
+         */
+        static void insertTx(ref AST.Type ts, AST.Type tx, AST.Type t)
+        {
+            AST.Type* pt;
+            for (pt = &ts; *pt != t; pt = &(cast(AST.TypeNext)*pt).next)
+            {
+            }
+            *pt = tx;
+        }
+
         AST.Type parseDecl(AST.Type t)
         {
             AST.Type ts;
@@ -2789,20 +2807,6 @@ final class CParser(AST) : Parser!AST
             // parse DeclaratorSuffixes
             while (1)
             {
-                /* Insert tx -> t into
-                 *   ts -> ... -> t
-                 * so that
-                 *   ts -> ... -> tx -> t
-                 */
-                static void insertTx(ref AST.Type ts, AST.Type tx, AST.Type t)
-                {
-                    AST.Type* pt;
-                    for (pt = &ts; *pt != t; pt = &(cast(AST.TypeNext)*pt).next)
-                    {
-                    }
-                    *pt = tx;
-                }
-
                 switch (token.value)
                 {
                     case TOK.leftBracket:
@@ -2915,7 +2919,17 @@ final class CParser(AST) : Parser!AST
             return ts;
         }
 
-        t = parseDecl(t);
+        auto t = parseDecl(tbase);
+
+        if (specifier.vector_size)
+        {
+            auto length = new AST.IntegerExp(token.loc, specifier.vector_size / tbase.size(), AST.Type.tuns32);
+            auto tsa = new AST.TypeSArray(tbase, length);
+            AST.Type tv = new AST.TypeVector(tsa);
+            specifier.vector_size = 0;          // used it up
+
+            insertTx(t, tv, tbase);     // replace tbase with tv
+        }
 
         /* Because const is transitive, cannot assemble types from
          * fragments. Instead, types to be annotated with const are put
@@ -3553,7 +3567,19 @@ final class CParser(AST) : Parser!AST
             {
                 nextToken();
                 check(TOK.leftParenthesis);
-                cparseConstantExp();  // TODO implement
+                if (token.value == TOK.int32Literal)
+                {
+                    const n = token.unsvalue;
+                    if (n < 1 || n & (n - 1) || ushort.max < n)
+                        error("__attribute__((vector_size(%lld))) must be an integer positive power of 2 and be <= 32,768", cast(ulong)n);
+                    specifier.vector_size = cast(uint) n;
+                    nextToken();
+                }
+                else
+                {
+                    error("value for vector_size expected, not `%s`", token.toChars());
+                    nextToken();
+                }
                 check(TOK.rightParenthesis);
             }
             else
@@ -3852,6 +3878,10 @@ final class CParser(AST) : Parser!AST
         else if (!tag)
             error("missing tag `identifier` after `%s`", Token.toChars(structOrUnion));
 
+        // many ways and places to declare alignment
+        if (packalign.isUnknown() && !this.packalign.isUnknown())
+            packalign.set(this.packalign.get());
+
         /* Need semantic information to determine if this is a declaration,
          * redeclaration, or reference to existing declaration.
          * Defer to the semantic() pass with a TypeTag.
@@ -4694,6 +4724,7 @@ final class CParser(AST) : Parser!AST
                 // atomic-type-specifier
                 case TOK._Atomic:
                 case TOK.typeof_:
+                case TOK.__attribute__:
                     t = peek(t);
                     if (t.value != TOK.leftParenthesis ||
                         !skipParens(t, &t))
@@ -4959,6 +4990,7 @@ final class CParser(AST) : Parser!AST
         bool dllexport; /// dllexport attribute
         bool _deprecated;       /// deprecated attribute
         AST.Expression depMsg;  /// deprecated message
+        uint vector_size;       /// positive power of 2 multipe of base type size
 
         SCW scw;        /// storage-class specifiers
         MOD mod;        /// type qualifiers
@@ -5400,6 +5432,24 @@ final class CParser(AST) : Parser!AST
                 pragmaDirective(scanloc);
                 return true;
             }
+            else if (n.ident == Id.ident) // #ident "string"
+            {
+                scan(&n);
+                if (n.value == TOK.string_ && n.ptr[0] == '"' && n.postfix == 0)
+                {
+                    /* gcc inserts string into the .comment section in the object file.
+                     * Just ignore it for now, but can support it later by writing
+                     * the string to obj_exestr()
+                     */
+                    //auto comment = n.ustring;
+
+                    scan(&n);
+                    if (n.value == TOK.endOfFile || n.value == TOK.endOfLine)
+                        return true;
+                }
+                error("\"string\" expected after `#ident`");
+                return false;
+            }
         }
         if (n.ident != Id.undef)
             error("C preprocessor directive `#%s` is not supported", n.toChars());
@@ -5416,20 +5466,39 @@ final class CParser(AST) : Parser!AST
     private void uupragmaDirective(const ref Loc startloc)
     {
         const loc = startloc;
-        nextToken();
+        nextToken();    // move past __pragma
         if (token.value != TOK.leftParenthesis)
         {
-            error(loc, "left parenthesis expected to follow `__pragma`");
+            error(loc, "left parenthesis expected to follow `__pragma` instead of `%s`", token.toChars());
+            nextToken();
             return;
         }
         nextToken();
-        if (token.value == TOK.identifier && token.ident == Id.pack)
-            pragmaPack(startloc, false);
+
+        if (token.value == TOK.identifier)
+        {
+            if (token.ident == Id.pack)
+                pragmaPack(startloc, false);
+            else
+            {
+                nextToken();
+                if (token.value == TOK.leftParenthesis)
+                    cparseParens();
+            }
+
+        }
+        else if (token.value == TOK.endOfFile)
+        {
+        }
+        else if (token.value == TOK.rightParenthesis)
+        {
+        }
         else
-            error(loc, "unrecognized __pragma");
+            error(loc, "unrecognized `__pragma(%s)`", token.toChars());
+
         if (token.value != TOK.rightParenthesis)
         {
-            error(loc, "right parenthesis expected to close `__pragma(...)`");
+            error(loc, "right parenthesis expected to close `__pragma(...)` instead of `%s`", token.toChars());
             return;
         }
         nextToken();
diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d
index 40092c3f584..ee1340d6342 100644
--- a/gcc/d/dmd/cppmangle.d
+++ b/gcc/d/dmd/cppmangle.d
@@ -446,7 +446,15 @@ private final class CppMangleVisitor : Visitor
                 if (this.context.res.dyncast() == DYNCAST.dsymbol)
                     parentti = this.context.res.asFuncDecl().parent.isTemplateInstance();
                 else
-                    parentti = this.context.res.asType().toDsymbol(null).parent.isTemplateInstance();
+                {
+                    auto parent = this.context.res.asType().toDsymbol(null).parent;
+                    parentti = parent.isTemplateInstance();
+                    // https://issues.dlang.org/show_bug.cgi?id=22760
+                    // The template instance may sometimes have the form
+                    // S1!int.S1, therefore the above instruction might yield null
+                    if (parentti is null && parent.parent)
+                        parentti = parent.parent.isTemplateInstance();
+                }
                 return (*parentti.tiargs)[arg];
             }());
         scope (exit) this.context.pop(prev);
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index 8ffbef3c966..6fcc2806585 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -71,6 +71,8 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
 
         if (const match = (sc && sc.flags & SCOPE.Cfile) ? e.cimplicitConvTo(t) : e.implicitConvTo(t))
         {
+            // no need for an extra cast when matching is exact
+
             if (match == MATCH.convert && e.type.isTypeNoreturn())
             {
                 return specialNoreturnCast(e, t);
@@ -88,6 +90,8 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
             auto ad = isAggregate(e.type);
             if (ad && ad.aliasthis)
             {
+                if (!ad.type || ad.type.isTypeError())
+                    return e;
                 auto ts = ad.type.isTypeStruct();
                 const adMatch = ts
                     ? ts.implicitConvToWithoutAliasThis(t)
diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d
index e4585934089..1b8e8ef1880 100644
--- a/gcc/d/dmd/dclass.d
+++ b/gcc/d/dmd/dclass.d
@@ -17,7 +17,6 @@ import core.stdc.stdio;
 import core.stdc.string;
 
 import dmd.aggregate;
-import dmd.apply;
 import dmd.arraytypes;
 import dmd.astenums;
 import dmd.attrib;
@@ -867,7 +866,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
          * Resolve forward references to all class member functions,
          * and determine whether this class is abstract.
          */
-        static int func(Dsymbol s)
+        static int func(Dsymbol s, void*)
         {
             auto fd = s.isFuncDeclaration();
             if (!fd)
@@ -883,7 +882,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
         for (size_t i = 0; i < members.length; i++)
         {
             auto s = (*members)[i];
-            if (s.apply(&func))
+            if (s.apply(&func, null))
             {
                 return yes();
             }
@@ -910,7 +909,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
              * each of the virtual functions,
              * which will fill in the vtbl[] overrides.
              */
-            static int virtualSemantic(Dsymbol s)
+            static int virtualSemantic(Dsymbol s, void*)
             {
                 auto fd = s.isFuncDeclaration();
                 if (fd && !(fd.storage_class & STC.static_) && !fd.isUnitTestDeclaration())
@@ -921,7 +920,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
             for (size_t i = 0; i < members.length; i++)
             {
                 auto s = (*members)[i];
-                s.apply(&virtualSemantic);
+                s.apply(&virtualSemantic,null);
             }
         }
 
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index 0e5df5eb550..cfa6988a861 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -44,6 +44,10 @@ import dmd.tokens;
 import dmd.typesem;
 import dmd.visitor;
 
+version (IN_GCC) {}
+else version (IN_LLVM) {}
+else version = MARS;
+
 /************************************
  * Check to see the aggregate type is nested and its context pointer is
  * accessible from the current scope.
@@ -633,9 +637,7 @@ extern (C++) final class TupleDeclaration : Declaration
                 version (none)
                 {
                     buf.printf("_%s_%d", ident.toChars(), i);
-                    const len = buf.offset;
-                    const name = buf.extractSlice().ptr;
-                    auto id = Identifier.idPool(name, len);
+                    auto id = Identifier.idPool(buf.extractSlice());
                     auto arg = new Parameter(STC.in_, t, id, null);
                 }
                 else
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index 7a69382e6ba..197091e1d89 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -534,22 +534,19 @@ enum class BUILTIN : unsigned char
 Expression *eval_builtin(const Loc &loc, FuncDeclaration *fd, Expressions *arguments);
 BUILTIN isBuiltin(FuncDeclaration *fd);
 
+struct ContractInfo;
+
 class FuncDeclaration : public Declaration
 {
 public:
-    Statements *frequires;              // in contracts
-    Ensures *fensures;                  // out contracts
-    Statement *frequire;                // lowered in contract
-    Statement *fensure;                 // lowered out contract
     Statement *fbody;
 
     FuncDeclarations foverrides;        // functions this function overrides
-    FuncDeclaration *fdrequire;         // function that does the in contract
-    FuncDeclaration *fdensure;          // function that does the out contract
 
-    Expressions *fdrequireParams;       // argument list for __require
-    Expressions *fdensureParams;        // argument list for __ensure
+private:
+    ContractInfo *contracts;            // contract information
 
+public:
     const char *mangleString;           // mangled symbol created from mangleExact()
 
     VarDeclaration *vresult;            // result variable for out contracts
@@ -686,6 +683,22 @@ public:
 
     static FuncDeclaration *create(const Loc &loc, const Loc &endloc, Identifier *id, StorageClass storage_class, Type *type, bool noreturn = false);
     FuncDeclaration *syntaxCopy(Dsymbol *) override;
+    Statements *frequires();
+    Ensures *fensures();
+    Statement *frequire();
+    Statement *fensure();
+    FuncDeclaration *fdrequire();
+    FuncDeclaration *fdensure();
+    Expressions *fdrequireParams();
+    Expressions *fdensureParams();
+    Statements *frequires(Statements *frs);
+    Ensures *fensures(Statements *fes);
+    Statement *frequire(Statement *fr);
+    Statement *fensure(Statement *fe);
+    FuncDeclaration *fdrequire(FuncDeclaration *fdr);
+    FuncDeclaration *fdensure(FuncDeclaration *fde);
+    Expressions *fdrequireParams(Expressions *fdrp);
+    Expressions *fdensureParams(Expressions *fdep);
     bool functionSemantic();
     bool functionSemantic3();
     bool equals(const RootObject * const o) const override final;
diff --git a/gcc/d/dmd/delegatize.d b/gcc/d/dmd/delegatize.d
index fd9569105b5..b135bfacbf9 100644
--- a/gcc/d/dmd/delegatize.d
+++ b/gcc/d/dmd/delegatize.d
@@ -14,7 +14,6 @@
 module dmd.delegatize;
 
 import core.stdc.stdio;
-import dmd.apply;
 import dmd.astenums;
 import dmd.declaration;
 import dmd.dscope;
@@ -27,6 +26,7 @@ import dmd.init;
 import dmd.initsem;
 import dmd.location;
 import dmd.mtype;
+import dmd.postordervisitor;
 import dmd.statement;
 import dmd.tokens;
 import dmd.visitor;
diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d
index 221250b27e0..87b40b854b9 100644
--- a/gcc/d/dmd/denum.d
+++ b/gcc/d/dmd/denum.d
@@ -169,7 +169,12 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
             return defaultval;
         }
         //printf("EnumDeclaration::getDefaultValue() %p %s\n", this, toChars());
-        if (defaultval)
+        // https://issues.dlang.org/show_bug.cgi?id=23904
+        // Return defaultval only if it is not ErrorExp.
+        // A speculative context may set defaultval to ErrorExp;
+        // subsequent non-speculative contexts need to be able
+        // to print the error.
+        if (defaultval && !defaultval.isErrorExp())
             return defaultval;
 
         if (isCsymbol())
diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d
index b653d9bbf89..c4d5ddbc079 100644
--- a/gcc/d/dmd/dimport.d
+++ b/gcc/d/dmd/dimport.d
@@ -26,6 +26,7 @@ import dmd.location;
 import dmd.mtype;
 import dmd.visitor;
 
+import core.stdc.stdio;
 /***********************************************************
  */
 extern (C++) final class Import : Dsymbol
@@ -232,7 +233,20 @@ extern (C++) final class Import : Dsymbol
          * most likely because of parsing errors.
          * Therefore we cannot trust the resulting AST.
          */
-        if (load(sc)) return;
+        if (load(sc))
+        {
+            // https://issues.dlang.org/show_bug.cgi?id=23873
+            // For imports that are not at module or function level,
+            // e.g. aggregate level, the import symbol is added to the
+            // symbol table and later semantic is performed on it.
+            // This leads to semantic analysis on an malformed AST
+            // which causes all kinds of segfaults.
+            // The fix is to note that the module has errors and avoid
+            // semantic analysis on it.
+            if(mod)
+                mod.errors = true;
+            return;
+        }
 
         if (!mod) return; // Failed
 
diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d
index 4ef6a392073..5b27a07339a 100644
--- a/gcc/d/dmd/dinterpret.d
+++ b/gcc/d/dmd/dinterpret.d
@@ -16,7 +16,6 @@ module dmd.dinterpret;
 import core.stdc.stdio;
 import core.stdc.stdlib;
 import core.stdc.string;
-import dmd.apply;
 import dmd.arraytypes;
 import dmd.astenums;
 import dmd.attrib;
diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d
index 7674f775e3e..3e60dc4f9d8 100644
--- a/gcc/d/dmd/doc.d
+++ b/gcc/d/dmd/doc.d
@@ -429,9 +429,9 @@ extern(C++) void gendocfile(Module m)
     if (m.filetype == FileType.ddoc)
     {
         const ploc = m.md ? &m.md.loc : &m.loc;
-        const loc = Loc(ploc.filename ? ploc.filename : srcfilename.ptr,
-                        ploc.linnum,
-                        ploc.charnum);
+        Loc loc = *ploc;
+        if (!loc.filename)
+            loc.filename = srcfilename.ptr;
 
         size_t commentlen = strlen(cast(char*)m.comment);
         Dsymbols a;
@@ -4151,7 +4151,7 @@ private size_t endRowAndTable(ref OutBuffer buf, size_t iStart, size_t iEnd, con
 private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, size_t offset)
 {
     const incrementLoc = loc.linnum == 0 ? 1 : 0;
-    loc.linnum += incrementLoc;
+    loc.linnum = loc.linnum + incrementLoc;
     loc.charnum = 0;
     //printf("highlightText()\n");
     bool leadingBlank = true;
@@ -4256,7 +4256,7 @@ private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, s
             lineQuoted = false;
             tableRowDetected = false;
             iLineStart = i + 1;
-            loc.linnum += incrementLoc;
+            loc.linnum = loc.linnum + incrementLoc;
 
             // update the paragraph start if we just entered a macro
             if (previousMacroLevel < macroLevel && iParagraphStart < iLineStart)
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 506946fe458..a5cd63b1d4f 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -17,7 +17,6 @@ import core.stdc.string;
 
 import dmd.aggregate;
 import dmd.aliasthis;
-import dmd.apply;
 import dmd.arraytypes;
 import dmd.astcodegen;
 import dmd.astenums;
@@ -78,6 +77,10 @@ import dmd.templateparamsem;
 import dmd.typesem;
 import dmd.visitor;
 
+version (IN_GCC) {}
+else version (IN_LLVM) {}
+else version = MARS;
+
 enum LOG = false;
 
 private uint setMangleOverride(Dsymbol s, const(char)[] sym)
@@ -484,7 +487,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
 
             // Infering the type requires running semantic,
             // so mark the scope as ctfe if required
-            bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0;
+            bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0 || !sc.func;
             if (needctfe)
             {
                 sc.flags |= SCOPE.condition;
@@ -1366,9 +1369,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
     {
         static if (LOG)
         {
-            printf("Import::semantic('%s') %s\n", toPrettyChars(), id.toChars());
+            printf("Import::semantic('%s') %s\n", imp.toPrettyChars(), imp.id.toChars());
             scope(exit)
-                printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
+                printf("-Import::semantic('%s'), pkg = %p\n", imp.toChars(), imp.pkg);
         }
         if (imp.semanticRun > PASS.initial)
             return;
@@ -1434,7 +1437,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                 imp.addPackageAccess(scopesym);
             }
 
-            imp.mod.dsymbolSemantic(null);
+            // if a module has errors it means that parsing has failed.
+            if (!imp.mod.errors)
+                imp.mod.dsymbolSemantic(null);
 
             if (imp.mod.needmoduleinfo)
             {
@@ -1463,7 +1468,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
                 else
                 {
                     Dsymbol s = imp.mod.search_correct(imp.names[i]);
-                    if (s)
+                    // https://issues.dlang.org/show_bug.cgi?id=23908
+                    // Don't suggest symbols from the importer's module
+                    if (s && s.parent != importer)
                         imp.mod.error(imp.loc, "import `%s` not found, did you mean %s `%s`?", imp.names[i].toChars(), s.kind(), s.toPrettyChars());
                     else
                         imp.mod.error(imp.loc, "import `%s` not found", imp.names[i].toChars());
@@ -7124,8 +7131,9 @@ bool determineFields(AggregateDeclaration ad)
     // determineFields can be called recursively from one of the fields's v.semantic
     ad.fields.setDim(0);
 
-    static int func(Dsymbol s, AggregateDeclaration ad)
+    static int func(Dsymbol s, void* ctx)
     {
+        auto ad = cast(AggregateDeclaration)ctx;
         auto v = s.isVarDeclaration();
         if (!v)
             return 0;
@@ -7141,7 +7149,7 @@ bool determineFields(AggregateDeclaration ad)
         if (v.aliasTuple)
         {
             // If this variable was really a tuple, process each element.
-            return v.aliasTuple.foreachVar(tv => tv.apply(&func, ad));
+            return v.aliasTuple.foreachVar(tv => tv.apply(&func, cast(void*) ad));
         }
 
         if (v.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.ctfe | STC.templateparameter))
@@ -7173,7 +7181,7 @@ bool determineFields(AggregateDeclaration ad)
         for (size_t i = 0; i < ad.members.length; i++)
         {
             auto s = (*ad.members)[i];
-            if (s.apply(&func, ad))
+            if (s.apply(&func, cast(void *)ad))
             {
                 if (ad.sizeok != Sizeok.none)
                 {
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index ef743d60fd9..5b98d2f4877 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -4141,185 +4141,207 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                     goto Lnomatch;
 
             L2:
-                for (size_t i = 0; 1; i++)
+                if (!resolveTemplateInstantiation(t.tempinst.tiargs, &t.tempinst.tdtypes, tempdecl, tp, dedtypes))
+                    goto Lnomatch;
+            }
+            visit(cast(Type)t);
+            return;
+
+        Lnomatch:
+            //printf("no match\n");
+            result = MATCH.nomatch;
+        }
+
+        /********************
+         * Match template `parameters` to the target template instance.
+         * Example:
+         *    struct Temp(U, int Z) {}
+         *    void foo(T)(Temp!(T, 3));
+         *    foo(Temp!(int, 3)());
+         * Input:
+         *    this.parameters  = template params of foo -> [T]
+         *    tiargs           = <Temp!(int, 3)>.tiargs  -> [int, 3]
+         *    tdtypes          = <Temp!(int, 3)>.tdtypes -> [int, 3]
+         *    tempdecl         = <struct Temp!(T, int Z)> -> [T, Z]
+         *    tp               = <Temp!(T, 3)>
+         * Output:
+         *    dedtypes         = deduced params of `foo(Temp!(int, 3)())` -> [int]
+         */
+        private bool resolveTemplateInstantiation(Objects* tiargs, Objects* tdtypes, TemplateDeclaration tempdecl, TypeInstance tp, Objects* dedtypes)
+        {
+            for (size_t i = 0; 1; i++)
+            {
+                //printf("\ttest: tempinst.tiargs[%zu]\n", i);
+                RootObject o1 = null;
+                if (i < tiargs.length)
+                    o1 = (*tiargs)[i];
+                else if (i < tdtypes.length && i < tp.tempinst.tiargs.length)
                 {
-                    //printf("\ttest: tempinst.tiargs[%zu]\n", i);
-                    RootObject o1 = null;
-                    if (i < t.tempinst.tiargs.length)
-                        o1 = (*t.tempinst.tiargs)[i];
-                    else if (i < t.tempinst.tdtypes.length && i < tp.tempinst.tiargs.length)
-                    {
-                        // Pick up default arg
-                        o1 = t.tempinst.tdtypes[i];
-                    }
-                    else if (i >= tp.tempinst.tiargs.length)
-                        break;
-                    //printf("\ttest: o1 = %s\n", o1.toChars());
-                    if (i >= tp.tempinst.tiargs.length)
+                    // Pick up default arg
+                    o1 = (*tdtypes)[i];
+                }
+                else if (i >= tp.tempinst.tiargs.length)
+                    break;
+                //printf("\ttest: o1 = %s\n", o1.toChars());
+                if (i >= tp.tempinst.tiargs.length)
+                {
+                    size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0);
+                    while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg()))
                     {
-                        size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0);
-                        while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg()))
-                        {
-                            i++;
-                        }
-                        if (i >= dim)
-                            break; // match if all remained parameters are dependent
-                        goto Lnomatch;
+                        i++;
                     }
+                    if (i >= dim)
+                        break; // match if all remained parameters are dependent
+                    return false;
+                }
 
-                    RootObject o2 = (*tp.tempinst.tiargs)[i];
-                    Type t2 = isType(o2);
-                    //printf("\ttest: o2 = %s\n", o2.toChars());
-                    size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1)
-                        ? templateParameterLookup(t2, parameters) : IDX_NOTFOUND;
-                    if (j != IDX_NOTFOUND && j == parameters.length - 1 &&
-                        (*parameters)[j].isTemplateTupleParameter())
-                    {
-                        /* Given:
+                RootObject o2 = (*tp.tempinst.tiargs)[i];
+                Type t2 = isType(o2);
+                //printf("\ttest: o2 = %s\n", o2.toChars());
+                size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1)
+                    ? templateParameterLookup(t2, parameters) : IDX_NOTFOUND;
+                if (j != IDX_NOTFOUND && j == parameters.length - 1 &&
+                    (*parameters)[j].isTemplateTupleParameter())
+                {
+                    /* Given:
                          *  struct A(B...) {}
                          *  alias A!(int, float) X;
                          *  static if (is(X Y == A!(Z), Z...)) {}
                          * deduce that Z is a tuple(int, float)
                          */
 
-                        /* Create tuple from remaining args
+                    /* Create tuple from remaining args
                          */
-                        size_t vtdim = (tempdecl.isVariadic() ? t.tempinst.tiargs.length : t.tempinst.tdtypes.length) - i;
-                        auto vt = new Tuple(vtdim);
-                        for (size_t k = 0; k < vtdim; k++)
-                        {
-                            RootObject o;
-                            if (k < t.tempinst.tiargs.length)
-                                o = (*t.tempinst.tiargs)[i + k];
-                            else // Pick up default arg
-                                o = t.tempinst.tdtypes[i + k];
-                            vt.objects[k] = o;
-                        }
-
-                        Tuple v = cast(Tuple)(*dedtypes)[j];
-                        if (v)
-                        {
-                            if (!match(v, vt))
-                                goto Lnomatch;
-                        }
-                        else
-                            (*dedtypes)[j] = vt;
-                        break;
-                    }
-                    else if (!o1)
-                        break;
-
-                    Type t1 = isType(o1);
-                    Dsymbol s1 = isDsymbol(o1);
-                    Dsymbol s2 = isDsymbol(o2);
-                    Expression e1 = s1 ? getValue(s1) : getValue(isExpression(o1));
-                    Expression e2 = isExpression(o2);
-                    version (none)
+                    size_t vtdim = (tempdecl.isVariadic() ? tiargs.length : tdtypes.length) - i;
+                    auto vt = new Tuple(vtdim);
+                    for (size_t k = 0; k < vtdim; k++)
                     {
-                        Tuple v1 = isTuple(o1);
-                        Tuple v2 = isTuple(o2);
-                        if (t1)
-                            printf("t1 = %s\n", t1.toChars());
-                        if (t2)
-                            printf("t2 = %s\n", t2.toChars());
-                        if (e1)
-                            printf("e1 = %s\n", e1.toChars());
-                        if (e2)
-                            printf("e2 = %s\n", e2.toChars());
-                        if (s1)
-                            printf("s1 = %s\n", s1.toChars());
-                        if (s2)
-                            printf("s2 = %s\n", s2.toChars());
-                        if (v1)
-                            printf("v1 = %s\n", v1.toChars());
-                        if (v2)
-                            printf("v2 = %s\n", v2.toChars());
+                        RootObject o;
+                        if (k < tiargs.length)
+                            o = (*tiargs)[i + k];
+                        else // Pick up default arg
+                            o = (*tdtypes)[i + k];
+                        vt.objects[k] = o;
                     }
 
-                    if (t1 && t2)
+                    Tuple v = cast(Tuple)(*dedtypes)[j];
+                    if (v)
                     {
-                        if (!deduceType(t1, sc, t2, parameters, dedtypes))
-                            goto Lnomatch;
+                        if (!match(v, vt))
+                            return false;
                     }
-                    else if (e1 && e2)
-                    {
-                    Le:
-                        e1 = e1.ctfeInterpret();
+                    else
+                        (*dedtypes)[j] = vt;
+                    break;
+                }
+                else if (!o1)
+                    break;
 
-                        /* If it is one of the template parameters for this template,
+                Type t1 = isType(o1);
+                Dsymbol s1 = isDsymbol(o1);
+                Dsymbol s2 = isDsymbol(o2);
+                Expression e1 = s1 ? getValue(s1) : getValue(isExpression(o1));
+                Expression e2 = isExpression(o2);
+                version (none)
+                {
+                    Tuple v1 = isTuple(o1);
+                    Tuple v2 = isTuple(o2);
+                    if (t1)
+                        printf("t1 = %s\n", t1.toChars());
+                    if (t2)
+                        printf("t2 = %s\n", t2.toChars());
+                    if (e1)
+                        printf("e1 = %s\n", e1.toChars());
+                    if (e2)
+                        printf("e2 = %s\n", e2.toChars());
+                    if (s1)
+                        printf("s1 = %s\n", s1.toChars());
+                    if (s2)
+                        printf("s2 = %s\n", s2.toChars());
+                    if (v1)
+                        printf("v1 = %s\n", v1.toChars());
+                    if (v2)
+                        printf("v2 = %s\n", v2.toChars());
+                }
+
+                if (t1 && t2)
+                {
+                    if (!deduceType(t1, sc, t2, parameters, dedtypes))
+                        return false;
+                }
+                else if (e1 && e2)
+                {
+                Le:
+                    e1 = e1.ctfeInterpret();
+
+                    /* If it is one of the template parameters for this template,
                          * we should not attempt to interpret it. It already has a value.
                          */
-                        if (e2.op == EXP.variable && (e2.isVarExp().var.storage_class & STC.templateparameter))
-                        {
-                            /*
+                    if (e2.op == EXP.variable && (e2.isVarExp().var.storage_class & STC.templateparameter))
+                    {
+                        /*
                              * (T:Number!(e2), int e2)
                              */
-                            j = templateIdentifierLookup(e2.isVarExp().var.ident, parameters);
-                            if (j != IDX_NOTFOUND)
-                                goto L1;
-                            // The template parameter was not from this template
-                            // (it may be from a parent template, for example)
-                        }
-
-                        e2 = e2.expressionSemantic(sc); // https://issues.dlang.org/show_bug.cgi?id=13417
-                        e2 = e2.ctfeInterpret();
+                        j = templateIdentifierLookup(e2.isVarExp().var.ident, parameters);
+                        if (j != IDX_NOTFOUND)
+                            goto L1;
+                        // The template parameter was not from this template
+                        // (it may be from a parent template, for example)
+                    }
 
-                        //printf("e1 = %s, type = %s %d\n", e1.toChars(), e1.type.toChars(), e1.type.ty);
-                        //printf("e2 = %s, type = %s %d\n", e2.toChars(), e2.type.toChars(), e2.type.ty);
-                        if (!e1.equals(e2))
-                        {
-                            if (!e2.implicitConvTo(e1.type))
-                                goto Lnomatch;
+                    e2 = e2.expressionSemantic(sc); // https://issues.dlang.org/show_bug.cgi?id=13417
+                    e2 = e2.ctfeInterpret();
 
-                            e2 = e2.implicitCastTo(sc, e1.type);
-                            e2 = e2.ctfeInterpret();
-                            if (!e1.equals(e2))
-                                goto Lnomatch;
-                        }
-                    }
-                    else if (e1 && t2 && t2.ty == Tident)
+                    //printf("e1 = %s, type = %s %d\n", e1.toChars(), e1.type.toChars(), e1.type.ty);
+                    //printf("e2 = %s, type = %s %d\n", e2.toChars(), e2.type.toChars(), e2.type.ty);
+                    if (!e1.equals(e2))
                     {
-                        j = templateParameterLookup(t2, parameters);
-                    L1:
-                        if (j == IDX_NOTFOUND)
-                        {
-                            t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
-                            if (e2)
-                                goto Le;
-                            goto Lnomatch;
-                        }
-                        if (!(*parameters)[j].matchArg(sc, e1, j, parameters, dedtypes, null))
-                            goto Lnomatch;
+                        if (!e2.implicitConvTo(e1.type))
+                            return false;
+
+                        e2 = e2.implicitCastTo(sc, e1.type);
+                        e2 = e2.ctfeInterpret();
+                        if (!e1.equals(e2))
+                            return false;
                     }
-                    else if (s1 && s2)
+                }
+                else if (e1 && t2 && t2.ty == Tident)
+                {
+                    j = templateParameterLookup(t2, parameters);
+                L1:
+                    if (j == IDX_NOTFOUND)
                     {
-                    Ls:
-                        if (!s1.equals(s2))
-                            goto Lnomatch;
+                        t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
+                        if (e2)
+                            goto Le;
+                        return false;
                     }
-                    else if (s1 && t2 && t2.ty == Tident)
+                    if (!(*parameters)[j].matchArg(sc, e1, j, parameters, dedtypes, null))
+                        return false;
+                }
+                else if (s1 && s2)
+                {
+                Ls:
+                    if (!s1.equals(s2))
+                        return false;
+                }
+                else if (s1 && t2 && t2.ty == Tident)
+                {
+                    j = templateParameterLookup(t2, parameters);
+                    if (j == IDX_NOTFOUND)
                     {
-                        j = templateParameterLookup(t2, parameters);
-                        if (j == IDX_NOTFOUND)
-                        {
-                            t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
-                            if (s2)
-                                goto Ls;
-                            goto Lnomatch;
-                        }
-                        if (!(*parameters)[j].matchArg(sc, s1, j, parameters, dedtypes, null))
-                            goto Lnomatch;
+                        t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
+                        if (s2)
+                            goto Ls;
+                        return false;
                     }
-                    else
-                        goto Lnomatch;
+                    if (!(*parameters)[j].matchArg(sc, s1, j, parameters, dedtypes, null))
+                        return false;
                 }
+                else
+                    return false;
             }
-            visit(cast(Type)t);
-            return;
-
-        Lnomatch:
-            //printf("no match\n");
-            result = MATCH.nomatch;
+            return true;
         }
 
         override void visit(TypeStruct t)
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index 4f1edaa4d05..c0dd17f2ea6 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -377,13 +377,18 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId,
                 desc ~ " `%s` assigned to non-scope parameter calling `assert()`", v);
             return;
         }
+
+        bool isThis = fdc && fdc.needThis() && fdc.vthis == vPar; // implicit `this` parameter to member function
+
         const(char)* msg =
+            (isThis)        ? (desc ~ " `%s` calling non-scope member function `%s.%s()`") :
             (fdc &&  parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s` calling `%s`") :
             (fdc && !parId) ? (desc ~ " `%s` assigned to non-scope anonymous parameter calling `%s`") :
             (!fdc && parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s`") :
             (desc ~ " `%s` assigned to non-scope anonymous parameter");
 
-        if (sc.setUnsafeDIP1000(gag, arg.loc, msg, v, parId ? parId : fdc, fdc))
+        auto param = isThis ? v : (parId ? parId : fdc);
+        if (sc.setUnsafeDIP1000(gag, arg.loc, msg, v, param, fdc))
         {
             result = true;
             printScopeFailure(previewSupplementalFunc(sc.isDeprecated(), global.params.useDIP1000), vPar, 10);
@@ -1746,20 +1751,8 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re
         /* Check each argument that is
          * passed as 'return scope'.
          */
-        Type t1 = e.e1.type.toBasetype();
-        TypeFunction tf;
-        TypeDelegate dg;
-        if (t1.ty == Tdelegate)
-        {
-            dg = t1.isTypeDelegate();
-            tf = dg.next.isTypeFunction();
-        }
-        else if (t1.ty == Tfunction)
-            tf = t1.isTypeFunction();
-        else
-            return;
-
-        if (!e.type.hasPointers())
+        TypeFunction tf = e.calledFunctionType();
+        if (!tf || !e.type.hasPointers())
             return;
 
         if (e.arguments && e.arguments.length)
@@ -1815,6 +1808,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re
             }
         }
         // If 'this' is returned, check it too
+        Type t1 = e.e1.type.toBasetype();
         if (e.e1.op == EXP.dotVariable && t1.ty == Tfunction)
         {
             DotVarExp dve = e.e1.isDotVarExp();
@@ -1880,7 +1874,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re
         /* If returning the result of a delegate call, the .ptr
          * field of the delegate must be checked.
          */
-        if (dg)
+        if (t1.isTypeDelegate())
         {
             if (tf.isreturn)
                 escapeByValue(e.e1, er, live, retRefTransition);
@@ -2066,13 +2060,8 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR
         /* If the function returns by ref, check each argument that is
          * passed as 'return ref'.
          */
-        Type t1 = e.e1.type.toBasetype();
-        TypeFunction tf;
-        if (t1.ty == Tdelegate)
-            tf = t1.isTypeDelegate().next.isTypeFunction();
-        else if (t1.ty == Tfunction)
-            tf = t1.isTypeFunction();
-        else
+        TypeFunction tf = e.calledFunctionType();
+        if (!tf)
             return;
         if (tf.isref)
         {
@@ -2107,6 +2096,7 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR
                 }
             }
             // If 'this' is returned by ref, check it too
+            Type t1 = e.e1.type.toBasetype();
             if (e.e1.op == EXP.dotVariable && t1.ty == Tfunction)
             {
                 DotVarExp dve = e.e1.isDotVarExp();
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 067d22fe130..473efb8c99a 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -19,7 +19,6 @@ import core.stdc.string;
 
 import dmd.aggregate;
 import dmd.aliasthis;
-import dmd.apply;
 import dmd.arrayop;
 import dmd.arraytypes;
 import dmd.astenums;
@@ -56,6 +55,7 @@ import dmd.nspace;
 import dmd.objc;
 import dmd.opover;
 import dmd.optimize;
+import dmd.postordervisitor;
 import dmd.root.complex;
 import dmd.root.ctfloat;
 import dmd.root.filename;
@@ -699,6 +699,20 @@ VarDeclaration expToVariable(Expression e)
             case EXP.super_:
                 return (cast(ThisExp)e).var.isVarDeclaration();
 
+            // Temporaries for rvalues that need destruction
+            // are of form: (T s = rvalue, s). For these cases
+            // we can just return var declaration of `s`. However,
+            // this is intentionally not calling `Expression.extractLast`
+            // because at this point we cannot infer the var declaration
+            // of more complex generated comma expressions such as the
+            // one for the array append hook.
+            case EXP.comma:
+            {
+                if (auto ve = e.isCommaExp().e2.isVarExp())
+                    return ve.var.isVarDeclaration();
+
+                return null;
+            }
             default:
                 return null;
         }
@@ -723,7 +737,6 @@ extern (C++) abstract class Expression : ASTNode
     Type type;      // !=null means that semantic() has been run
     Loc loc;        // file location
     const EXP op;   // to minimize use of dynamic_cast
-    bool parens;    // if this is a parenthesized expression
 
     extern (D) this(const ref Loc loc, EXP op) scope
     {
@@ -1530,6 +1543,11 @@ extern (C++) abstract class Expression : ASTNode
             return false;
         if (sc.flags & (SCOPE.ctfe | SCOPE.debug_))
             return false;
+        /* The original expression (`new S(...)`) will be verified instead. This
+         * is to keep errors related to the original code and not the lowering.
+         */
+        if (f.ident == Id._d_newitemT)
+            return false;
 
         if (!f.isNogc())
         {
@@ -2338,6 +2356,7 @@ extern (C++) final class ComplexExp : Expression
 extern (C++) class IdentifierExp : Expression
 {
     Identifier ident;
+    bool parens;        // if it appears as (identifier)
 
     extern (D) this(const ref Loc loc, Identifier ident) scope
     {
@@ -3520,6 +3539,8 @@ extern (C++) final class CompoundLiteralExp : Expression
  */
 extern (C++) final class TypeExp : Expression
 {
+    bool parens;    // if this is a parenthesized expression
+
     extern (D) this(const ref Loc loc, Type type)
     {
         super(loc, EXP.type);
@@ -3672,7 +3693,7 @@ extern (C++) final class NewExp : Expression
     bool onstack;               // allocate on stack
     bool thrownew;              // this NewExp is the expression of a ThrowStatement
 
-    Expression lowering;        // lowered druntime hook: `_d_newclass`
+    Expression lowering;        // lowered druntime hook: `_d_new{class,itemT}`
 
     /// Puts the `arguments` and `names` into an `ArgumentList` for easily passing them around.
     /// The fields are still separate for backwards compatibility
@@ -5188,6 +5209,7 @@ extern (C++) final class CallExp : UnaExp
     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)
+    bool isUfcsRewrite;     /// the first argument was pushed in here by a UFCS rewrite
     VarDeclaration vthis2;  // container for multi-context
 
     /// Puts the `arguments` and `names` into an `ArgumentList` for easily passing them around.
@@ -5329,6 +5351,26 @@ extern (C++) final class CallExp : UnaExp
     }
 }
 
+/**
+ * Get the called function type from a call expression
+ * Params:
+ *   ce = function call expression. Must have had semantic analysis done.
+ * Returns: called function type, or `null` if error / no semantic analysis done
+ */
+TypeFunction calledFunctionType(CallExp ce)
+{
+    Type t = ce.e1.type;
+    if (!t)
+        return null;
+    t = t.toBasetype();
+    if (auto tf = t.isTypeFunction())
+        return tf;
+    else if (auto td = t.isTypeDelegate())
+        return td.nextOf().isTypeFunction();
+    else
+        return null;
+}
+
 FuncDeclaration isFuncAddress(Expression e, bool* hasOverloads = null)
 {
     if (auto ae = e.isAddrExp())
@@ -7058,9 +7100,7 @@ extern (C++) final class FileInitExp : DefaultInitExp
             s = loc.isValid() ? loc.filename : sc._module.ident.toChars();
 
         Expression e = new StringExp(loc, s.toDString());
-        e = e.expressionSemantic(sc);
-        e = e.castTo(sc, type);
-        return e;
+        return e.expressionSemantic(sc);
     }
 
     override void accept(Visitor v)
@@ -7082,8 +7122,7 @@ extern (C++) final class LineInitExp : DefaultInitExp
     override Expression resolveLoc(const ref Loc loc, Scope* sc)
     {
         Expression e = new IntegerExp(loc, loc.linnum, Type.tint32);
-        e = e.castTo(sc, type);
-        return e;
+        return e.expressionSemantic(sc);
     }
 
     override void accept(Visitor v)
@@ -7106,9 +7145,7 @@ extern (C++) final class ModuleInitExp : DefaultInitExp
     {
         const auto s = (sc.callsc ? sc.callsc : sc)._module.toPrettyChars().toDString();
         Expression e = new StringExp(loc, s);
-        e = e.expressionSemantic(sc);
-        e = e.castTo(sc, type);
-        return e;
+        return e.expressionSemantic(sc);
     }
 
     override void accept(Visitor v)
@@ -7137,9 +7174,7 @@ extern (C++) final class FuncInitExp : DefaultInitExp
         else
             s = "";
         Expression e = new StringExp(loc, s.toDString());
-        e = e.expressionSemantic(sc);
-        e.type = Type.tstring;
-        return e;
+        return e.expressionSemantic(sc);
     }
 
     override void accept(Visitor v)
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index a4b18b9fe9e..770c3e7ae3d 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -83,7 +83,6 @@ public:
     Type *type;                 // !=NULL means that semantic() has been run
     Loc loc;                    // file location
     EXP op;                     // to minimize use of dynamic_cast
-    d_bool parens;              // if this is a parenthesized expression
 
     size_t size() const;
     static void _init();
@@ -316,6 +315,7 @@ class IdentifierExp : public Expression
 {
 public:
     Identifier *ident;
+    d_bool parens;
 
     static IdentifierExp *create(const Loc &loc, Identifier *ident);
     bool isLvalue() override final;
@@ -839,6 +839,7 @@ public:
     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)
+    d_bool isUfcsRewrite;       // the first argument was pushed in here by a UFCS rewrite
     VarDeclaration *vthis2;     // container for multi-context
 
     static CallExp *create(const Loc &loc, Expression *e, Expressions *exps);
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index cf4aac4a889..8ac8866a85b 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -653,7 +653,7 @@ private Expression resolveUFCS(Scope* sc, CallExp ce)
     if (!ce.names)
         ce.names = new Identifiers();
     ce.names.shift(null);
-
+    ce.isUfcsRewrite = true;
     return null;
 }
 
@@ -1254,12 +1254,12 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
                 return ErrorExp.get();
             e2 = resolveProperties(sc, e2);
 
-            Expressions a;
+            Expressions* a = new Expressions();
             a.push(e2);
 
             for (size_t i = 0; i < os.a.length; i++)
             {
-                if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, ArgumentList(&a), FuncResolveFlag.quiet))
+                if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, ArgumentList(a), FuncResolveFlag.quiet))
                 {
                     if (f.errors)
                         return ErrorExp.get();
@@ -1378,10 +1378,10 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
                 return ErrorExp.get();
             e2 = resolveProperties(sc, e2);
 
-            Expressions a;
+            Expressions* a = new Expressions();
             a.push(e2);
 
-            FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, ArgumentList(&a), FuncResolveFlag.quiet);
+            FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, ArgumentList(a), FuncResolveFlag.quiet);
             if (fd && fd.type)
             {
                 if (fd.errors)
@@ -3574,6 +3574,51 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
         result = exp;
     }
 
+    /**
+     * Sets the `lowering` field of a `NewExp` to a call to `_d_newitemT` unless
+     * compiling with `-betterC` or within `__traits(compiles)`.
+     *
+     * Params:
+     *  ne = the `NewExp` to lower
+     */
+    private void tryLowerToNewItem(NewExp ne)
+    {
+        if (global.params.betterC || !sc.needsCodegen())
+            return;
+
+        auto hook = global.params.tracegc ? Id._d_newitemTTrace : Id._d_newitemT;
+        if (!verifyHookExist(ne.loc, *sc, hook, "new struct"))
+            return;
+
+        /* Lower the memory allocation and initialization of `new T()` to
+         * `_d_newitemT!T()`.
+         */
+        Expression id = new IdentifierExp(ne.loc, Id.empty);
+        id = new DotIdExp(ne.loc, id, Id.object);
+        auto tiargs = new Objects();
+        /*
+         * Remove `inout`, `const`, `immutable` and `shared` to reduce the
+         * number of generated `_d_newitemT` instances.
+         */
+        auto t = ne.type.nextOf.unqualify(MODFlags.wild | MODFlags.const_ |
+            MODFlags.immutable_ | MODFlags.shared_);
+        tiargs.push(t);
+        id = new DotTemplateInstanceExp(ne.loc, id, hook, tiargs);
+
+        auto arguments = new Expressions();
+        if (global.params.tracegc)
+        {
+            auto funcname = (sc.callsc && sc.callsc.func) ?
+                sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
+            arguments.push(new StringExp(ne.loc, ne.loc.filename.toDString()));
+            arguments.push(new IntegerExp(ne.loc, ne.loc.linnum, Type.tint32));
+            arguments.push(new StringExp(ne.loc, funcname.toDString()));
+        }
+        id = new CallExp(ne.loc, id, arguments);
+
+        ne.lowering = id.expressionSemantic(sc);
+    }
+
     override void visit(NewExp exp)
     {
         static if (LOGSEMANTIC)
@@ -4007,6 +4052,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             }
 
             exp.type = exp.type.pointerTo();
+            tryLowerToNewItem(exp);
         }
         else if (tb.ty == Tarray)
         {
@@ -4078,6 +4124,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             }
 
             exp.type = exp.type.pointerTo();
+            tryLowerToNewItem(exp);
         }
         else if (tb.ty == Taarray)
         {
@@ -5192,7 +5239,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             {
                 s = (cast(TemplateExp)exp.e1).td;
             L2:
-                exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, null, exp.argumentList, FuncResolveFlag.standard);
+                exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, null, exp.argumentList,
+                    exp.isUfcsRewrite ? FuncResolveFlag.ufcs : FuncResolveFlag.standard);
                 if (!exp.f || exp.f.errors)
                     return setError();
                 if (exp.f.needThis())
@@ -5301,6 +5349,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                     buf.writeByte(')');
 
                     //printf("tf = %s, args = %s\n", tf.deco, (*arguments)[0].type.deco);
+                    if (exp.isUfcsRewrite)
+                    {
+                        const arg = (*exp.argumentList.arguments)[0];
+                        .error(exp.loc, "no property `%s` for `%s` of type `%s`", exp.f.ident.toChars(), arg.toChars(), arg.type.toChars());
+                        .errorSupplemental(exp.loc, "the following error occured while looking for a UFCS match");
+                    }
+
                     .error(exp.loc, "%s `%s%s` is not callable using argument types `%s`",
                         exp.f.kind(), exp.f.toPrettyChars(), parametersTypeToChars(tf.parameterList), buf.peekChars());
                     if (failMessage)
@@ -6733,7 +6788,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
 
             if (exp.ident != Id.__sizeof)
             {
-                result = fieldLookup(exp.e1, sc, exp.ident);
+                result = fieldLookup(exp.e1, sc, exp.ident, exp.arrow);
                 return;
             }
         }
@@ -9068,7 +9123,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             else if (sc.flags & SCOPE.Cfile && e1x.isDotIdExp())
             {
                 auto die = e1x.isDotIdExp();
-                e1x = fieldLookup(die.e1, sc, die.ident);
+                e1x = fieldLookup(die.e1, sc, die.ident, die.arrow);
             }
             else if (auto die = e1x.isDotIdExp())
             {
@@ -11023,7 +11078,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)
+        if (global.params.betterC || !sc.needsCodegen())
             return;
 
         if (auto ce = exp.isCatExp())
@@ -13175,10 +13230,20 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag)
                 Expression se = new ScopeExp(exp.loc, imp.pkg);
                 return se.expressionSemantic(sc);
             }
+
+            if (auto attr = s.isAttribDeclaration())
+            {
+                if (auto sm = ie.sds.search(exp.loc, exp.ident, flags))
+                {
+                    auto es = new DsymbolExp(exp.loc, sm);
+                    return es;
+                }
+            }
+
             // BUG: handle other cases like in IdentifierExp::semantic()
             debug
             {
-                printf("s = '%s', kind = '%s'\n", s.toChars(), s.kind());
+                printf("s = %p '%s', kind = '%s'\n", s, s.toChars(), s.kind());
             }
             assert(0);
         }
diff --git a/gcc/d/dmd/foreachvar.d b/gcc/d/dmd/foreachvar.d
index 7a964695f45..1293057fe83 100644
--- a/gcc/d/dmd/foreachvar.d
+++ b/gcc/d/dmd/foreachvar.d
@@ -15,7 +15,6 @@ import core.stdc.stdio;
 import core.stdc.stdlib;
 import core.stdc.string;
 
-import dmd.apply;
 import dmd.arraytypes;
 import dmd.astenums;
 import dmd.attrib;
@@ -33,6 +32,7 @@ import dmd.identifier;
 import dmd.init;
 import dmd.initsem;
 import dmd.mtype;
+import dmd.postordervisitor;
 import dmd.printast;
 import dmd.root.array;
 import dmd.root.rootobject;
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index 8e11ab1bb4c..a714d2d281a 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -59,6 +59,10 @@ import dmd.statementsem;
 import dmd.tokens;
 import dmd.visitor;
 
+version (IN_GCC) {}
+else version (IN_LLVM) {}
+else version = MARS;
+
 /// Inline Status
 enum ILS : ubyte
 {
@@ -259,21 +263,30 @@ extern (C++) struct Ensure
 }
 
 /***********************************************************
+ * Most functions don't have contracts, so save memory by grouping
+ * this information into a separate struct
  */
-extern (C++) class FuncDeclaration : Declaration
+private struct ContractInfo
 {
     Statements* frequires;              /// in contracts
     Ensures* fensures;                  /// out contracts
     Statement frequire;                 /// lowered in contract
     Statement fensure;                  /// lowered out contract
-    Statement fbody;                    /// function body
-
-    FuncDeclarations foverrides;        /// functions this function overrides
     FuncDeclaration fdrequire;          /// function that does the in contract
     FuncDeclaration fdensure;           /// function that does the out contract
-
     Expressions* fdrequireParams;       /// argument list for __require
     Expressions* fdensureParams;        /// argument list for __ensure
+}
+
+/***********************************************************
+ */
+extern (C++) class FuncDeclaration : Declaration
+{
+    Statement fbody;                    /// function body
+
+    FuncDeclarations foverrides;        /// functions this function overrides
+
+    private ContractInfo* contracts;    /// contract information
 
     const(char)* mangleString;          /// mangled symbol created from mangleExact()
 
@@ -403,6 +416,44 @@ extern (C++) class FuncDeclaration : Declaration
         return new FuncDeclaration(loc, endloc, id, storage_class, type, noreturn);
     }
 
+    final nothrow pure @safe
+    {
+        private ref ContractInfo getContracts()
+        {
+            if (!contracts)
+                contracts = new ContractInfo();
+            return *contracts;
+        }
+
+        // getters
+        inout(Statements*) frequires() inout { return contracts ? contracts.frequires : null; }
+        inout(Ensures*) fensures() inout { return contracts ? contracts.fensures : null; }
+        inout(Statement) frequire() inout { return contracts ? contracts.frequire: null; }
+        inout(Statement) fensure() inout { return contracts ? contracts.fensure : null; }
+        inout(FuncDeclaration) fdrequire() inout { return contracts ? contracts.fdrequire : null; }
+        inout(FuncDeclaration) fdensure() inout { return contracts ? contracts.fdensure: null; }
+        inout(Expressions*) fdrequireParams() inout { return contracts ? contracts.fdrequireParams: null; }
+        inout(Expressions*) fdensureParams() inout { return contracts ? contracts.fdensureParams: null; }
+
+        extern (D) private static string generateContractSetter(string field, string type)
+        {
+            return type ~ " " ~ field ~ "(" ~ type ~ " param)" ~
+                    "{
+                        if (!param && !contracts) return null;
+                        return getContracts()." ~ field ~ " = param;
+                     }";
+        }
+
+        mixin(generateContractSetter("frequires", "Statements*"));
+        mixin(generateContractSetter("fensures", "Ensures*"));
+        mixin(generateContractSetter("frequire", "Statement"));
+        mixin(generateContractSetter("fensure", "Statement"));
+        mixin(generateContractSetter("fdrequire", "FuncDeclaration"));
+        mixin(generateContractSetter("fdensure", "FuncDeclaration"));
+        mixin(generateContractSetter("fdrequireParams", "Expressions*"));
+        mixin(generateContractSetter("fdensureParams", "Expressions*"));
+    }
+
     override FuncDeclaration syntaxCopy(Dsymbol s)
     {
         //printf("FuncDeclaration::syntaxCopy('%s')\n", toChars());
@@ -2717,7 +2768,7 @@ extern (C++) class FuncDeclaration : Declaration
      */
     static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, const(char)* name, StorageClass stc = 0)
     {
-        return genCfunc(fparams, treturn, Identifier.idPool(name, cast(uint)strlen(name)), stc);
+        return genCfunc(fparams, treturn, Identifier.idPool(name[0 .. strlen(name)]), stc);
     }
 
     static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, Identifier id, StorageClass stc = 0)
@@ -3199,6 +3250,7 @@ enum FuncResolveFlag : ubyte
     quiet = 1,          /// do not issue error message on no match, just return `null`.
     overloadOnly = 2,   /// only resolve overloads, i.e. do not issue error on ambiguous
                         /// matches and need explicit this.
+    ufcs = 4,           /// trying to resolve UFCS call
 }
 
 /*******************************************
@@ -3316,12 +3368,22 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,
     }
 
     // no match, generate an error messages
+    if (flags & FuncResolveFlag.ufcs)
+    {
+        auto arg = (*fargs)[0];
+        .error(loc, "no property `%s` for `%s` of type `%s`", s.ident.toChars(), arg.toChars(), arg.type.toChars());
+        .errorSupplemental(loc, "the following error occured while looking for a UFCS match");
+    }
+
     if (!fd)
     {
         // all of overloads are templates
         if (td)
         {
-            .error(loc, "none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`",
+            const(char)* msg = "none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`";
+            if (!od && !td.overnext)
+                msg = "%s `%s.%s` is not callable using argument types `!(%s)%s`";
+            .error(loc, msg,
                    td.kind(), td.parent.toPrettyChars(), td.ident.toChars(),
                    tiargsBuf.peekChars(), fargsBuf.peekChars());
 
diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d
index 45b4528c204..0ac60420ef7 100644
--- a/gcc/d/dmd/globals.d
+++ b/gcc/d/dmd/globals.d
@@ -26,6 +26,10 @@ import dmd.location;
 import dmd.lexer : CompileEnv;
 import dmd.utils;
 
+version (IN_GCC) {}
+else version (IN_LLVM) {}
+else version = MARS;
+
 /// Defines a setting for how compiler warnings and deprecations are handled
 enum DiagnosticReporting : ubyte
 {
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index 902cf83f81f..66345acc88b 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -353,10 +353,11 @@ typedef unsigned long long uinteger_t;
 // file location
 struct Loc
 {
-    const char *filename; // either absolute or relative to cwd
-    unsigned linnum;
-    unsigned charnum;
-
+private:
+    unsigned _linnum;
+    unsigned short _charnum;
+    unsigned short fileIndex;
+public:
     static void set(bool showColumns, MessageStyle messageStyle);
 
     static bool showColumns;
@@ -364,18 +365,25 @@ struct Loc
 
     Loc()
     {
-        linnum = 0;
-        charnum = 0;
-        filename = NULL;
+        _linnum = 0;
+        _charnum = 0;
+        fileIndex = 0;
     }
 
     Loc(const char *filename, unsigned linnum, unsigned charnum)
     {
-        this->linnum = linnum;
-        this->charnum = charnum;
-        this->filename = filename;
+        this->linnum(linnum);
+        this->charnum(charnum);
+        this->filename(filename);
     }
 
+    uint32_t charnum() const;
+    uint32_t charnum(uint32_t num);
+    uint32_t linnum() const;
+    uint32_t linnum(uint32_t num);
+    const char *filename() const;
+    void filename(const char *name);
+
     const char *toChars(
         bool showColumns = Loc::showColumns,
         MessageStyle messageStyle = Loc::messageStyle) const;
diff --git a/gcc/d/dmd/gluelayer.d b/gcc/d/dmd/gluelayer.d
index 7b52eff663d..1793700463c 100644
--- a/gcc/d/dmd/gluelayer.d
+++ b/gcc/d/dmd/gluelayer.d
@@ -48,25 +48,6 @@ version (NoBackend)
         }
     }
 }
-else version (MARS)
-{
-    public import dmd.backend.cc : block, Blockx, Symbol;
-    public import dmd.backend.type : type;
-    public import dmd.backend.el : elem;
-    public import dmd.backend.code_x86 : code;
-
-    extern (C++)
-    {
-        Statement asmSemantic(AsmStatement s, Scope* sc);
-
-        void toObjFile(Dsymbol ds, bool multiobj);
-
-        extern(C++) abstract class ObjcGlue
-        {
-            static void initialize();
-        }
-    }
-}
 else version (IN_GCC)
 {
     extern (C++) union tree_node;
@@ -88,4 +69,12 @@ else version (IN_GCC)
     }
 }
 else
-    static assert(false, "Unsupported compiler backend");
+{
+    public import dmd.backend.cc : block, Blockx, Symbol;
+    public import dmd.backend.type : type;
+    public import dmd.backend.el : elem;
+    public import dmd.backend.code_x86 : code;
+    public import dmd.iasm : asmSemantic;
+    public import dmd.objc_glue : ObjcGlue;
+    public import dmd.toobj : toObjFile;
+}
diff --git a/gcc/d/dmd/iasm.d b/gcc/d/dmd/iasm.d
index 66829da8667..1fdfe40765b 100644
--- a/gcc/d/dmd/iasm.d
+++ b/gcc/d/dmd/iasm.d
@@ -23,13 +23,14 @@ import dmd.tokens;
 import dmd.statement;
 import dmd.statementsem;
 
-version (MARS)
+version (IN_GCC)
 {
-    import dmd.iasmdmd;
+    import dmd.iasmgcc;
 }
-else version (IN_GCC)
+else
 {
-    import dmd.iasmgcc;
+    import dmd.iasmdmd;
+    version = MARS;
 }
 
 /************************ AsmStatement ***************************************/
diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d
index a2271d51017..a2daf6064d3 100644
--- a/gcc/d/dmd/id.d
+++ b/gcc/d/dmd/id.d
@@ -315,6 +315,8 @@ immutable Msgtable[] msgtable =
     { "_d_newThrowable" },
     { "_d_newclassT" },
     { "_d_newclassTTrace" },
+    { "_d_newitemT" },
+    { "_d_newitemTTrace" },
     { "_d_assert_fail" },
     { "dup" },
     { "_aaApply" },
@@ -549,6 +551,7 @@ immutable Msgtable[] msgtable =
     { "_pure", "pure" },
     { "define" },
     { "undef" },
+    { "ident" },
 ];
 
 
diff --git a/gcc/d/dmd/identifier.d b/gcc/d/dmd/identifier.d
index 2233d777770..b1c421c1c59 100644
--- a/gcc/d/dmd/identifier.d
+++ b/gcc/d/dmd/identifier.d
@@ -274,12 +274,7 @@ nothrow:
         return idPool(s[0 .. len]);
     }
 
-    extern (D) static Identifier idPool(const(char)[] s)
-    {
-        return idPool(s, false);
-    }
-
-    extern (D) private static Identifier idPool(const(char)[] s, bool isAnonymous)
+    extern (D) static Identifier idPool(const(char)[] s, bool isAnonymous = false)
     {
         auto sv = stringtable.update(s);
         auto id = sv.value;
@@ -291,18 +286,18 @@ nothrow:
         return id;
     }
 
-    extern (D) static Identifier idPool(const(char)* s, size_t len, int value)
-    {
-        return idPool(s[0 .. len], value);
-    }
-
-    extern (D) static Identifier idPool(const(char)[] s, int value)
+    /******************************************
+     * Used for inserting keywords into the string table.
+     * Params:
+     *  s = string for keyword
+     *  value = TOK.xxxx for the keyword
+     */
+    extern (D) static void idPool(const(char)[] s, TOK value)
     {
         auto sv = stringtable.insert(s, null);
         assert(sv);
         auto id = new Identifier(sv.toString(), value);
         sv.value = id;
-        return id;
     }
 
     /**********************************
diff --git a/gcc/d/dmd/importc.d b/gcc/d/dmd/importc.d
index 97710b88199..fe0aa171d98 100644
--- a/gcc/d/dmd/importc.d
+++ b/gcc/d/dmd/importc.d
@@ -108,11 +108,12 @@ Expression arrayFuncConv(Expression e, Scope* sc)
  *   e = evaluates to an instance of a struct
  *   sc = context
  *   id = identifier of a field in that struct
+ *   arrow = -> was used
  * Returns:
  *   if successful `e.ident`
  *   if not then `ErrorExp` and message is printed
  */
-Expression fieldLookup(Expression e, Scope* sc, Identifier id)
+Expression fieldLookup(Expression e, Scope* sc, Identifier id, bool arrow)
 {
     e = e.expressionSemantic(sc);
     if (e.isErrorExp())
@@ -123,6 +124,9 @@ Expression fieldLookup(Expression e, Scope* sc, Identifier id)
     if (t.isTypePointer())
     {
         t = t.isTypePointer().next;
+        auto pe = e.toChars();
+        if (!arrow)
+            e.error("since `%s` is a pointer, use `%s->%s` instead of `%s.%s`", pe, pe, id.toChars(), pe, id.toChars());
         e = new PtrExp(e.loc, e);
     }
     if (auto ts = t.isTypeStruct())
@@ -237,15 +241,16 @@ Expression castCallAmbiguity(Expression e, Scope* sc)
 
             case EXP.call:
                 auto ce = (*pe).isCallExp();
-                if (ce.e1.parens)
+                auto ie = ce.e1.isIdentifierExp();
+                if (ie && ie.parens)
                 {
-                    ce.e1 = expressionSemantic(ce.e1, sc);
+                    ce.e1 = expressionSemantic(ie, sc);
                     if (ce.e1.op == EXP.type)
                     {
                         const numArgs = ce.arguments ? ce.arguments.length : 0;
                         if (numArgs >= 1)
                         {
-                            ce.e1.parens = false;
+                            ie.parens = false;
                             Expression arg;
                             foreach (a; (*ce.arguments)[])
                             {
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index 893d2a627c3..ca770bd77b6 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -587,6 +587,9 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
          */
         t = t.toBasetype();
 
+        if (auto tv = t.isTypeVector())
+            t = tv.basetype;
+
         /* If `{ expression }` return the expression initializer
          */
         ExpInitializer isBraceExpression()
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index 0ec468b3245..a878cc9523d 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -119,7 +119,7 @@ class Lexer
     this(const(char)* filename, const(char)* base, size_t begoffset,
         size_t endoffset, bool doDocComment, bool commentToken,
         ErrorSink errorSink,
-        const CompileEnv* compileEnv) pure scope
+        const CompileEnv* compileEnv) scope
     {
         scanloc = Loc(filename, 1, 1);
         // debug printf("Lexer::Lexer(%p)\n", base);
@@ -573,7 +573,7 @@ class Lexer
                         }
                         break;
                     }
-                    Identifier id = Identifier.idPool(cast(char*)t.ptr, cast(uint)(p - t.ptr));
+                    Identifier id = Identifier.idPool((cast(char*)t.ptr)[0 .. p - t.ptr], false);
                     t.ident = id;
                     t.value = cast(TOK)id.getValue();
 
@@ -2672,9 +2672,9 @@ class Lexer
         return result;
     }
 
-    final Loc loc() pure @nogc
+    final Loc loc() @nogc
     {
-        scanloc.charnum = cast(uint)(1 + p - line);
+        scanloc.charnum = cast(ushort)(1 + p - line);
         version (LocOffset)
             scanloc.fileOffset = cast(uint)(p - base);
         return scanloc;
@@ -3098,9 +3098,9 @@ class Lexer
     /**************************
      * `p` should be at start of next line
      */
-    private void endOfLine() pure @nogc @safe
+    private void endOfLine() @nogc @safe
     {
-        scanloc.linnum++;
+        scanloc.linnum = scanloc.linnum + 1;
         line = p;
     }
 }
diff --git a/gcc/d/dmd/location.d b/gcc/d/dmd/location.d
index 020d297b06d..b2b366130ca 100644
--- a/gcc/d/dmd/location.d
+++ b/gcc/d/dmd/location.d
@@ -11,7 +11,10 @@
 
 module dmd.location;
 
+import core.stdc.stdio;
+
 import dmd.common.outbuffer;
+import dmd.root.array;
 import dmd.root.filename;
 
 version (DMDLIB)
@@ -34,10 +37,9 @@ debug info etc.
 */
 struct Loc
 {
-    /// zero-terminated filename string, either absolute or relative to cwd
-    const(char)* filename;
-    uint linnum; /// line number, starting from 1
-    uint charnum; /// utf8 code unit index relative to start of line, starting from 1
+    private uint _linnum;
+    private ushort _charnum;
+    private ushort fileIndex; // index into filenames[], starting from 1 (0 means no filename)
     version (LocOffset)
         uint fileOffset; /// utf8 code unit index relative to start of file, starting from 0
 
@@ -46,6 +48,8 @@ struct Loc
     extern (C++) __gshared bool showColumns;
     extern (C++) __gshared MessageStyle messageStyle;
 
+    __gshared Array!(const(char)*) filenames;
+
 nothrow:
 
     /*******************************
@@ -60,19 +64,69 @@ nothrow:
         this.messageStyle = messageStyle;
     }
 
-    extern (D) this(const(char)* filename, uint linnum, uint charnum) pure
+    extern (D) this(const(char)* filename, uint linnum, uint charnum)
     {
-        this.linnum = linnum;
-        this.charnum = charnum;
+        this._linnum = linnum;
+        this._charnum = cast(ushort) charnum;
         this.filename = filename;
     }
 
+    /// utf8 code unit index relative to start of line, starting from 1
+    extern (C++) uint charnum() const @nogc @safe
+    {
+        return _charnum;
+    }
+
+    /// ditto
+    extern (C++) uint charnum(uint num) @nogc @safe
+    {
+        return _charnum = cast(ushort) num;
+    }
+
+    /// line number, starting from 1
+    extern (C++) uint linnum() const @nogc @safe
+    {
+        return _linnum;
+    }
+
+    /// ditto
+    extern (C++) uint linnum(uint num) @nogc @safe
+    {
+        return _linnum = num;
+    }
+
+    /***
+     * Returns: filename for this location, null if none
+     */
+    extern (C++) const(char)* filename() const @nogc
+    {
+        return fileIndex ? filenames[fileIndex - 1] : null;
+    }
+
+    /***
+     * Set file name for this location
+     * Params:
+     *   name = file name for location, null for no file name
+     */
+    extern (C++) void filename(const(char)* name)
+    {
+        if (name)
+        {
+            //printf("setting %s\n", name);
+            filenames.push(name);
+            fileIndex = cast(ushort)filenames.length;
+            assert(fileIndex);  // no overflow
+        }
+        else
+            fileIndex = 0;
+    }
+
     extern (C++) const(char)* toChars(
         bool showColumns = Loc.showColumns,
-        MessageStyle messageStyle = Loc.messageStyle) const pure nothrow
+        MessageStyle messageStyle = Loc.messageStyle) const nothrow
     {
         OutBuffer buf;
-        if (filename)
+        if (fileIndex)
         {
             buf.writestring(filename);
         }
@@ -126,7 +180,7 @@ nothrow:
      * may lead to multiple equivalent filenames (`foo.d-mixin-<line>`),
      * e.g., for test/runnable/test18880.d.
      */
-    extern (D) bool opEquals(ref const(Loc) loc) const @trusted pure nothrow @nogc
+    extern (D) bool opEquals(ref const(Loc) loc) const @trusted nothrow @nogc
     {
         import core.stdc.string : strcmp;
 
@@ -137,7 +191,7 @@ nothrow:
     }
 
     /// ditto
-    extern (D) size_t toHash() const @trusted pure nothrow
+    extern (D) size_t toHash() const @trusted nothrow
     {
         import dmd.root.string : toDString;
 
@@ -153,6 +207,6 @@ nothrow:
      */
     bool isValid() const pure
     {
-        return filename !is null;
+        return fileIndex != 0;
     }
 }
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index badc5795547..cb3e6cddd20 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -2448,7 +2448,7 @@ extern (C++) abstract class Type : ASTNode
         //printf("%p %s, deco = %s, name = %s\n", this, toChars(), deco, name);
         assert(0 < length && length < namelen); // don't overflow the buffer
 
-        auto id = Identifier.idPool(name, length);
+        auto id = Identifier.idPool(name[0 .. length]);
 
         if (name != namebuf.ptr)
             free(name);
@@ -7119,9 +7119,9 @@ bool isCopyable(Type t)
             assert(ctor);
             scope el = new IdentifierExp(Loc.initial, Id.p); // dummy lvalue
             el.type = cast() ts;
-            Expressions args;
+            Expressions* args = new Expressions();
             args.push(el);
-            FuncDeclaration f = resolveFuncCall(Loc.initial, null, ctor, null, cast()ts, ArgumentList(&args), FuncResolveFlag.quiet);
+            FuncDeclaration f = resolveFuncCall(Loc.initial, null, ctor, null, cast()ts, ArgumentList(args), FuncResolveFlag.quiet);
             if (!f || f.storage_class & STC.disable)
                 return false;
         }
diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d
index a0f3e60861b..9a8f2422746 100644
--- a/gcc/d/dmd/nogc.d
+++ b/gcc/d/dmd/nogc.d
@@ -16,7 +16,6 @@ module dmd.nogc;
 import core.stdc.stdio;
 
 import dmd.aggregate;
-import dmd.apply;
 import dmd.astenums;
 import dmd.declaration;
 import dmd.dscope;
@@ -26,6 +25,7 @@ import dmd.func;
 import dmd.globals;
 import dmd.init;
 import dmd.mtype;
+import dmd.postordervisitor;
 import dmd.tokens;
 import dmd.visitor;
 
diff --git a/gcc/d/dmd/ob.d b/gcc/d/dmd/ob.d
index 89728b64486..56243a0e035 100644
--- a/gcc/d/dmd/ob.d
+++ b/gcc/d/dmd/ob.d
@@ -20,7 +20,6 @@ import dmd.root.rootobject;
 import dmd.root.rmem;
 
 import dmd.aggregate;
-import dmd.apply;
 import dmd.arraytypes;
 import dmd.astenums;
 import dmd.declaration;
diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d
index d7b90d7635f..0e64d9c7c8d 100644
--- a/gcc/d/dmd/opover.d
+++ b/gcc/d/dmd/opover.d
@@ -607,8 +607,6 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
             //printf("BinExp::op_overload() (%s)\n", e.toChars());
             Identifier id = opId(e);
             Identifier id_r = opId_r(e);
-            Expressions args1;
-            Expressions args2;
             int argsset = 0;
             AggregateDeclaration ad1 = isAggregate(e.e1.type);
             AggregateDeclaration ad2 = isAggregate(e.e2.type);
@@ -701,6 +699,8 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
                     }
                 }
             }
+            Expressions* args1 = new Expressions();
+            Expressions* args2 = new Expressions();
             if (s || s_r)
             {
                 /* Try:
@@ -709,16 +709,16 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
                  * and see which is better.
                  */
                 args1.setDim(1);
-                args1[0] = e.e1;
-                expandTuples(&args1);
+                (*args1)[0] = e.e1;
+                expandTuples(args1);
                 args2.setDim(1);
-                args2[0] = e.e2;
-                expandTuples(&args2);
+                (*args2)[0] = e.e2;
+                expandTuples(args2);
                 argsset = 1;
                 MatchAccumulator m;
                 if (s)
                 {
-                    functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2));
+                    functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
                     if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
                     {
                         return ErrorExp.get();
@@ -727,7 +727,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
                 FuncDeclaration lastf = m.lastf;
                 if (s_r)
                 {
-                    functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(&args1));
+                    functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1));
                     if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
                     {
                         return ErrorExp.get();
@@ -791,16 +791,16 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
                         if (!argsset)
                         {
                             args1.setDim(1);
-                            args1[0] = e.e1;
-                            expandTuples(&args1);
+                            (*args1)[0] = e.e1;
+                            expandTuples(args1);
                             args2.setDim(1);
-                            args2[0] = e.e2;
-                            expandTuples(&args2);
+                            (*args2)[0] = e.e2;
+                            expandTuples(args2);
                         }
                         MatchAccumulator m;
                         if (s_r)
                         {
-                            functionResolve(m, s_r, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2));
+                            functionResolve(m, s_r, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
                             if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
                             {
                                 return ErrorExp.get();
@@ -809,7 +809,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
                         FuncDeclaration lastf = m.lastf;
                         if (s)
                         {
-                            functionResolve(m, s, e.loc, sc, tiargs, e.e2.type, ArgumentList(&args1));
+                            functionResolve(m, s, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1));
                             if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
                             {
                                 return ErrorExp.get();
@@ -1197,7 +1197,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
                 return ErrorExp.get();
             }
             Identifier id = opId(e);
-            Expressions args2;
+            Expressions* args2 = new Expressions();
             AggregateDeclaration ad1 = isAggregate(e.e1.type);
             Dsymbol s = null;
             Objects* tiargs = null;
@@ -1240,10 +1240,10 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
                  *      a.opOpAssign(b)
                  */
                 args2.setDim(1);
-                args2[0] = e.e2;
-                expandTuples(&args2);
+                (*args2)[0] = e.e2;
+                expandTuples(args2);
                 MatchAccumulator m;
-                functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2));
+                functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
                 if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
                 {
                     return ErrorExp.get();
@@ -1322,12 +1322,12 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop
          *      b.opEquals(a)
          * and see which is better.
          */
-        Expressions args1 = Expressions(1);
-        args1[0] = e.e1;
-        expandTuples(&args1);
-        Expressions args2 = Expressions(1);
-        args2[0] = e.e2;
-        expandTuples(&args2);
+        Expressions* args1 = new Expressions(1);
+        (*args1)[0] = e.e1;
+        expandTuples(args1);
+        Expressions* args2 = new Expressions(1);
+        (*args2)[0] = e.e2;
+        expandTuples(args2);
         MatchAccumulator m;
         if (0 && s && s_r)
         {
@@ -1336,7 +1336,7 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop
         }
         if (s)
         {
-            functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2));
+            functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
             if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
                 return ErrorExp.get();
         }
@@ -1344,7 +1344,7 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop
         int count = m.count;
         if (s_r)
         {
-            functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(&args1));
+            functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1));
             if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
                 return ErrorExp.get();
         }
diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d
index 61c385fc061..335310de65d 100644
--- a/gcc/d/dmd/optimize.d
+++ b/gcc/d/dmd/optimize.d
@@ -769,11 +769,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
             return;
         if (e.arguments)
         {
-            Type t1 = e.e1.type.toBasetype();
-            if (auto td = t1.isTypeDelegate())
-                t1 = td.next;
             // t1 can apparently be void for __ArrayDtor(T) calls
-            if (auto tf = t1.isTypeFunction())
+            if (auto tf = e.calledFunctionType())
             {
                 foreach (i, ref arg; (*e.arguments)[])
                 {
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index 68a25064fc0..b7e07911cb9 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -4515,10 +4515,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                 }
                 if (_init)
                 {
-                    if (isThis)
-                        error(token.loc, "cannot use syntax `alias this = %s`, use `alias %s this` instead", _init.toChars(), _init.toChars());
-                    else
-                        error("alias cannot have initializer");
+                    error("alias cannot have initializer");
                 }
                 v = new AST.AliasDeclaration(aliasLoc, ident, t);
 
@@ -4780,23 +4777,20 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
             addComment(s, comment);
             return a;
         }
-        version (none)
+        /* Look for:
+         *  alias this = identifier;
+         */
+        if (token.value == TOK.this_ && peekNext() == TOK.assign && peekNext2() == TOK.identifier)
         {
-            /* Look for:
-             *  alias this = identifier;
-             */
-            if (token.value == TOK.this_ && peekNext() == TOK.assign && peekNext2() == TOK.identifier)
-            {
-                check(TOK.this_);
-                check(TOK.assign);
-                auto s = new AliasThis(loc, token.ident);
-                nextToken();
-                check(TOK.semicolon, "`alias this = Identifier`");
-                auto a = new Dsymbols();
-                a.push(s);
-                addComment(s, comment);
-                return a;
-            }
+            check(TOK.this_);
+            check(TOK.assign);
+            auto s = new AST.AliasThis(loc, token.ident);
+            nextToken();
+            check(TOK.semicolon, "`alias this = Identifier`");
+            auto a = new AST.Dsymbols();
+            a.push(s);
+            addComment(s, comment);
+            return a;
         }
         /* Look for:
          *  alias identifier = type;
@@ -5032,7 +5026,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                 stc = STC.ref_;
                 nextToken();
             }
-            if (token.value != TOK.leftParenthesis && token.value != TOK.leftCurly)
+            if (token.value != TOK.leftParenthesis && token.value != TOK.leftCurly &&
+                token.value != TOK.goesTo)
             {
                 // function type (parameters) { statements... }
                 // delegate type (parameters) { statements... }
@@ -5331,7 +5326,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                         error("cannot use function constraints for non-template functions. Use `static if` instead");
                 }
                 else
-                    error("semicolon expected following function declaration");
+                    error("semicolon expected following function declaration, not `%s`", token.toChars());
             }
             break;
         }
@@ -7081,7 +7076,7 @@ LagainStc:
 
     private void checkParens(TOK value, AST.Expression e)
     {
-        if (precedence[e.op] == PREC.rel && !e.parens)
+        if (precedence[e.op] == PREC.rel)
             error(e.loc, "`%s` must be surrounded by parentheses when next to operator `%s`", e.toChars(), Token.toChars(value));
     }
 
@@ -8485,7 +8480,6 @@ LagainStc:
                 // ( expression )
                 nextToken();
                 e = parseExpression();
-                e.parens = true;
                 check(loc, TOK.rightParenthesis);
                 break;
             }
@@ -8806,9 +8800,9 @@ LagainStc:
                                         nextToken();
                                         return AST.ErrorExp.get();
                                     }
-                                    e = new AST.TypeExp(loc, t);
-                                    e.parens = true;
-                                    e = parsePostExp(e);
+                                    auto te = new AST.TypeExp(loc, t);
+                                    te.parens = true;
+                                    e = parsePostExp(te);
                                 }
                                 else
                                 {
@@ -9115,14 +9109,18 @@ LagainStc:
     private AST.Expression parseAndExp()
     {
         Loc loc = token.loc;
+        bool parens = token.value == TOK.leftParenthesis;
         auto e = parseCmpExp();
         while (token.value == TOK.and)
         {
-            checkParens(TOK.and, e);
-            nextToken();
+            if (!parens)
+                checkParens(TOK.and, e);
+            parens = nextToken() == TOK.leftParenthesis;
             auto e2 = parseCmpExp();
-            checkParens(TOK.and, e2);
+            if (!parens)
+                checkParens(TOK.and, e2);
             e = new AST.AndExp(loc, e, e2);
+            parens = true;              // don't call checkParens() for And
             loc = token.loc;
         }
         return e;
@@ -9130,32 +9128,42 @@ LagainStc:
 
     private AST.Expression parseXorExp()
     {
-        const loc = token.loc;
+        Loc loc = token.loc;
 
+        bool parens = token.value == TOK.leftParenthesis;
         auto e = parseAndExp();
         while (token.value == TOK.xor)
         {
-            checkParens(TOK.xor, e);
-            nextToken();
+            if (!parens)
+                checkParens(TOK.xor, e);
+            parens = nextToken() == TOK.leftParenthesis;
             auto e2 = parseAndExp();
-            checkParens(TOK.xor, e2);
+            if (!parens)
+                checkParens(TOK.xor, e2);
             e = new AST.XorExp(loc, e, e2);
+            parens = true;
+            loc = token.loc;
         }
         return e;
     }
 
     private AST.Expression parseOrExp()
     {
-        const loc = token.loc;
+        Loc loc = token.loc;
 
+        bool parens = token.value == TOK.leftParenthesis;
         auto e = parseXorExp();
         while (token.value == TOK.or)
         {
-            checkParens(TOK.or, e);
-            nextToken();
+            if (!parens)
+                checkParens(TOK.or, e);
+            parens = nextToken() == TOK.leftParenthesis;
             auto e2 = parseXorExp();
-            checkParens(TOK.or, e2);
+            if (!parens)
+                checkParens(TOK.or, e2);
             e = new AST.OrExp(loc, e, e2);
+            parens = true;
+            loc = token.loc;
         }
         return e;
     }
@@ -9206,6 +9214,7 @@ LagainStc:
 
     AST.Expression parseAssignExp()
     {
+        bool parens = token.value == TOK.leftParenthesis;
         AST.Expression e;
         e = parseCondExp();
         if (e is null)
@@ -9214,7 +9223,7 @@ LagainStc:
         // require parens for e.g. `t ? a = 1 : b = 2`
         void checkRequiredParens()
         {
-            if (e.op == EXP.question && !e.parens)
+            if (e.op == EXP.question && !parens)
                 eSink.error(e.loc, "`%s` must be surrounded by parentheses when next to operator `%s`",
                     e.toChars(), Token.toChars(token.value));
         }
diff --git a/gcc/d/dmd/apply.d b/gcc/d/dmd/postordervisitor.d
similarity index 77%
rename from gcc/d/dmd/apply.d
rename to gcc/d/dmd/postordervisitor.d
index d18b81f044f..a0c71150c0f 100644
--- a/gcc/d/dmd/apply.d
+++ b/gcc/d/dmd/postordervisitor.d
@@ -9,11 +9,9 @@
  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/apply.d
  */
 
-module dmd.apply;
+module dmd.postordervisitor;
 
 import dmd.arraytypes;
-import dmd.dsymbol;
-import dmd.dsymbolsem;
 import dmd.dtemplate;
 import dmd.expression;
 import dmd.root.array;
@@ -26,39 +24,6 @@ bool walkPostorder(Expression e, StoppableVisitor v)
     return v.stop;
 }
 
-/*********************************
- * Iterate this dsymbol or members of this scoped dsymbol, then
- * call `fp` with the found symbol and `params`.
- * Params:
- *  symbol = the dsymbol or parent of members to call fp on
- *  fp = function pointer to process the iterated symbol.
- *       If it returns nonzero, the iteration will be aborted.
- *  params = any parameters passed to fp.
- * Returns:
- *  nonzero if the iteration is aborted by the return value of fp,
- *  or 0 if it's completed.
- */
-int apply(FP, Params...)(Dsymbol symbol, FP fp, Params params)
-{
-    if (auto nd = symbol.isNspace())
-    {
-        return nd.members.foreachDsymbol( (s) { return s && s.apply(fp, params); } );
-    }
-    if (auto ad = symbol.isAttribDeclaration())
-    {
-        return ad.include(ad._scope).foreachDsymbol( (s) { return s && s.apply(fp, params); } );
-    }
-    if (auto tm = symbol.isTemplateMixin())
-    {
-        if (tm._scope) // if fwd reference
-            dsymbolSemantic(tm, null); // try to resolve it
-
-        return tm.members.foreachDsymbol( (s) { return s && s.apply(fp, params); } );
-    }
-
-    return fp(symbol, params);
-}
-
 /**************************************
  * An Expression tree walker that will visit each Expression e in the tree,
  * in depth-first evaluation order, and call fp(e,param) on it.
diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d
index ee268d95251..c40e72c0862 100644
--- a/gcc/d/dmd/semantic2.d
+++ b/gcc/d/dmd/semantic2.d
@@ -447,14 +447,12 @@ private extern(C++) final class Semantic2Visitor : Visitor
                 const sameParams = tf1.parameterList == tf2.parameterList;
 
                 // Allow the hack to declare overloads with different parameters/STC's
-                // @@@DEPRECATED_2.104@@@
-                // Deprecated in 2020-08, make this an error in 2.104
                 if (parent1.isModule() &&
                     linkage1 != LINK.d && linkage1 != LINK.cpp &&
                     (!sameAttr || !sameParams)
                 )
                 {
-                    f2.deprecation("cannot overload `extern(%s)` function at %s",
+                    f2.error("cannot overload `extern(%s)` function at %s",
                             linkageToChars(f1._linkage),
                             f1.loc.toChars());
                     return 0;
diff --git a/gcc/d/dmd/sideeffect.d b/gcc/d/dmd/sideeffect.d
index 3f3e7e6377a..90b86df0418 100644
--- a/gcc/d/dmd/sideeffect.d
+++ b/gcc/d/dmd/sideeffect.d
@@ -11,7 +11,6 @@
 
 module dmd.sideeffect;
 
-import dmd.apply;
 import dmd.astenums;
 import dmd.declaration;
 import dmd.dscope;
@@ -22,6 +21,7 @@ import dmd.globals;
 import dmd.identifier;
 import dmd.init;
 import dmd.mtype;
+import dmd.postordervisitor;
 import dmd.tokens;
 import dmd.visitor;
 
@@ -101,9 +101,11 @@ extern (C++) bool hasSideEffect(Expression e, bool assumeImpureCalls = false)
 int callSideEffectLevel(FuncDeclaration f)
 {
     /* https://issues.dlang.org/show_bug.cgi?id=12760
-     * ctor call always has side effects.
+     * https://issues.dlang.org/show_bug.cgi?id=16384
+     *
+     * ctor calls and invariant calls always have side effects
      */
-    if (f.isCtorDeclaration())
+    if (f.isCtorDeclaration() || f.isInvariantDeclaration())
         return 0;
     assert(f.type.ty == Tfunction);
     TypeFunction tf = cast(TypeFunction)f.type;
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index f849ce1f69a..f0454163224 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -1273,8 +1273,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
                 }
                 else if (auto td = sfront.isTemplateDeclaration())
                 {
-                    Expressions a;
-                    if (auto f = resolveFuncCall(loc, sc, td, null, tab, ArgumentList(&a), FuncResolveFlag.quiet))
+                    if (auto f = resolveFuncCall(loc, sc, td, null, tab, ArgumentList(), FuncResolveFlag.quiet))
                         tfront = f.type;
                 }
                 else if (auto d = sfront.toAlias().isDeclaration())
@@ -2733,7 +2732,8 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
                 tbret = tret.toBasetype();
             }
 
-            if (inferRef) // deduce 'auto ref'
+            // https://issues.dlang.org/show_bug.cgi?id=23914
+            if (inferRef && !resType.isTypeNoreturn()) // deduce 'auto ref'
                 tf.isref = false;
 
             if (tbret.ty != Tvoid && !resType.isTypeNoreturn()) // if non-void return
@@ -3593,6 +3593,11 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
             cas.error("`asm` statement is assumed to be impure - mark it with `pure` if it is not");
         if (!(cas.stc & STC.nogc) && sc.func.setGC(cas.loc, "`asm` statement in %s `%s` is assumed to use the GC - mark it with `@nogc` if it does not"))
             cas.error("`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not");
+        // @@@DEPRECATED_2.114@@@
+        // change deprecation() to error(), add `else` and remove `| STC.safe`
+        // to turn deprecation into an error when deprecation cycle is over
+        if (cas.stc & STC.safe)
+            cas.deprecation("`asm` statement cannot be marked `@safe`, use `@system` or `@trusted` instead");
         if (!(cas.stc & (STC.trusted | STC.safe)))
         {
             sc.setUnsafe(false, cas.loc, "`asm` statement is assumed to be `@system` - mark it with `@trusted` if it is not");
@@ -4045,6 +4050,13 @@ void catchSemantic(Catch c, Scope* sc)
         // reference .object.Throwable
         c.type = getThrowable();
     }
+    else if (!c.type.isNaked() && !c.type.isConst())
+    {
+        // @@@DEPRECATED_2.113@@@
+        // Deprecated in 2.103, change into an error & uncomment in 2.113
+        deprecation(c.loc, "can only catch mutable or const qualified types, not `%s`", c.type.toChars());
+        //c.errors = true;
+    }
     c.type = c.type.typeSemantic(c.loc, sc);
     if (c.type == Type.terror)
     {
diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d
index 352c89ef164..58717625cac 100644
--- a/gcc/d/dmd/tokens.d
+++ b/gcc/d/dmd/tokens.d
@@ -593,7 +593,7 @@ shared static this() nothrow
     foreach (kw; keywords)
     {
         //printf("keyword[%d] = '%s'\n",kw, Token.tochars[kw].ptr);
-        Identifier.idPool(Token.tochars[kw].ptr, Token.tochars[kw].length, cast(uint)kw);
+        Identifier.idPool(Token.tochars[kw], kw);
     }
 }
 
diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d
index 0f363536d8e..53c8fb08b50 100644
--- a/gcc/d/dmd/traits.d
+++ b/gcc/d/dmd/traits.d
@@ -1215,7 +1215,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
             {
                 if (fd.overnext)
                 {
-                    deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `%s`", fd.toChars());
+                    deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not the overload set `%s`", fd.toChars());
                     deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from");
                 }
             }
@@ -1225,7 +1225,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
             {
                 if (td.overnext || td.funcroot)
                 {
-                    deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `%s`", td.ident.toChars());
+                    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/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d
index c58827063d2..a82a268eb66 100644
--- a/gcc/d/dmd/transitivevisitor.d
+++ b/gcc/d/dmd/transitivevisitor.d
@@ -161,6 +161,16 @@ package mixin template ParseVisitMethods(AST)
             s._body.accept(this);
     }
 
+    override void visit(AST.StaticForeachStatement s)
+	{
+        // printf("Visiting StaticForeachStatement\n");
+		if (s.sfe.aggrfe)
+            s.sfe.aggrfe.accept(this);
+
+		if (s.sfe.rangefe)
+            s.sfe.rangefe.accept(this);
+	}
+
     override void visit(AST.IfStatement s)
     {
         //printf("Visiting IfStatement\n");
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index f0decf2a48d..09eef83ba08 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -163,7 +163,7 @@ private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb
         /* Look for what user might have intended
          */
         const p = mt.mutableOf().unSharedOf().toChars();
-        auto id = Identifier.idPool(p, cast(uint)strlen(p));
+        auto id = Identifier.idPool(p[0 .. strlen(p)]);
         if (const n = importHint(id.toString()))
             error(loc, "`%s` is not defined, perhaps `import %.*s;` ?", p, cast(int)n.length, n.ptr);
         else if (auto s2 = sc.search_correct(id))
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 23f2f0b1c8d..8fb1eea65a6 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -2296,11 +2296,12 @@ public:
 	    return;
 	  }
 
+	/* This case should have been rewritten to `_d_newitemT' during the
+	   semantic phase.  */
+	gcc_assert (e->lowering);
+
 	/* Generate: _d_newitemT()  */
-	libcall_fn libcall = htype->isZeroInit ()
-	  ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
-	tree arg = build_typeinfo (e, e->newtype);
-	new_call = build_libcall (libcall, tb, 1, arg);
+	new_call = build_expr (e->lowering);
 
 	if (e->member || !e->arguments)
 	  {
@@ -2423,11 +2424,12 @@ public:
 	    return;
 	  }
 
-	libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
-	  ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
+	/* This case should have been rewritten to `_d_newitemT' during the
+	   semantic phase.  */
+	gcc_assert (e->lowering);
 
-	tree arg = build_typeinfo (e, e->newtype);
-	result = build_libcall (libcall, tb, 1, arg);
+	/* Generate: _d_newitemT()  */
+	result = build_expr (e->lowering);
 
 	if (e->arguments && e->arguments->length == 1)
 	  {
diff --git a/gcc/d/runtime.def b/gcc/d/runtime.def
index fd83cc9748c..4d1ba09f1a7 100644
--- a/gcc/d/runtime.def
+++ b/gcc/d/runtime.def
@@ -70,11 +70,6 @@ DEF_D_RUNTIME (DYNAMIC_CAST, "_d_dynamic_cast", RT(OBJECT),
 DEF_D_RUNTIME (INTERFACE_CAST, "_d_interface_cast", RT(OBJECT),
 	       P2(OBJECT, CLASSINFO), 0)
 
-/* Used when calling new on a pointer.  The `i' variant is for when the
-   initializer is nonzero.  */
-DEF_D_RUNTIME (NEWITEMT, "_d_newitemT", RT(VOIDPTR), P1(CONST_TYPEINFO), 0)
-DEF_D_RUNTIME (NEWITEMIT, "_d_newitemiT", RT(VOIDPTR), P1(CONST_TYPEINFO), 0)
-
 /* Used when calling new on an array.  The `i' variant is for when the
    initializer is nonzero, and the `m' variant is when initializing a
    multi-dimensional array.  */
diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc
index 8bd6eb63d51..db6f71babda 100644
--- a/gcc/d/toir.cc
+++ b/gcc/d/toir.cc
@@ -780,8 +780,8 @@ public:
 
     this->do_label (label);
 
-    if (this->is_return_label (s->ident) && this->func_->fensure != NULL)
-      this->build_stmt (this->func_->fensure);
+    if (this->is_return_label (s->ident) && this->func_->fensure () != NULL)
+      this->build_stmt (this->func_->fensure ());
     else if (s->statement)
       this->build_stmt (s->statement);
   }
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index 1c5e50c03c0..bf174383615 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -1421,7 +1421,7 @@ check_typeinfo_type (const Loc &loc, Scope *sc, Expression *expr)
       /* If TypeInfo has not been declared, warn about each location once.  */
       static Loc warnloc;
 
-      if (loc.filename && !warnloc.equals (loc))
+      if (loc.filename () && !warnloc.equals (loc))
 	{
 	  error_at (make_location_t (loc),
 		    "%<object.TypeInfo%> could not be found, "
diff --git a/gcc/testsuite/gdc.dg/asm4.d b/gcc/testsuite/gdc.dg/asm4.d
index e243c0820ac..db857af7e36 100644
--- a/gcc/testsuite/gdc.dg/asm4.d
+++ b/gcc/testsuite/gdc.dg/asm4.d
@@ -6,7 +6,7 @@ module asm4;
 void test1()
 {
     asm pure nothrow @nogc @trusted {}
-    asm @safe {}
+    asm @system {}
 }
 
 void test2() pure nothrow @nogc @safe
diff --git a/gcc/testsuite/gdc.test/compilable/aliasdecl.d b/gcc/testsuite/gdc.test/compilable/aliasdecl.d
index 5bacbc62347..74a674d43a9 100644
--- a/gcc/testsuite/gdc.test/compilable/aliasdecl.d
+++ b/gcc/testsuite/gdc.test/compilable/aliasdecl.d
@@ -36,12 +36,12 @@ void main()
         enum a = 1;
     }
 
- /+ struct S
+    struct S2
     {
         int value;
         alias this = value;
     }
-    auto s = S(10);
+    auto s = S2(10);
     int n = s;
-    assert(n == 10); +/
+    assert(n == 10);
 }
diff --git a/gcc/testsuite/gdc.test/compilable/atomic_store_2_shared_classes.d b/gcc/testsuite/gdc.test/compilable/atomic_store_2_shared_classes.d
new file mode 100644
index 00000000000..0d8cd748937
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/atomic_store_2_shared_classes.d
@@ -0,0 +1,13 @@
+// REQUIRED_ARGS: -preview=nosharedaccess
+import core.atomic;
+
+class Foo
+{
+}
+
+void oops()
+{
+    auto f0 = new shared Foo;
+    auto f1 = new shared Foo;
+    atomicStore(f0, f1);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/imports/library.c b/gcc/testsuite/gdc.test/compilable/imports/library.c
new file mode 100644
index 00000000000..4951e465574
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/library.c
@@ -0,0 +1,5 @@
+typedef enum SomeEnum
+{
+    foo = 0,
+    bar = -10000,
+} SomeEnum;
diff --git a/gcc/testsuite/gdc.test/compilable/noreturn3.d b/gcc/testsuite/gdc.test/compilable/noreturn3.d
index 69689d24d85..2538a0d0231 100644
--- a/gcc/testsuite/gdc.test/compilable/noreturn3.d
+++ b/gcc/testsuite/gdc.test/compilable/noreturn3.d
@@ -91,8 +91,8 @@ auto ref forwardOrExit(ref int num)
 
 static assert( is(typeof(forwardOrExit(global)) == int));
 
-// // Must not infer ref due to the noreturn rvalue
-static assert(!is(typeof(&forwardOrExit(global))));
+// Noreturn types do not affect `auto ref` deduction
+static assert(is(typeof(&forwardOrExit(global))));
 
 auto ref forwardOrExit2(ref int num)
 {
@@ -104,8 +104,8 @@ auto ref forwardOrExit2(ref int num)
 
 static assert( is(typeof(forwardOrExit2(global)) == int));
 
-// // Must not infer ref due to the noreturn rvalue
-static assert(!is(typeof(&forwardOrExit2(global))));
+// Noreturn types do not affect `auto ref` deduction
+static assert(is(typeof(&forwardOrExit2(global))));
 
 /*****************************************************************************/
 
diff --git a/gcc/testsuite/gdc.test/compilable/test22760.d b/gcc/testsuite/gdc.test/compilable/test22760.d
new file mode 100644
index 00000000000..5957db3256c
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22760.d
@@ -0,0 +1,15 @@
+// https://issues.dlang.org/show_bug.cgi?id=22760
+
+extern(C++) void f(T)(T)
+{
+}
+struct S1(T)
+{
+    struct S2
+    {
+    }
+}
+void fun()
+{
+    f(S1!int.S2());
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23874.d b/gcc/testsuite/gdc.test/compilable/test23874.d
new file mode 100644
index 00000000000..81ee9d59ec2
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23874.d
@@ -0,0 +1,10 @@
+// https://issues.dlang.org/show_bug.cgi?id=23874
+// REQUIRED_ARGS: -profile=gc
+
+string myToString()
+{
+    return "";
+}
+
+enum x = myToString ~ "";
+immutable x2 = myToString ~ "";
diff --git a/gcc/testsuite/gdc.test/compilable/test23912.d b/gcc/testsuite/gdc.test/compilable/test23912.d
new file mode 100644
index 00000000000..d89d3026e8f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23912.d
@@ -0,0 +1,17 @@
+// https://issues.dlang.org/show_bug.cgi?id=23912
+// REQUIRED_ARGS: -preview=dip1000
+
+struct Test
+{
+    string val;
+
+    this(return scope string val) scope @safe {}
+    ~this() scope @safe {}
+}
+
+void giver(scope string input) @safe
+{
+    accepts(Test(input));
+}
+
+void accepts(scope Test test) @safe {}
diff --git a/gcc/testsuite/gdc.test/compilable/test23913.d b/gcc/testsuite/gdc.test/compilable/test23913.d
new file mode 100644
index 00000000000..e39c6dec317
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23913.d
@@ -0,0 +1,7 @@
+// EXTRA_FILES: imports/library.c
+
+// https://issues.dlang.org/show_bug.cgi?id=23913
+
+import imports.library;
+
+alias x = __traits(getMember, imports.library, "SomeEnum");
diff --git a/gcc/testsuite/gdc.test/compilable/test23948.d b/gcc/testsuite/gdc.test/compilable/test23948.d
new file mode 100644
index 00000000000..4f7b8da093a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23948.d
@@ -0,0 +1,29 @@
+// https://issues.dlang.org/show_bug.cgi?id=23948
+
+void foo1(const(char)* fun = __FILE__)() {
+
+}
+
+void foo2(const(char)* fun = __FILE_FULL_PATH__)() {
+
+}
+
+void foo3(const(char)* fun = __MODULE__)() {
+
+}
+
+void foo4(const(char)* fun = __FUNCTION__)() {
+
+}
+
+void foo5(const(char)* fun = __PRETTY_FUNCTION__)() {
+
+}
+
+void main() {
+    foo1();
+    foo2();
+    foo3();
+    foo4();
+    foo5();
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d
index 802d1c2983e..f0a9456035b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d
@@ -91,9 +91,9 @@ TEST_OUTPUT:
 ---
 fail_compilation/bug9631.d(106): Error: function `bug9631.targ.ft!().ft(S __param_0)` is not callable using argument types `(S)`
 fail_compilation/bug9631.d(106):        cannot pass argument `x` of type `bug9631.S` to parameter `bug9631.tem!().S __param_0`
-fail_compilation/bug9631.d(107): Error: none of the overloads of template `bug9631.targ.ft` are callable using argument types `!()(S)`
+fail_compilation/bug9631.d(107): Error: template `bug9631.targ.ft` is not callable using argument types `!()(S)`
 fail_compilation/bug9631.d(105):        Candidate is: `ft()(tem!().S)`
-fail_compilation/bug9631.d(109): Error: none of the overloads of template `bug9631.targ.ft2` are callable using argument types `!()(S, int)`
+fail_compilation/bug9631.d(109): Error: template `bug9631.targ.ft2` is not callable using argument types `!()(S, int)`
 fail_compilation/bug9631.d(108):        Candidate is: `ft2(T)(S, T)`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/chkformat.d b/gcc/testsuite/gdc.test/fail_compilation/chkformat.d
index fa8915e5fa9..eb75f4267b9 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/chkformat.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/chkformat.d
@@ -19,7 +19,11 @@ fail_compilation/chkformat.d(115): Deprecation: argument `& u` for format specif
 fail_compilation/chkformat.d(116): Deprecation: argument `16L` for format specification `"%c"` must be `char`, not `long`
 fail_compilation/chkformat.d(117): Deprecation: argument `17L` for format specification `"%c"` must be `char`, not `long`
 fail_compilation/chkformat.d(118): Deprecation: argument `& u` for format specification `"%s"` must be `char*`, not `int*`
-fail_compilation/chkformat.d(119): Deprecation: argument `& u` for format specification `"%ls"` must be `wchar_t*`, not `int*`
+fail_compilation/chkformat.d(119): Deprecation: argument `& u` for format specification `"%ls"` must be `wchar_t*`, not `int*`$?:windows=
+fail_compilation/chkformat.d(122): Deprecation: argument `0LU` for format specification `"%lu"` must be `uint`, not `ulong`
+fail_compilation/chkformat.d(122):        C `long` is 4 bytes on your system|32=
+fail_compilation/chkformat.d(122): Deprecation: argument `0LU` for format specification `"%lu"` must be `uint`, not `ulong`
+fail_compilation/chkformat.d(122):        C `long` is 4 bytes on your system$
 fail_compilation/chkformat.d(201): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long`
 fail_compilation/chkformat.d(202): Deprecation: more format specifiers than 1 arguments
 fail_compilation/chkformat.d(203): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long`
@@ -81,6 +85,7 @@ void test18() { int u; printf("%s\n", &u); }
 void test19() { int u; printf("%ls\n", &u); }
 //void test20() { int u; char[] s; sprintf(&s[0], "%d\n", &u); }
 //void test21() { int u; fprintf(null, "%d\n", &u); }
+void test20() { printf("%lu", ulong.init); }
 
 #line 200
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d
index 9f12ae69835..a3ad34a0ea3 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d
@@ -2,12 +2,12 @@
 EXTRA_FILES: imports/constraints.d
 TEST_OUTPUT:
 ---
-fail_compilation/constraints_aggr.d(32): Error: none of the overloads of template `imports.constraints.C.f` are callable using argument types `!()(int)`
+fail_compilation/constraints_aggr.d(32): Error: template `imports.constraints.C.f` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(60):        Candidate is: `f(T)(T v)`
   with `T = int`
   must satisfy the following constraint:
 `       !P!T`
-fail_compilation/constraints_aggr.d(33): Error: none of the overloads of template `imports.constraints.C.g` are callable using argument types `!()()`
+fail_compilation/constraints_aggr.d(33): Error: template `imports.constraints.C.g` is not callable using argument types `!()()`
 fail_compilation/imports/constraints.d(63):        Candidate is: `g(this T)()`
   with `T = imports.constraints.C`
   must satisfy the following constraint:
diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d
index aac87601eb9..fbb4aa94d53 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d
@@ -2,72 +2,72 @@
 EXTRA_FILES: imports/constraints.d
 TEST_OUTPUT:
 ---
-fail_compilation/constraints_func1.d(79): Error: none of the overloads of template `imports.constraints.test1` are callable using argument types `!()(int)`
+fail_compilation/constraints_func1.d(79): Error: template `imports.constraints.test1` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(9):        Candidate is: `test1(T)(T v)`
   with `T = int`
   must satisfy the following constraint:
 `       N!T`
-fail_compilation/constraints_func1.d(80): Error: none of the overloads of template `imports.constraints.test2` are callable using argument types `!()(int)`
+fail_compilation/constraints_func1.d(80): Error: template `imports.constraints.test2` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(10):        Candidate is: `test2(T)(T v)`
   with `T = int`
   must satisfy the following constraint:
 `       !P!T`
-fail_compilation/constraints_func1.d(81): Error: none of the overloads of template `imports.constraints.test3` are callable using argument types `!()(int)`
+fail_compilation/constraints_func1.d(81): Error: template `imports.constraints.test3` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(11):        Candidate is: `test3(T)(T v)`
   with `T = int`
   must satisfy the following constraint:
 `       N!T`
-fail_compilation/constraints_func1.d(82): Error: none of the overloads of template `imports.constraints.test4` are callable using argument types `!()(int)`
+fail_compilation/constraints_func1.d(82): Error: template `imports.constraints.test4` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(12):        Candidate is: `test4(T)(T v)`
   with `T = int`
   must satisfy the following constraint:
 `       N!T`
-fail_compilation/constraints_func1.d(83): Error: none of the overloads of template `imports.constraints.test5` are callable using argument types `!()(int)`
+fail_compilation/constraints_func1.d(83): Error: template `imports.constraints.test5` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(13):        Candidate is: `test5(T)(T v)`
   with `T = int`
   must satisfy one of the following constraints:
 `       N!T
        N!T`
-fail_compilation/constraints_func1.d(84): Error: none of the overloads of template `imports.constraints.test6` are callable using argument types `!()(int)`
+fail_compilation/constraints_func1.d(84): Error: template `imports.constraints.test6` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(14):        Candidate is: `test6(T)(T v)`
   with `T = int`
   must satisfy one of the following constraints:
 `       N!T
        N!T
        !P!T`
-fail_compilation/constraints_func1.d(85): Error: none of the overloads of template `imports.constraints.test7` are callable using argument types `!()(int)`
+fail_compilation/constraints_func1.d(85): Error: template `imports.constraints.test7` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(15):        Candidate is: `test7(T)(T v)`
   with `T = int`
   must satisfy one of the following constraints:
 `       N!T
        N!T`
-fail_compilation/constraints_func1.d(86): Error: none of the overloads of template `imports.constraints.test8` are callable using argument types `!()(int)`
+fail_compilation/constraints_func1.d(86): Error: template `imports.constraints.test8` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(16):        Candidate is: `test8(T)(T v)`
   with `T = int`
   must satisfy the following constraint:
 `       N!T`
-fail_compilation/constraints_func1.d(87): Error: none of the overloads of template `imports.constraints.test9` are callable using argument types `!()(int)`
+fail_compilation/constraints_func1.d(87): Error: template `imports.constraints.test9` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(17):        Candidate is: `test9(T)(T v)`
   with `T = int`
   must satisfy the following constraint:
 `       !P!T`
-fail_compilation/constraints_func1.d(88): Error: none of the overloads of template `imports.constraints.test10` are callable using argument types `!()(int)`
+fail_compilation/constraints_func1.d(88): Error: template `imports.constraints.test10` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(18):        Candidate is: `test10(T)(T v)`
   with `T = int`
   must satisfy the following constraint:
 `       !P!T`
-fail_compilation/constraints_func1.d(89): Error: none of the overloads of template `imports.constraints.test11` are callable using argument types `!()(int)`
+fail_compilation/constraints_func1.d(89): Error: template `imports.constraints.test11` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(19):        Candidate is: `test11(T)(T v)`
   with `T = int`
   must satisfy one of the following constraints:
 `       N!T
        !P!T`
-fail_compilation/constraints_func1.d(90): Error: none of the overloads of template `imports.constraints.test12` are callable using argument types `!()(int)`
+fail_compilation/constraints_func1.d(90): Error: template `imports.constraints.test12` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(20):        Candidate is: `test12(T)(T v)`
   with `T = int`
   must satisfy the following constraint:
 `       !P!T`
-fail_compilation/constraints_func1.d(92): Error: none of the overloads of template `imports.constraints.test1` are callable using argument types `!()(int, int)`
+fail_compilation/constraints_func1.d(92): Error: template `imports.constraints.test1` is not callable using argument types `!()(int, int)`
 fail_compilation/imports/constraints.d(9):        Candidate is: `test1(T)(T v)`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d
index a20426d35dc..4b8ebd5da2b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d
@@ -2,83 +2,83 @@
 EXTRA_FILES: imports/constraints.d
 TEST_OUTPUT:
 ---
-fail_compilation/constraints_func2.d(94): Error: none of the overloads of template `imports.constraints.test13` are callable using argument types `!()(int)`
+fail_compilation/constraints_func2.d(94): Error: template `imports.constraints.test13` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(23):        Candidate is: `test13(T)(T v)`
   with `T = int`
   must satisfy one of the following constraints:
 `       N!T
        !P!T`
-fail_compilation/constraints_func2.d(95): Error: none of the overloads of template `imports.constraints.test14` are callable using argument types `!()(int)`
+fail_compilation/constraints_func2.d(95): Error: template `imports.constraints.test14` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(24):        Candidate is: `test14(T)(T v)`
   with `T = int`
   must satisfy one of the following constraints:
 `       !P!T
        N!T`
-fail_compilation/constraints_func2.d(96): Error: none of the overloads of template `imports.constraints.test15` are callable using argument types `!()(int)`
+fail_compilation/constraints_func2.d(96): Error: template `imports.constraints.test15` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(25):        Candidate is: `test15(T)(T v)`
   with `T = int`
   must satisfy one of the following constraints:
 `       !P!T
        !P!T`
-fail_compilation/constraints_func2.d(97): Error: none of the overloads of template `imports.constraints.test16` are callable using argument types `!()(int)`
+fail_compilation/constraints_func2.d(97): Error: template `imports.constraints.test16` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(26):        Candidate is: `test16(T)(T v)`
   with `T = int`
   must satisfy one of the following constraints:
 `       N!T
        N!T`
-fail_compilation/constraints_func2.d(98): Error: none of the overloads of template `imports.constraints.test17` are callable using argument types `!()(int)`
+fail_compilation/constraints_func2.d(98): Error: template `imports.constraints.test17` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(27):        Candidate is: `test17(T)(T v)`
   with `T = int`
   must satisfy the following constraint:
 `       N!T`
-fail_compilation/constraints_func2.d(99): Error: none of the overloads of template `imports.constraints.test18` are callable using argument types `!()(int)`
+fail_compilation/constraints_func2.d(99): Error: template `imports.constraints.test18` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(28):        Candidate is: `test18(T)(T v)`
   with `T = int`
   must satisfy one of the following constraints:
 `       N!T
        N!T`
-fail_compilation/constraints_func2.d(100): Error: none of the overloads of template `imports.constraints.test19` are callable using argument types `!()(int)`
+fail_compilation/constraints_func2.d(100): Error: template `imports.constraints.test19` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(29):        Candidate is: `test19(T)(T v)`
   with `T = int`
   must satisfy one of the following constraints:
 `       N!T
        !P!T
        N!T`
-fail_compilation/constraints_func2.d(101): Error: none of the overloads of template `imports.constraints.test20` are callable using argument types `!()(int)`
+fail_compilation/constraints_func2.d(101): Error: template `imports.constraints.test20` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(30):        Candidate is: `test20(T)(T v)`
   with `T = int`
   must satisfy the following constraint:
 `       N!T`
-fail_compilation/constraints_func2.d(102): Error: none of the overloads of template `imports.constraints.test21` are callable using argument types `!()(int)`
+fail_compilation/constraints_func2.d(102): Error: template `imports.constraints.test21` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(31):        Candidate is: `test21(T)(T v)`
   with `T = int`
   must satisfy one of the following constraints:
 `       N!T
        N!T`
-fail_compilation/constraints_func2.d(103): Error: none of the overloads of template `imports.constraints.test22` are callable using argument types `!()(int)`
+fail_compilation/constraints_func2.d(103): Error: template `imports.constraints.test22` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(32):        Candidate is: `test22(T)(T v)`
   with `T = int`
   must satisfy one of the following constraints:
 `       !P!T
        !P!T`
-fail_compilation/constraints_func2.d(104): Error: none of the overloads of template `imports.constraints.test23` are callable using argument types `!()(int)`
+fail_compilation/constraints_func2.d(104): Error: template `imports.constraints.test23` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(33):        Candidate is: `test23(T)(T v)`
   with `T = int`
   must satisfy one of the following constraints:
 `       !P!T
        N!T
        !P!T`
-fail_compilation/constraints_func2.d(105): Error: none of the overloads of template `imports.constraints.test24` are callable using argument types `!()(int)`
+fail_compilation/constraints_func2.d(105): Error: template `imports.constraints.test24` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(34):        Candidate is: `test24(R)(R r)`
   with `R = int`
   must satisfy the following constraint:
 `       __traits(hasMember, R, "stuff")`
-fail_compilation/constraints_func2.d(106): Error: none of the overloads of template `imports.constraints.test25` are callable using argument types `!()(int)`
+fail_compilation/constraints_func2.d(106): Error: template `imports.constraints.test25` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(35):        Candidate is: `test25(T)(T v)`
   with `T = int`
   must satisfy the following constraint:
 `       N!T`
-fail_compilation/constraints_func2.d(107): Error: none of the overloads of template `imports.constraints.test26` are callable using argument types `!(float)(int)`
+fail_compilation/constraints_func2.d(107): Error: template `imports.constraints.test26` is not callable using argument types `!(float)(int)`
 fail_compilation/imports/constraints.d(36):        Candidate is: `test26(T, U)(U u)`
   with `T = float,
        U = int`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d
index 6f214b9f07e..d16bdf0959c 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d
@@ -23,21 +23,21 @@ fail_compilation/imports/constraints.d(42):                        `overload(T,
   must satisfy one of the following constraints:
 `       N!T
        N!V`
-fail_compilation/constraints_func3.d(56): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()()`
+fail_compilation/constraints_func3.d(56): Error: template `imports.constraints.variadic` is not callable using argument types `!()()`
 fail_compilation/imports/constraints.d(43):        Candidate is: `variadic(A, T...)(A a, T v)`
-fail_compilation/constraints_func3.d(57): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int)`
+fail_compilation/constraints_func3.d(57): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int)`
 fail_compilation/imports/constraints.d(43):        Candidate is: `variadic(A, T...)(A a, T v)`
   with `A = int,
        T = ()`
   must satisfy the following constraint:
 `       N!int`
-fail_compilation/constraints_func3.d(58): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int)`
+fail_compilation/constraints_func3.d(58): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int)`
 fail_compilation/imports/constraints.d(43):        Candidate is: `variadic(A, T...)(A a, T v)`
   with `A = int,
        T = (int)`
   must satisfy the following constraint:
 `       N!int`
-fail_compilation/constraints_func3.d(59): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int, int)`
+fail_compilation/constraints_func3.d(59): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int, int)`
 fail_compilation/imports/constraints.d(43):        Candidate is: `variadic(A, T...)(A a, T v)`
   with `A = int,
        T = (int, int)`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d
index 4048baed69c..c4dea0ec451 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d
@@ -44,13 +44,13 @@ fail_compilation/imports/constraints.d(42):                        `overload(T,
        N!V`
 void overload(T, V)(T v1, V v2) if (N!T || N!V);
      ^
-fail_compilation/constraints_func4.d(93): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()()`
+fail_compilation/constraints_func4.d(93): Error: template `imports.constraints.variadic` is not callable using argument types `!()()`
     variadic();
             ^
 fail_compilation/imports/constraints.d(43):        Candidate is: `variadic(A, T...)(A a, T v)`
 void variadic(A, T...)(A a, T v) if (N!int);
      ^
-fail_compilation/constraints_func4.d(94): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int)`
+fail_compilation/constraints_func4.d(94): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int)`
     variadic(0);
             ^
 fail_compilation/imports/constraints.d(43):        Candidate is: `variadic(A, T...)(A a, T v)`
@@ -60,7 +60,7 @@ fail_compilation/imports/constraints.d(43):        Candidate is: `variadic(A, T.
 `       N!int`
 void variadic(A, T...)(A a, T v) if (N!int);
      ^
-fail_compilation/constraints_func4.d(95): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int)`
+fail_compilation/constraints_func4.d(95): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int)`
     variadic(0, 1);
             ^
 fail_compilation/imports/constraints.d(43):        Candidate is: `variadic(A, T...)(A a, T v)`
@@ -70,7 +70,7 @@ fail_compilation/imports/constraints.d(43):        Candidate is: `variadic(A, T.
 `       N!int`
 void variadic(A, T...)(A a, T v) if (N!int);
      ^
-fail_compilation/constraints_func4.d(96): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int, int)`
+fail_compilation/constraints_func4.d(96): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int, int)`
     variadic(0, 1, 2);
             ^
 fail_compilation/imports/constraints.d(43):        Candidate is: `variadic(A, T...)(A a, T v)`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag13942.d b/gcc/testsuite/gdc.test/fail_compilation/diag13942.d
index aeee10749c1..25e0515a5bc 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag13942.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag13942.d
@@ -2,7 +2,7 @@
 TEST_OUTPUT:
 ---
 fail_compilation/diag13942.d(18): Error: template instance `isRawStaticArray!()` does not match template declaration `isRawStaticArray(T, A...)`
-fail_compilation/diag13942.d(26): Error: none of the overloads of template `diag13942.to!double.to` are callable using argument types `!()()`
+fail_compilation/diag13942.d(26): Error: template `diag13942.to!double.to` is not callable using argument types `!()()`
 fail_compilation/diag13942.d(17):        Candidate is: `to(A...)(A args)`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag16977.d b/gcc/testsuite/gdc.test/fail_compilation/diag16977.d
index 73d628584d5..fc8f66032e2 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag16977.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag16977.d
@@ -3,7 +3,7 @@ TEST_OUTPUT:
 ---
 fail_compilation/diag16977.d(25): Error: undefined identifier `undefined`, did you mean function `undefinedId`?
 fail_compilation/diag16977.d(26): Error: cannot implicitly convert expression `"\x01string"` of type `string` to `int`
-fail_compilation/diag16977.d(27): Error: none of the overloads of template `diag16977.templ` are callable using argument types `!()(int)`
+fail_compilation/diag16977.d(27): Error: template `diag16977.templ` is not callable using argument types `!()(int)`
 fail_compilation/diag16977.d(20):        Candidate is: `templ(S)(S s)`
   with `S = int`
   must satisfy the following constraint:
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag20268.d b/gcc/testsuite/gdc.test/fail_compilation/diag20268.d
index a314561892a..053626a603c 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag20268.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag20268.d
@@ -3,7 +3,7 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/diag20268.d(12): Error: none of the overloads of template `diag20268.__lambda4` are callable using argument types `!()(int)`
+fail_compilation/diag20268.d(12): Error: template `diag20268.__lambda4` is not callable using argument types `!()(int)`
 fail_compilation/diag20268.d(11):        Candidate is: `__lambda4(__T1, __T2)(x, y)`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag23355.d b/gcc/testsuite/gdc.test/fail_compilation/diag23355.d
index 586cbb0fce8..a530eb60ef0 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag23355.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag23355.d
@@ -2,10 +2,10 @@
 TEST_OUTPUT:
 ---
 fail_compilation/diag23355.d(1): Error: undefined identifier `n`
-fail_compilation/diag23355.d(4): Error: none of the overloads of template `diag23355.ffi1` are callable using argument types `!()(int[4])`
+fail_compilation/diag23355.d(4): Error: template `diag23355.ffi1` is not callable using argument types `!()(int[4])`
 fail_compilation/diag23355.d(1):        Candidate is: `ffi1(T)(T[n] s)`
 fail_compilation/diag23355.d(2): Error: undefined identifier `n`
-fail_compilation/diag23355.d(4): Error: none of the overloads of template `diag23355.ffi2` are callable using argument types `!()(int[4])`
+fail_compilation/diag23355.d(4): Error: template `diag23355.ffi2` is not callable using argument types `!()(int[4])`
 fail_compilation/diag23355.d(2):        Candidate is: `ffi2()(T[n] s)`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8101.d b/gcc/testsuite/gdc.test/fail_compilation/diag8101.d
index ddc74e28131..4c8dfe881ab 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag8101.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag8101.d
@@ -14,7 +14,7 @@ fail_compilation/diag8101.d(41):                        `diag8101.f_2(int, int,
 fail_compilation/diag8101.d(42):                        `diag8101.f_2(int, int, int, int, int)`
 fail_compilation/diag8101.d(43):                        `diag8101.f_2(int, int, int, int, int, int)`
 fail_compilation/diag8101.d(63):        ... (1 more, -v to show) ...
-fail_compilation/diag8101.d(65): Error: none of the overloads of template `diag8101.t_0` are callable using argument types `!()()`
+fail_compilation/diag8101.d(65): Error: template `diag8101.t_0` is not callable using argument types `!()()`
 fail_compilation/diag8101.d(46):        Candidate is: `t_0(T1)()`
 fail_compilation/diag8101.d(66): Error: none of the overloads of template `diag8101.t_1` are callable using argument types `!()()`
 fail_compilation/diag8101.d(48):        Candidates are: `t_1(T1)()`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8648.d b/gcc/testsuite/gdc.test/fail_compilation/diag8648.d
index a04ed7c0a42..e48f569b74d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag8648.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag8648.d
@@ -2,13 +2,13 @@
 TEST_OUTPUT:
 ---
 fail_compilation/diag8648.d(18): Error: undefined identifier `X`
-fail_compilation/diag8648.d(29): Error: none of the overloads of template `diag8648.foo` are callable using argument types `!()(Foo!(int, 1))`
+fail_compilation/diag8648.d(29): Error: template `diag8648.foo` is not callable using argument types `!()(Foo!(int, 1))`
 fail_compilation/diag8648.d(18):        Candidate is: `foo(T, n)(X!(T, n))`
 fail_compilation/diag8648.d(20): Error: undefined identifier `a`
-fail_compilation/diag8648.d(31): Error: none of the overloads of template `diag8648.bar` are callable using argument types `!()(Foo!(int, 1))`
+fail_compilation/diag8648.d(31): Error: template `diag8648.bar` is not callable using argument types `!()(Foo!(int, 1))`
 fail_compilation/diag8648.d(20):        Candidate is: `bar(T)(Foo!(T, a))`
 fail_compilation/diag8648.d(20): Error: undefined identifier `a`
-fail_compilation/diag8648.d(32): Error: none of the overloads of template `diag8648.bar` are callable using argument types `!()(Foo!(int, f))`
+fail_compilation/diag8648.d(32): Error: template `diag8648.bar` is not callable using argument types `!()(Foo!(int, f))`
 fail_compilation/diag8648.d(20):        Candidate is: `bar(T)(Foo!(T, a))`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag9004.d b/gcc/testsuite/gdc.test/fail_compilation/diag9004.d
index 37d5bd84f32..30589bf0cac 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag9004.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag9004.d
@@ -1,7 +1,7 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/diag9004.d(21): Error: none of the overloads of template `diag9004.bar` are callable using argument types `!()(Foo!int, int)`
+fail_compilation/diag9004.d(21): Error: template `diag9004.bar` is not callable using argument types `!()(Foo!int, int)`
 fail_compilation/diag9004.d(14):        Candidate is: `bar(FooT)(FooT foo, FooT.T x)`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag9574.d b/gcc/testsuite/gdc.test/fail_compilation/diag9574.d
deleted file mode 100644
index b280b3bda92..00000000000
--- a/gcc/testsuite/gdc.test/fail_compilation/diag9574.d
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-TEST_OUTPUT:
----
-fail_compilation/diag9574.d(12): Error: cannot use syntax `alias this = x`, use `alias x this` instead
-fail_compilation/diag9574.d(18): Error: cannot use syntax `alias this = x`, use `alias x this` instead
----
-*/
-
-struct S
-{
-    int x;
-    alias this = x;
-}
-
-class C
-{
-    int x;
-    alias this = x;
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag_template_alias.d b/gcc/testsuite/gdc.test/fail_compilation/diag_template_alias.d
index bbfb5a0e9d2..151bb426574 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag_template_alias.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag_template_alias.d
@@ -3,7 +3,7 @@ TEST_OUTPUT:
 ---
 fail_compilation/diag_template_alias.d(1): Error: identifier expected for template `alias` parameter
 fail_compilation/diag_template_alias.d(1): Error: found `alias` when expecting `(`
-fail_compilation/diag_template_alias.d(1): Error: semicolon expected following function declaration
+fail_compilation/diag_template_alias.d(1): Error: semicolon expected following function declaration, not `(`
 fail_compilation/diag_template_alias.d(1): Error: declaration expected, not `(`
 ---
  */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag_template_this.d b/gcc/testsuite/gdc.test/fail_compilation/diag_template_this.d
index 778f68e8842..25de03ce19e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag_template_this.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag_template_this.d
@@ -3,7 +3,7 @@ TEST_OUTPUT:
 ---
 fail_compilation/diag_template_this.d(1): Error: identifier expected for template `this` parameter
 fail_compilation/diag_template_this.d(1): Error: found `this` when expecting `(`
-fail_compilation/diag_template_this.d(1): Error: semicolon expected following function declaration
+fail_compilation/diag_template_this.d(1): Error: semicolon expected following function declaration, not `(`
 fail_compilation/diag_template_this.d(1): Error: declaration expected, not `(`
 ---
  */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diagin.d b/gcc/testsuite/gdc.test/fail_compilation/diagin.d
index 0d1f8f14fea..1748e92a841 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diagin.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diagin.d
@@ -4,7 +4,7 @@ TEST_OUTPUT:
 ---
 fail_compilation/diagin.d(14): Error: function `diagin.foo(in int)` is not callable using argument types `()`
 fail_compilation/diagin.d(14):        too few arguments, expected 1, got 0
-fail_compilation/diagin.d(16): Error: none of the overloads of template `diagin.foo1` are callable using argument types `!()(bool[])`
+fail_compilation/diagin.d(16): Error: template `diagin.foo1` is not callable using argument types `!()(bool[])`
 fail_compilation/diagin.d(20):        Candidate is: `foo1(T)(in T v, string)`
 ---
  */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d b/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d
index fe7d546f51b..0ac72296639 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d
@@ -21,7 +21,7 @@ __error__
 }
 }
 )`
-fail_compilation/e15876_3.d(28): Error: semicolon expected following function declaration
+fail_compilation/e15876_3.d(28): Error: semicolon expected following function declaration, not `End of File`
 ---
 */
 d(={for
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail12744.d b/gcc/testsuite/gdc.test/fail_compilation/fail12744.d
index 2056c0e2a27..711e57fad30 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail12744.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail12744.d
@@ -14,10 +14,10 @@ fail_compilation/fail12744.d(61): Error: template instance `fail12744.bar12744L!
 fail_compilation/fail12744.d(40): Error: incompatible parameter storage classes `lazy` and `out`
 fail_compilation/fail12744.d(62): Error: template instance `fail12744.bar12744L!(foo12744O)` error instantiating
 fail_compilation/fail12744.d(41): Error: incompatible parameter storage classes `auto ref` and `out`
-fail_compilation/fail12744.d(67): Error: none of the overloads of template `fail12744.bar12744A` are callable using argument types `!(foo12744O)(int)`
+fail_compilation/fail12744.d(67): Error: template `fail12744.bar12744A` is not callable using argument types `!(foo12744O)(int)`
 fail_compilation/fail12744.d(41):        Candidate is: `bar12744A(alias f)(auto ref PTT12744!f args)`
 fail_compilation/fail12744.d(41): Error: incompatible parameter storage classes `auto ref` and `lazy`
-fail_compilation/fail12744.d(68): Error: none of the overloads of template `fail12744.bar12744A` are callable using argument types `!(foo12744L)(int)`
+fail_compilation/fail12744.d(68): Error: template `fail12744.bar12744A` is not callable using argument types `!(foo12744L)(int)`
 fail_compilation/fail12744.d(41):        Candidate is: `bar12744A(alias f)(auto ref PTT12744!f args)`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail14669.d b/gcc/testsuite/gdc.test/fail_compilation/fail14669.d
index 5621ecceda8..45fe1463551 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail14669.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail14669.d
@@ -4,7 +4,7 @@ TEST_OUTPUT:
 fail_compilation/fail14669.d(11): Error: `auto` can only be used as part of `auto ref` for template function parameters
 fail_compilation/fail14669.d(16): Error: template instance `fail14669.foo1!()` error instantiating
 fail_compilation/fail14669.d(12): Error: `auto` can only be used as part of `auto ref` for template function parameters
-fail_compilation/fail14669.d(17): Error: none of the overloads of template `fail14669.foo2` are callable using argument types `!()(int)`
+fail_compilation/fail14669.d(17): Error: template `fail14669.foo2` is not callable using argument types `!()(int)`
 fail_compilation/fail14669.d(12):        Candidate is: `foo2()(auto int a)`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail15414.d b/gcc/testsuite/gdc.test/fail_compilation/fail15414.d
index 1fb6e23aedb..ed576b57fe6 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail15414.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail15414.d
@@ -5,7 +5,7 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail15414.d(20): Deprecation: `__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `fun`
+fail_compilation/fail15414.d(20): Deprecation: `__traits(getAttributes)` may only be used for individual functions, not the overload set `fun`
 fail_compilation/fail15414.d(20):        the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail162.d b/gcc/testsuite/gdc.test/fail_compilation/fail162.d
index a537f108e28..c79f8d8d548 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail162.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail162.d
@@ -1,7 +1,7 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail162.d(25): Error: none of the overloads of template `fail162.testHelper` are callable using argument types `!()(string, string)`
+fail_compilation/fail162.d(25): Error: template `fail162.testHelper` is not callable using argument types `!()(string, string)`
 fail_compilation/fail162.d(10):        Candidate is: `testHelper(A...)()`
 fail_compilation/fail162.d(30): Error: template instance `fail162.test!("hello", "world")` error instantiating
 ---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d b/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d
index 00dd9fd7cba..d36bb0b6e89 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d
@@ -3,7 +3,7 @@ REQUIRED_ARGS: -verrors=spec -o-
 TEST_OUTPUT:
 ---
 (spec:1) fail_compilation/fail20730b.d-mixin-43(43): Error: C style cast illegal, use `cast(int)mod`
-fail_compilation/fail20730b.d(26): Error: none of the overloads of template `fail20730b.atomicOp` are callable using argument types `!("+=")(shared(uint), int)`
+fail_compilation/fail20730b.d(26): Error: template `fail20730b.atomicOp` is not callable using argument types `!("+=")(shared(uint), int)`
 fail_compilation/fail20730b.d(41):        Candidate is: `atomicOp(string op, T, V1)(shared ref T val, V1 mod)`
   with `op = "+=",
        T = uint,
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail236.d b/gcc/testsuite/gdc.test/fail_compilation/fail236.d
index 626ec0090f1..accc0e17dd2 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail236.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail236.d
@@ -2,7 +2,7 @@
 TEST_OUTPUT:
 ---
 fail_compilation/fail236.d(14): Error: undefined identifier `x`
-fail_compilation/fail236.d(22): Error: none of the overloads of template `fail236.Templ2` are callable using argument types `!()(int)`
+fail_compilation/fail236.d(22): Error: template `fail236.Templ2` is not callable using argument types `!()(int)`
 fail_compilation/fail236.d(12):        Candidate is: `Templ2(alias a)(x)`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23626a.d b/gcc/testsuite/gdc.test/fail_compilation/fail23626a.d
index 2943f1a6c4f..559e0e2de0a 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail23626a.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23626a.d
@@ -1,7 +1,7 @@
 /* TEST_OUTPUT:
 ---
 fail_compilation/fail23626a.d(10): Deprecation: function `fail23626a.ambig` cannot overload `extern(D)` function at fail_compilation/fail23626a.d(9)
-fail_compilation/fail23626a.d(13): Deprecation: function `fail23626a.ambigC` cannot overload `extern(C)` function at fail_compilation/fail23626a.d(12)
+fail_compilation/fail23626a.d(13): Error: function `fail23626a.ambigC` cannot overload `extern(C)` function at fail_compilation/fail23626a.d(12)
 fail_compilation/fail23626a.d(16): Error: function `fail23626a.ambigCxx(int a)` conflicts with previous declaration at fail_compilation/fail23626a.d(15)
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail2456.d b/gcc/testsuite/gdc.test/fail_compilation/fail2456.d
index 08e11da2017..5d7d6eebd2e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail2456.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail2456.d
@@ -108,3 +108,17 @@ void test2456b()
         catch (Throwable) {}    // NG
     }
 }
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail2456.d(121): Deprecation: can only catch mutable or const qualified types, not `immutable(Exception)`
+---
+*/
+void main() {
+    try {
+        throw new Exception("");
+    } catch (immutable Exception e) {
+        assert(0);
+    }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail2789.d b/gcc/testsuite/gdc.test/fail_compilation/fail2789.d
index 2d6c8e2651a..261e4126d41 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail2789.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail2789.d
@@ -61,8 +61,8 @@ auto f6() { return ""; }    // string(), conflict
 TEST_OUTPUT:
 ---
 fail_compilation/fail2789.d(67): Error: function `fail2789.f_ExternC1()` conflicts with previous declaration at fail_compilation/fail2789.d(66)
-fail_compilation/fail2789.d(70): Deprecation: function `fail2789.f_ExternC2` cannot overload `extern(C)` function at fail_compilation/fail2789.d(69)
-fail_compilation/fail2789.d(73): Deprecation: function `fail2789.f_ExternC3` cannot overload `extern(C)` function at fail_compilation/fail2789.d(72)
+fail_compilation/fail2789.d(70): Error: function `fail2789.f_ExternC2` cannot overload `extern(C)` function at fail_compilation/fail2789.d(69)
+fail_compilation/fail2789.d(73): Error: function `fail2789.f_ExternC3` cannot overload `extern(C)` function at fail_compilation/fail2789.d(72)
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail8009.d b/gcc/testsuite/gdc.test/fail_compilation/fail8009.d
index 96489d9a77d..a4844bf66f5 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail8009.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail8009.d
@@ -1,7 +1,7 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail8009.d(9): Error: none of the overloads of template `fail8009.filter` are callable using argument types `!()(void)`
+fail_compilation/fail8009.d(9): Error: template `fail8009.filter` is not callable using argument types `!()(void)`
 fail_compilation/fail8009.d(8):        Candidate is: `filter(R)(scope bool delegate(ref BAD!R) func)`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail95.d b/gcc/testsuite/gdc.test/fail_compilation/fail95.d
index a1b3906dc6c..7065bc11516 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail95.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail95.d
@@ -1,7 +1,7 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail95.d(19): Error: none of the overloads of template `fail95.A` are callable using argument types `!()(int)`
+fail_compilation/fail95.d(19): Error: template `fail95.A` is not callable using argument types `!()(int)`
 fail_compilation/fail95.d(11):        Candidate is: `A(alias T)(T)`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d b/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d
index 6612a67e1e0..9ba29700020 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d
@@ -4,8 +4,8 @@ fail_compilation/failcontracts.d(18): Error: missing `{ ... }` for function lite
 fail_compilation/failcontracts.d(18): Error: semicolon expected following auto declaration, not `bode`
 fail_compilation/failcontracts.d(19): Error: function declaration without return type. (Note that constructors are always named `this`)
 fail_compilation/failcontracts.d(19): Error: no identifier for declarator `test1()`
-fail_compilation/failcontracts.d(19): Error: semicolon expected following function declaration
-fail_compilation/failcontracts.d(20): Error: semicolon expected following function declaration
+fail_compilation/failcontracts.d(19): Error: semicolon expected following function declaration, not `bode`
+fail_compilation/failcontracts.d(20): Error: semicolon expected following function declaration, not `bode`
 fail_compilation/failcontracts.d(22): Error: unexpected `(` in declarator
 fail_compilation/failcontracts.d(22): Error: found `T` when expecting `)`
 fail_compilation/failcontracts.d(22): Error: enum declaration is invalid
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d b/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d
index 24e39da85bb..448e629602d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d
@@ -1,8 +1,10 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/ice11856_1.d(16): Error: none of the overloads of template `ice11856_1.g` are callable using argument types `!()(A)`
-fail_compilation/ice11856_1.d(14):        Candidate is: `g(T)(T x)`
+fail_compilation/ice11856_1.d(18): Error: no property `g` for `A()` of type `A`
+fail_compilation/ice11856_1.d(18):        the following error occured while looking for a UFCS match
+fail_compilation/ice11856_1.d(18): Error: template `ice11856_1.g` is not callable using argument types `!()(A)`
+fail_compilation/ice11856_1.d(16):        Candidate is: `g(T)(T x)`
   with `T = A`
   must satisfy the following constraint:
 `       is(typeof(x.f()))`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice14130.d b/gcc/testsuite/gdc.test/fail_compilation/ice14130.d
index c64fb848484..151bf17535c 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice14130.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice14130.d
@@ -2,7 +2,7 @@
 TEST_OUTPUT:
 ---
 fail_compilation/ice14130.d(10): Error: undefined identifier `Undef`
-fail_compilation/ice14130.d(14): Error: none of the overloads of template `ice14130.foo` are callable using argument types `!()(int)`
+fail_compilation/ice14130.d(14): Error: template `ice14130.foo` is not callable using argument types `!()(int)`
 fail_compilation/ice14130.d(10):        Candidate is: `foo(R, F = Undef)(R r, F s = 0)`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice14907.d b/gcc/testsuite/gdc.test/fail_compilation/ice14907.d
index e1d7aac9f3c..5d676cd1a12 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice14907.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice14907.d
@@ -6,7 +6,7 @@ fail_compilation/ice14907.d(19):        while looking for match for `S!()`
 fail_compilation/ice14907.d(15): Error: template `ice14907.f(int v = f)()` recursive template expansion
 fail_compilation/ice14907.d(20):        while looking for match for `f!()`
 fail_compilation/ice14907.d(15): Error: template `ice14907.f(int v = f)()` recursive template expansion
-fail_compilation/ice14907.d(21): Error: none of the overloads of template `ice14907.f` are callable using argument types `!()()`
+fail_compilation/ice14907.d(21): Error: template `ice14907.f` is not callable using argument types `!()()`
 fail_compilation/ice14907.d(15):        Candidate is: `f(int v = f)()`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice6538.d b/gcc/testsuite/gdc.test/fail_compilation/ice6538.d
index 1c6cf4b1505..af7c5543228 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice6538.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice6538.d
@@ -7,7 +7,7 @@
 TEST_OUTPUT:
 ---
 fail_compilation/ice6538.d(23): Error: expression `super` is not a valid template value argument
-fail_compilation/ice6538.d(28): Error: none of the overloads of template `ice6538.D.foo` are callable using argument types `!()()`
+fail_compilation/ice6538.d(28): Error: template `ice6538.D.foo` is not callable using argument types `!()()`
 fail_compilation/ice6538.d(23):        Candidate is: `foo()()`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice9284.d b/gcc/testsuite/gdc.test/fail_compilation/ice9284.d
index 00602d2de81..47fd44c6b01 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice9284.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice9284.d
@@ -1,7 +1,7 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/ice9284.d(14): Error: none of the overloads of template `ice9284.C.__ctor` are callable using argument types `!()(int)`
+fail_compilation/ice9284.d(14): Error: template `ice9284.C.__ctor` is not callable using argument types `!()(int)`
 fail_compilation/ice9284.d(12):        Candidate is: `__ctor()(string)`
 fail_compilation/ice9284.d(20): Error: template instance `ice9284.C.__ctor!()` error instantiating
 ---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/import23873.d b/gcc/testsuite/gdc.test/fail_compilation/imports/import23873.d
new file mode 100644
index 00000000000..39334cf62ef
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/import23873.d
@@ -0,0 +1,2 @@
+static if ;
+else auto x
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908a.d b/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908a.d
new file mode 100644
index 00000000000..4c369e3c46a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908a.d
@@ -0,0 +1,3 @@
+module imports.spell23908a;
+
+import imports.spell23908b : nonexistent;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908b.d b/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908b.d
new file mode 100644
index 00000000000..316b4feff01
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908b.d
@@ -0,0 +1,3 @@
+module imports.spell23908b;
+
+import imports.spell23908a;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d
index 0900e6010d1..5129f301460 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d
@@ -15,7 +15,7 @@ fail_compilation/named_arguments_error.d(38): Error: no named argument `element`
 fail_compilation/named_arguments_error.d(39): Error: no named argument `number` allowed for scalar
 fail_compilation/named_arguments_error.d(40): Error: cannot implicitly convert expression `g(x: 3, y: 4, z: 5)` of type `int` to `string`
 fail_compilation/named_arguments_error.d(41): Error: named arguments with Implicit Function Template Instantiation are not supported yet
-fail_compilation/named_arguments_error.d(41): Error: none of the overloads of template `named_arguments_error.tempfun` are callable using argument types `!()(string, int)`
+fail_compilation/named_arguments_error.d(41): Error: template `named_arguments_error.tempfun` is not callable using argument types `!()(string, int)`
 fail_compilation/named_arguments_error.d(45):        Candidate is: `tempfun(T, U)(T t, U u)`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope.d b/gcc/testsuite/gdc.test/fail_compilation/retscope.d
index 7bc5e96bef8..50cfdd3ef9c 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/retscope.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/retscope.d
@@ -403,7 +403,7 @@ class Foo13
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/retscope.d(1205): Error: scope variable `f14` assigned to non-scope parameter `this` calling `foo`
+fail_compilation/retscope.d(1205): Error: scope variable `f14` calling non-scope member function `f14.foo()`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/spell23908.d b/gcc/testsuite/gdc.test/fail_compilation/spell23908.d
new file mode 100644
index 00000000000..a7501e1ca54
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/spell23908.d
@@ -0,0 +1,11 @@
+/*
+EXTRA_FILES: imports/spell23908a.d imports/spell23908b.d
+TEST_OUTPUT:
+---
+fail_compilation/imports/spell23908a.d(3): Error: module `imports.spell23908b` import `nonexistent` not found
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=23908
+
+import imports.spell23908a;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/static_import.d b/gcc/testsuite/gdc.test/fail_compilation/static_import.d
new file mode 100644
index 00000000000..24b7bc19546
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/static_import.d
@@ -0,0 +1,8 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/static_import.d(8): Error: static import `core` cannot have an import bind list
+---
+*/
+
+static import core.stdc.stdio : p = q;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test18385.d b/gcc/testsuite/gdc.test/fail_compilation/test18385.d
index 3f87885cb91..2e48192ab64 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test18385.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test18385.d
@@ -2,7 +2,7 @@
 REQUIRED_ARGS: -de
 TEST_OUTPUT:
 ---
-fail_compilation/test18385.d(13): Deprecation: function `test18385.foo` cannot overload `extern(C)` function at fail_compilation/test18385.d(12)
+fail_compilation/test18385.d(13): Error: function `test18385.foo` cannot overload `extern(C)` function at fail_compilation/test18385.d(12)
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test19107.d b/gcc/testsuite/gdc.test/fail_compilation/test19107.d
index 93d86bf381b..c8021229427 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test19107.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test19107.d
@@ -2,7 +2,7 @@
 EXTRA_FILES: imports/imp19661.d imports/test19107a.d imports/test19107b.d
 TEST_OUTPUT:
 ---
-fail_compilation/test19107.d(24): Error: none of the overloads of template `test19107.all` are callable using argument types `!((c) => c)(string[])`
+fail_compilation/test19107.d(24): Error: template `test19107.all` is not callable using argument types `!((c) => c)(string[])`
 fail_compilation/test19107.d(18):        Candidate is: `all(alias pred, T)(T t)`
   with `pred = __lambda2,
        T = string[]`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test20245.d b/gcc/testsuite/gdc.test/fail_compilation/test20245.d
index 98caa03b2f5..3c43c5cfe4b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test20245.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test20245.d
@@ -9,7 +9,7 @@ fail_compilation/test20245.d(27): Error: cannot take address of `scope` variable
 fail_compilation/test20245.d(33): Error: reference to local variable `x` assigned to non-scope parameter `ptr` calling `escape`
 fail_compilation/test20245.d(34): Error: copying `&x` into allocated memory escapes a reference to parameter `x`
 fail_compilation/test20245.d(50): Error: reference to local variable `price` assigned to non-scope `this.minPrice`
-fail_compilation/test20245.d(69): Error: reference to local variable `this` assigned to non-scope parameter `msg` calling `this`
+fail_compilation/test20245.d(69): Error: reference to local variable `this` calling non-scope member function `this.this()`
 fail_compilation/test20245.d(89): Error: reference to local variable `this` assigned to non-scope parameter `content` calling `listUp`
 fail_compilation/test20245.d(82):        which is not `scope` because of `charPtr = content`
 ---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23873.d b/gcc/testsuite/gdc.test/fail_compilation/test23873.d
new file mode 100644
index 00000000000..bb6a71dcc24
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test23873.d
@@ -0,0 +1,14 @@
+// https://issues.dlang.org/show_bug.cgi?id=23873
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/imports/import23873.d(1): Error: (expression) expected following `static if`
+fail_compilation/imports/import23873.d(1): Error: declaration expected following attribute, not `;`
+fail_compilation/imports/import23873.d(3): Error: no identifier for declarator `x`
+---
+*/
+struct Foo
+{
+    import imports.import23873;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23882.d b/gcc/testsuite/gdc.test/fail_compilation/test23882.d
new file mode 100644
index 00000000000..f6b57c4ea04
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test23882.d
@@ -0,0 +1,37 @@
+// https://issues.dlang.org/show_bug.cgi?id=23882
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test23882.d(26): Error: `typeof((*YC).S).init` is used as a type
+---
+*/
+
+struct G(H)
+{
+    Tuple!(R) S;
+}
+
+struct BB(H)
+{
+    H* YC;
+    alias YC this;
+}
+
+struct R
+{
+    BB!(G!float) CB;
+    alias CB this;
+
+    this(typeof(CB.S).init);
+}
+
+struct Tuple(Specs)
+{
+    Specs expand;
+
+    this(Specs values)
+    {
+        expand = values;
+    }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23905.d b/gcc/testsuite/gdc.test/fail_compilation/test23905.d
new file mode 100644
index 00000000000..5b30fa855e2
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test23905.d
@@ -0,0 +1,25 @@
+// https://issues.dlang.org/show_bug.cgi?id=23905
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test23905.d(24): Error: enum `test23905.Foo` is opaque and has no default initializer
+---
+*/
+
+struct SumType(T)
+{
+    T storage;
+
+    bool opEquals(Rhs)(Rhs rhs)
+    if (is(typeof(Rhs.init)))
+    {
+    }
+
+}
+
+enum Foo;
+
+void main(){
+    SumType!Foo data = Foo.init;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/udaparams.d b/gcc/testsuite/gdc.test/fail_compilation/udaparams.d
index 453ebba4e09..76df55fcfd7 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/udaparams.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/udaparams.d
@@ -23,7 +23,7 @@ fail_compilation/udaparams.d(57): Error: identifier expected for template value
 fail_compilation/udaparams.d(57): Error: found `@` when expecting `)`
 fail_compilation/udaparams.d(57): Error: basic type expected, not `3`
 fail_compilation/udaparams.d(57): Error: found `3` when expecting `)`
-fail_compilation/udaparams.d(57): Error: semicolon expected following function declaration
+fail_compilation/udaparams.d(57): Error: semicolon expected following function declaration, not `)`
 fail_compilation/udaparams.d(57): Error: declaration expected, not `)`
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ufcs.d b/gcc/testsuite/gdc.test/fail_compilation/ufcs.d
new file mode 100644
index 00000000000..501ef81927f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/ufcs.d
@@ -0,0 +1,34 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/ufcs.d(25): Error: no property `regularF` for `s` of type `S`
+fail_compilation/ufcs.d(25):        the following error occured while looking for a UFCS match
+fail_compilation/ufcs.d(25): Error: function `ufcs.regularF()` is not callable using argument types `(S)`
+fail_compilation/ufcs.d(25):        expected 0 argument(s), not 1
+fail_compilation/ufcs.d(26): Error: no property `templateF` for `s` of type `S`
+fail_compilation/ufcs.d(26):        the following error occured while looking for a UFCS match
+fail_compilation/ufcs.d(26): Error: template `ufcs.templateF` is not callable using argument types `!()(S)`
+fail_compilation/ufcs.d(31):        Candidate is: `templateF()()`
+fail_compilation/ufcs.d(27): Error: no property `templateO` for `s` of type `S`
+fail_compilation/ufcs.d(27):        the following error occured while looking for a UFCS match
+fail_compilation/ufcs.d(27): Error: none of the overloads of template `ufcs.templateO` are callable using argument types `!()(S)`
+fail_compilation/ufcs.d(33):        Candidates are: `templateO()(int x)`
+fail_compilation/ufcs.d(34):                        `templateO()(float y)`
+---
+*/
+
+struct S { }
+
+void f()
+{
+    S s;
+    s.regularF();
+    s.templateF();
+    s.templateO();
+}
+
+void regularF();
+void templateF()();
+
+void templateO()(int x);
+void templateO()(float y);
diff --git a/gcc/testsuite/gdc.test/runnable/betterc.d b/gcc/testsuite/gdc.test/runnable/betterc.d
index 74967e9bc35..3d8f7da0fcc 100644
--- a/gcc/testsuite/gdc.test/runnable/betterc.d
+++ b/gcc/testsuite/gdc.test/runnable/betterc.d
@@ -42,6 +42,7 @@ extern (C) void main()
     test18472();
     testRuntimeLowerings();
     test18457();
+    test20737();
 }
 
 /*******************************************/
@@ -199,3 +200,13 @@ void test18457()
     }
     assert(dtor == 1);
 }
+
+/**********************************************/
+// https://issues.dlang.org/show_bug.cgi?id=20737
+int tlsVar;
+
+int test20737()
+{
+    tlsVar = 123;
+    return 0;
+}
diff --git a/gcc/testsuite/gdc.test/runnable/eh2.d b/gcc/testsuite/gdc.test/runnable/eh2.d
index 2b469d2f803..775e83d3bf6 100644
--- a/gcc/testsuite/gdc.test/runnable/eh2.d
+++ b/gcc/testsuite/gdc.test/runnable/eh2.d
@@ -72,11 +72,11 @@ int main()
         a.test();
         Abc.x |= 0x40;
     }
-    catch (shared(Abc) b)
+    catch (Abc b)
     {
         Abc.x |= 0x80;
         printf("Caught %p, x = x%x\n", b, Abc.x);
-        assert(a is b);
+        assert(cast() a is b);
         assert(Abc.x == 0xB5);
     }
     printf("Success!\n");
diff --git a/gcc/testsuite/gdc.test/runnable/funclit.d b/gcc/testsuite/gdc.test/runnable/funclit.d
index e6e4fec1c54..c4b70dcb509 100644
--- a/gcc/testsuite/gdc.test/runnable/funclit.d
+++ b/gcc/testsuite/gdc.test/runnable/funclit.d
@@ -1263,6 +1263,7 @@ void assign16271(T)(ref T a, T b)
 void test16271()
 {
     int x;
+    (delegate ref => x)() = -1;     assert(x == -1);
     (ref () => x )() = 1;           assert(x == 1);
     func16271!(ref () => x) = 2;    assert(x == 2);
     assign16271(x, 3);              assert(x == 3);
diff --git a/gcc/testsuite/gdc.test/runnable/test20687.d b/gcc/testsuite/gdc.test/runnable/test20687.d
new file mode 100644
index 00000000000..47c33f17b73
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test20687.d
@@ -0,0 +1,28 @@
+// PERMUTE_ARGS:
+// https://issues.dlang.org/show_bug.cgi?id=20687
+
+struct S
+{
+    void foo(){}
+}
+
+void main()
+{
+    S i;
+    enum fpe = &S.foo;
+    const fp = &S.foo;
+    const dg = &i.foo;
+
+    // Allow these
+    static dgfp = &S.foo;
+    static const dgfpc = &S.foo;
+    static immutable dgfpi = &S.foo;
+    __gshared dgfpg = &S.foo;
+    __gshared const dgfpgc = &S.foo;
+    __gshared immutable dgfpgi = &S.foo;
+
+    static foreach (v; [fp, dgfpc, dgfpi, dgfpgc, dgfpgi])
+        static assert(fpe == v);
+
+    assert(fp == dg.funcptr && fp == dgfp && fp == dgfpg);
+}
diff --git a/gcc/testsuite/gdc.test/runnable/testinvariant.d b/gcc/testsuite/gdc.test/runnable/testinvariant.d
index d3b3b6ffa16..0ce85571911 100644
--- a/gcc/testsuite/gdc.test/runnable/testinvariant.d
+++ b/gcc/testsuite/gdc.test/runnable/testinvariant.d
@@ -176,6 +176,58 @@ void test13147()
     s.test();
 }
 
+/***************************************************/
+// https://issues.dlang.org/show_bug.cgi?id=16384
+
+struct S(T)
+{
+    T x = 5;
+    invariant { assert(x == 6); }
+    invariant { assert(x > 0); }
+
+    void foo() {}
+}
+
+void f(int i) pure { assert( i == 6); }
+
+struct S2(T)
+{
+    T x = 5;
+    invariant { f(x); }
+    invariant { assert(x > 0); }
+
+    void foo() {}
+}
+
+void test16384()
+{
+    string s;
+    S!int y;
+    try
+    {
+        y.foo();
+    }
+    catch(Error)
+    {
+        s = "needs to be thrown";
+    }
+
+    assert(s == "needs to be thrown");
+
+    S2!int y2;
+
+    try
+    {
+        y2.foo();
+    }
+    catch(Error)
+    {
+        s = "needs to be thrown2";
+    }
+
+    assert(s == "needs to be thrown2");
+}
+
 
 /***************************************************/
 
@@ -183,6 +235,7 @@ void main()
 {
     testinvariant();
     test6453();
+    test16384();
     test13113();
     test13147();
 }
diff --git a/gcc/testsuite/gdc.test/runnable/variadic.d b/gcc/testsuite/gdc.test/runnable/variadic.d
index 2d0736ded66..7e9473c332e 100644
--- a/gcc/testsuite/gdc.test/runnable/variadic.d
+++ b/gcc/testsuite/gdc.test/runnable/variadic.d
@@ -1118,6 +1118,53 @@ void test15417()
 }
 
 
+/***************************************/
+// https://issues.dlang.org/show_bug.cgi?id=21425
+
+import core.stdc.stdarg;
+import core.stdc.stdio;
+
+extern(C) void f5(int dummy, ...)
+{
+    va_list ap;
+
+    va_start(ap, dummy);
+    int x = va_arg!int(ap);
+    assert(x == 5);
+    va_end(ap);
+
+    va_start(ap, dummy);
+    int y = va_arg!int(ap);
+    assert(y == 5);
+    va_end(ap);
+}
+
+void test21425()
+{
+    f5(0, 5);
+}
+
+/*********************************************/
+// https://issues.dlang.org/show_bug.cgi?id=23409
+
+import core.stdc.string;
+
+void printf10(const(char)* fmt, ...){
+    char[30] s;
+    for(int i = 0; i < 10; i++){
+        va_list args;
+        va_start(args, fmt);
+        vsprintf(s.ptr, fmt, args);
+        va_end(args);
+        assert(strcmp(s.ptr, "Hello world\n") == 0);
+    }
+}
+
+void test23409()
+{
+    printf10("Hello %s\n".ptr, "world".ptr);
+}
+
 /***************************************/
 
 int main()
@@ -1169,6 +1216,8 @@ int main()
     testCopy();
     test14179();
     test15417();
+    test21425();
+    test23409();
 
     return 0;
 }
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 95ea67d789b..1cff48a7b2a 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-28a3b24c2e45de39cd3df528142fd06b6456e8fd
+17ccd12af386543c0b9935bf7e0a8e701b903105
 
 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/__builtins.di b/libphobos/libdruntime/__builtins.di
index 1c490358904..74147a095cd 100644
--- a/libphobos/libdruntime/__builtins.di
+++ b/libphobos/libdruntime/__builtins.di
@@ -67,8 +67,7 @@ version (DigitalMars)
 
     ushort __builtin_bswap16()(ushort value)
     {
-        import core.bitop;
-        return core.bitop.byteswap(value);
+        return cast(ushort) (((value >> 8) & 0xFF) | ((value << 8) & 0xFF00U));
     }
 
     uint __builtin_bswap32()(uint value)
diff --git a/libphobos/libdruntime/core/atomic.d b/libphobos/libdruntime/core/atomic.d
index 1fba06cc021..5a7d00c38db 100644
--- a/libphobos/libdruntime/core/atomic.d
+++ b/libphobos/libdruntime/core/atomic.d
@@ -162,7 +162,7 @@ void atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V)(ref shared T val, V new
 }
 
 /// Ditto
-void atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V)(ref shared T val, shared V newval) pure nothrow @nogc @trusted
+void atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V)(ref shared T val, auto ref shared V newval) pure nothrow @nogc @trusted
     if (is(T == class))
 {
     static assert (is (V : T), "Can't assign `newval` of type `shared " ~ V.stringof ~ "` to `shared " ~ T.stringof ~ "`.");
diff --git a/libphobos/libdruntime/core/internal/string.d b/libphobos/libdruntime/core/internal/string.d
index e09bba4707b..7bb319ecfa5 100644
--- a/libphobos/libdruntime/core/internal/string.d
+++ b/libphobos/libdruntime/core/internal/string.d
@@ -152,7 +152,7 @@ T[] signedToTempString(uint radix = 10, bool upperCase = false, T)(long value, r
     if (neg)
     {
         // about to do a slice without a bounds check
-        auto trustedSlice(return scope char[] r) @trusted { assert(r.ptr > buf.ptr); return (r.ptr-1)[0..r.length+1]; }
+        auto trustedSlice(return scope T[] r) @trusted { assert(r.ptr > buf.ptr); return (r.ptr-1)[0..r.length+1]; }
         r = trustedSlice(r);
         r[0] = '-';
     }
@@ -190,6 +190,12 @@ unittest
     assert(long.max.signedToTempString(buf) == "9223372036854775807");
     assert(long.min.signedToTempString(buf) == "-9223372036854775808");
 
+    wchar[65] wbuf = void;
+    assert(1.signedToTempString(wbuf) == "1"w);
+
+    dchar[65] dbuf = void;
+    assert(1.signedToTempString(dbuf) == "1"d);
+
     // use stack allocated struct version
     assert(0.signedToTempString() == "0");
     assert(1.signedToTempString == "1");
diff --git a/libphobos/libdruntime/core/internal/util/array.d b/libphobos/libdruntime/core/internal/util/array.d
index 6136cfef17d..066ee7e72db 100644
--- a/libphobos/libdruntime/core/internal/util/array.d
+++ b/libphobos/libdruntime/core/internal/util/array.d
@@ -26,14 +26,6 @@ private char[] errorMessage(Args...)(scope const(char*) format,
 
 @safe /* pure dmd @@@BUG11461@@@ */ nothrow:
 
-void enforceTypedArraysConformable(T)(const char[] action,
-    const T[] a1, const T[] a2, const bool allowOverlap = false)
-{
-    _enforceSameLength(action, a1.length, a2.length);
-    if (!allowOverlap)
-        _enforceNoOverlap(action, arrayToPtr(a1), arrayToPtr(a2), T.sizeof * a1.length);
-}
-
 void enforceRawArraysConformable(const char[] action, const size_t elementSize,
     const void[] a1, const void[] a2, const bool allowOverlap = false)
 {
@@ -76,14 +68,6 @@ private void _enforceNoOverlap(const char[] action,
     assert(0, msg);
 }
 
-void enforceTypedArraysConformableNogc(T)(const char[] action,
-    const T[] a1, const T[] a2, const bool allowOverlap = false)
-{
-    _enforceSameLengthNogc(action, a1.length, a2.length);
-    if (!allowOverlap)
-        _enforceNoOverlapNogc(action, arrayToPtr(a1), arrayToPtr(a2), T.sizeof * a1.length);
-}
-
 void enforceRawArraysConformableNogc(const char[] action, const size_t elementSize,
     const void[] a1, const void[] a2, const bool allowOverlap = false)
 {
diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d
index 5e339c041d1..ae047cb730e 100644
--- a/libphobos/libdruntime/core/lifetime.d
+++ b/libphobos/libdruntime/core/lifetime.d
@@ -2777,6 +2777,70 @@ if (is(T == class))
     return cast(T) p;
 }
 
+/**
+ * TraceGC wrapper around $(REF _d_newclassT, core,lifetime).
+ */
+T _d_newclassTTrace(T)(string file, int line, string funcname) @trusted
+{
+    version (D_TypeInfo)
+    {
+        import core.internal.array.utils : TraceHook, gcStatsPure, accumulatePure;
+        mixin(TraceHook!(T.stringof, "_d_newclassT"));
+
+        return _d_newclassT!T();
+    }
+    else
+        assert(0, "Cannot create new class if compiling without support for runtime type information!");
+}
+
+/**
+ * Allocate an initialized non-array item.
+ *
+ * This is an optimization to avoid things needed for arrays like the __arrayPad(size).
+ * Used to allocate struct instances on the heap.
+ *
+ * ---
+ * struct Sz {int x = 0;}
+ * struct Si {int x = 3;}
+ *
+ * void main()
+ * {
+ *     new Sz(); // uses zero-initialization
+ *     new Si(); // uses Si.init
+ * }
+ * ---
+ *
+ * Returns:
+ *     newly allocated item
+ */
+T* _d_newitemT(T)() @trusted
+{
+    import core.internal.lifetime : emplaceInitializer;
+    import core.internal.traits : hasElaborateDestructor, hasIndirections;
+    import core.memory : GC;
+
+    auto flags = !hasIndirections!T ? GC.BlkAttr.NO_SCAN : GC.BlkAttr.NONE;
+    immutable tiSize = hasElaborateDestructor!T ? size_t.sizeof : 0;
+    immutable itemSize = T.sizeof;
+    immutable totalSize = itemSize + tiSize;
+    if (tiSize)
+        flags |= GC.BlkAttr.STRUCTFINAL | GC.BlkAttr.FINALIZE;
+
+    auto blkInfo = GC.qalloc(totalSize, flags, null);
+    auto p = blkInfo.base;
+
+    if (tiSize)
+    {
+        // The GC might not have cleared the padding area in the block.
+        *cast(TypeInfo*) (p + (itemSize & ~(size_t.sizeof - 1))) = null;
+        *cast(TypeInfo*) (p + blkInfo.size - tiSize) = cast() typeid(T);
+    }
+
+    emplaceInitializer(*(cast(T*) p));
+
+    return cast(T*) p;
+}
+
 // Test allocation
 @safe unittest
 {
@@ -2805,15 +2869,134 @@ if (is(T == class))
     }
 }
 
-T _d_newclassTTrace(T)(string file, int line, string funcname) @trusted
+// Test allocation
+@safe unittest
+{
+    struct S { }
+    S* s = _d_newitemT!S();
+
+    assert(s !is null);
+}
+
+// Test initializers
+@safe unittest
 {
-    version (D_TypeInfo)
     {
-        import core.internal.array.utils: TraceHook, gcStatsPure, accumulatePure;
-        mixin(TraceHook!(T.stringof, "_d_newclassT"));
+        // zero-initialization
+        struct S { int x, y; }
+        S* s = _d_newitemT!S();
 
-        return _d_newclassT!T();
+        assert(s.x == 0);
+        assert(s.y == 0);
+    }
+    {
+        // S.init
+        struct S { int x = 2, y = 3; }
+        S* s = _d_newitemT!S();
+
+        assert(s.x == 2);
+        assert(s.y == 3);
+    }
+}
+
+// Test GC attributes
+version (CoreUnittest)
+{
+    struct S1
+    {
+        int x = 5;
+    }
+    struct S2
+    {
+        int x;
+        this(int x) { this.x = x; }
+    }
+    struct S3
+    {
+        int[4] x;
+        this(int x) { this.x[] = x; }
+    }
+    struct S4
+    {
+        int *x;
+    }
+
+}
+@system unittest
+{
+    import core.memory : GC;
+
+    auto s1 = new S1;
+    assert(s1.x == 5);
+    assert(GC.getAttr(s1) == GC.BlkAttr.NO_SCAN);
+
+    auto s2 = new S2(3);
+    assert(s2.x == 3);
+    assert(GC.getAttr(s2) == GC.BlkAttr.NO_SCAN);
+
+    auto s3 = new S3(1);
+    assert(s3.x == [1, 1, 1, 1]);
+    assert(GC.getAttr(s3) == GC.BlkAttr.NO_SCAN);
+    debug(SENTINEL) {} else
+        assert(GC.sizeOf(s3) == 16);
+
+    auto s4 = new S4;
+    assert(s4.x == null);
+    assert(GC.getAttr(s4) == 0);
+}
+
+// Test struct finalizers exception handling
+debug(SENTINEL) {} else
+@system unittest
+{
+    import core.memory : GC;
+
+    bool test(E)()
+    {
+        import core.exception;
+        static struct S1
+        {
+            E exc;
+            ~this() { throw exc; }
+        }
+
+        bool caught = false;
+        S1* s = new S1(new E("test onFinalizeError"));
+        try
+        {
+            GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0 .. 1]);
+        }
+        catch (FinalizeError err)
+        {
+            caught = true;
+        }
+        catch (E)
+        {
+        }
+        GC.free(s);
+        return caught;
+    }
+
+    assert(test!Exception);
+    import core.exception : InvalidMemoryOperationError;
+    assert(!test!InvalidMemoryOperationError);
+}
+
+version (D_ProfileGC)
+{
+    /**
+    * TraceGC wrapper around $(REF _d_newitemT, core,lifetime).
+    */
+    T* _d_newitemTTrace(T)(string file, int line, string funcname) @trusted
+    {
+        version (D_TypeInfo)
+        {
+            import core.internal.array.utils : TraceHook, gcStatsPure, accumulatePure;
+            mixin(TraceHook!(T.stringof, "_d_newitemT"));
+
+            return _d_newitemT!T();
+        }
+        else
+            assert(0, "Cannot create new `struct` if compiling without support for runtime type information!");
     }
-    else
-        assert(0, "Cannot create new class if compiling without support for runtime type information!");
 }
diff --git a/libphobos/libdruntime/core/stdc/assert_.d b/libphobos/libdruntime/core/stdc/assert_.d
index fc9402f6051..a8909e26126 100644
--- a/libphobos/libdruntime/core/stdc/assert_.d
+++ b/libphobos/libdruntime/core/stdc/assert_.d
@@ -12,7 +12,6 @@
 
 /****************************
  * These are the various functions called by the assert() macro.
- * They are all noreturn functions, although D doesn't have a specific attribute for that.
  */
 
 module core.stdc.assert_;
@@ -36,7 +35,7 @@ version (CRuntime_DigitalMars)
     /***
      * Assert failure function in the Digital Mars C library.
      */
-    void _assert(const(void)* exp, const(void)* file, uint line);
+    noreturn _assert(const(void)* exp, const(void)* file, uint line);
 }
 else version (CRuntime_Microsoft)
 {
@@ -44,37 +43,37 @@ else version (CRuntime_Microsoft)
      * Assert failure function in the Microsoft C library.
      * `_assert` is not in assert.h, but it is in the library.
      */
-    void _wassert(const(wchar)* exp, const(wchar)* file, uint line);
+    noreturn _wassert(const(wchar)* exp, const(wchar)* file, uint line);
     ///
-    void _assert(const(char)* exp, const(char)* file, uint line);
+    noreturn _assert(const(char)* exp, const(char)* file, uint line);
 }
 else version (Darwin)
 {
     /***
      * Assert failure function in the Darwin C library.
      */
-    void __assert_rtn(const(char)* func, const(char)* file, uint line, const(char)* exp);
+    noreturn __assert_rtn(const(char)* func, const(char)* file, uint line, const(char)* exp);
 }
 else version (FreeBSD)
 {
     /***
      * Assert failure function in the FreeBSD C library.
      */
-    void __assert(const(char)* exp, const(char)* file, uint line);
+    noreturn __assert(const(char)* exp, const(char)* file, uint line, const(char)* exp);
 }
 else version (NetBSD)
 {
     /***
      * Assert failure function in the NetBSD C library.
      */
-    void __assert(const(char)* file, int line, const(char)* exp);
+    noreturn __assert(const(char)* file, int line, const(char)* exp);
 }
 else version (OpenBSD)
 {
     /***
      * Assert failure function in the OpenBSD C library.
      */
-    void __assert(const(char)* file, int line, const(char)* exp);
+    noreturn __assert(const(char)* file, int line, const(char)* exp);
     ///
     void __assert2(const(char)* file, int line, const(char)* func, const(char)* exp);
 }
@@ -83,37 +82,37 @@ else version (DragonFlyBSD)
     /***
      * Assert failure function in the DragonFlyBSD C library.
      */
-    void __assert(const(char)* exp, const(char)* file, uint line);
+    noreturn __assert(const(char)* exp, const(char)* file, uint line, const(char)* exp);
 }
 else version (CRuntime_Glibc)
 {
     /***
      * Assert failure functions in the GLIBC library.
      */
-    void __assert(const(char)* exp, const(char)* file, uint line);
+    noreturn __assert(const(char)* exp, const(char)* file, uint line);
     ///
-    void __assert_fail(const(char)* exp, const(char)* file, uint line, const(char)* func);
+    noreturn __assert_fail(const(char)* exp, const(char)* file, uint line, const(char)* func);
     ///
-    void __assert_perror_fail(int errnum, const(char)* file, uint line, const(char)* func);
+    noreturn __assert_perror_fail(int errnum, const(char)* file, uint line, const(char)* func);
 }
 else version (CRuntime_Bionic)
 {
-    void __assert(const(char)* __file, int __line, const(char)* __msg);
+    noreturn __assert(const(char)* __file, int __line, const(char)* __msg);
 }
 else version (CRuntime_Musl)
 {
      /***
      * Assert failure function in the Musl C library.
      */
-    void __assert_fail(const(char)* exp, const(char)* file, uint line, const(char)* func);
+    noreturn __assert_fail(const(char)* exp, const(char)* file, uint line, const(char)* func);
 }
 else version (CRuntime_UClibc)
 {
-    void __assert(const(char)* exp, const(char)* file, uint line, const(char)* func);
+    noreturn __assert(const(char)* exp, const(char)* file, uint line, const(char)* func);
 }
 else version (Solaris)
 {
-    void __assert_c99(const(char)* exp, const(char)* file, uint line, const(char)* func);
+    noreturn __assert_c99(const(char)* exp, const(char)* file, uint line, const(char)* func);
 }
 else
 {
diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d
index 610cb7a30a1..337eabf64db 100644
--- a/libphobos/libdruntime/object.d
+++ b/libphobos/libdruntime/object.d
@@ -527,7 +527,8 @@ private extern(C) void _d_setSameMutex(shared Object ownee, shared Object owner)
 
 void setSameMutex(shared Object ownee, shared Object owner)
 {
-    _d_setSameMutex(ownee, owner);
+    import core.atomic : atomicLoad;
+    _d_setSameMutex(atomicLoad(ownee), atomicLoad(owner));
 }
 
 @system unittest
@@ -4532,6 +4533,7 @@ version (D_ProfileGC)
 {
     public import core.internal.array.appending : _d_arrayappendTTrace;
     public import core.internal.array.concatenation : _d_arraycatnTXTrace;
+    public import core.lifetime : _d_newitemTTrace;
 }
 public import core.internal.array.appending : _d_arrayappendcTXImpl;
 public import core.internal.array.comparison : __cmp;
@@ -4560,6 +4562,7 @@ public import core.lifetime : _d_delstructImpl;
 public import core.lifetime : _d_newThrowable;
 public import core.lifetime : _d_newclassT;
 public import core.lifetime : _d_newclassTTrace;
+public import core.lifetime : _d_newitemT;
 
 public @trusted @nogc nothrow pure extern (C) void _d_delThrowable(scope Throwable);
 
diff --git a/libphobos/libdruntime/rt/cast_.d b/libphobos/libdruntime/rt/cast_.d
index 1604510b427..925599e0159 100644
--- a/libphobos/libdruntime/rt/cast_.d
+++ b/libphobos/libdruntime/rt/cast_.d
@@ -117,22 +117,6 @@ int _d_isbaseof2(scope ClassInfo oc, scope const ClassInfo c, scope ref size_t o
 
 int _d_isbaseof(scope ClassInfo oc, scope const ClassInfo c) @safe
 {
-    if (areClassInfosEqual(oc, c))
-        return true;
-
-    do
-    {
-        if (oc.base && areClassInfosEqual(oc.base, c))
-            return true;
-
-        foreach (iface; oc.interfaces)
-        {
-            if (areClassInfosEqual(iface.classinfo, c) || _d_isbaseof(iface.classinfo, c))
-                return true;
-        }
-
-        oc = oc.base;
-    } while (oc);
-
-    return false;
+    size_t offset = 0;
+    return _d_isbaseof2(oc, c, offset);
 }
diff --git a/libphobos/libdruntime/rt/lifetime.d b/libphobos/libdruntime/rt/lifetime.d
index a37541bf01f..40fa3e00b45 100644
--- a/libphobos/libdruntime/rt/lifetime.d
+++ b/libphobos/libdruntime/rt/lifetime.d
@@ -676,7 +676,7 @@ Params:
     ti = `TypeInfo` of array type
     arr = array to shrink. Its `.length` is element length, not byte length, despite `void` type
 */
-extern(C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) /+nothrow+/
+extern(C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) nothrow
 {
     // note, we do not care about shared.  We are setting the length no matter
     // what, so no lock is required.
@@ -701,7 +701,17 @@ extern(C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) /+nothrow+/
             {
                 auto oldsize = __arrayAllocLength(info, tinext);
                 if (oldsize > cursize)
-                    finalize_array(arr.ptr + cursize, oldsize - cursize, sti);
+                {
+                    try
+                    {
+                        finalize_array(arr.ptr + cursize, oldsize - cursize, sti);
+                    }
+                    catch (Exception e)
+                    {
+                        import core.exception : onFinalizeError;
+                        onFinalizeError(sti, e);
+                    }
+                }
             }
         }
         // Note: Since we "assume" the append is safe, it means it is not shared.
@@ -1148,25 +1158,8 @@ extern (C) void[] _d_newarraymiTX(const TypeInfo ti, size_t[] dims) @weak
 }
 
 /**
-Allocate an uninitialized non-array item.
-
-This is an optimization to avoid things needed for arrays like the __arrayPad(size).
-
-- `_d_newitemU` leaves the item uninitialized
-- `_d_newitemT` zero initializes the item
-- `_d_newitemiT` uses a non-zero initializer from `TypeInfo`
-
-Used to allocate struct instances on the heap.
----
-struct Sz {int x = 0;}
-struct Si {int x = 3;}
-
-void main()
-{
-    new Sz(); // _d_newitemT(typeid(Sz))
-    new Si(); // _d_newitemiT(typeid(Si))
-}
----
+Non-template version of $(REF _d_newitemT, core,lifetime) that does not perform
+initialization. Needed for $(REF allocEntry, rt,aaA).
 
 Params:
     _ti = `TypeInfo` of item to allocate
@@ -1196,26 +1189,6 @@ extern (C) void* _d_newitemU(scope const TypeInfo _ti) pure nothrow @weak
     return p;
 }
 
-/// ditto
-extern (C) void* _d_newitemT(const TypeInfo _ti) pure nothrow @weak
-{
-    import core.stdc.string;
-    auto p = _d_newitemU(_ti);
-    memset(p, 0, _ti.tsize);
-    return p;
-}
-
-/// Same as above, for item with non-zero initializer.
-extern (C) void* _d_newitemiT(const TypeInfo _ti) pure nothrow @weak
-{
-    import core.stdc.string;
-    auto p = _d_newitemU(_ti);
-    auto init = _ti.initializer();
-    assert(init.length <= _ti.tsize);
-    memcpy(p, init.ptr, init.length);
-    return p;
-}
-
 debug(PRINTF)
 {
     extern(C) void printArrayCache()
@@ -2361,52 +2334,6 @@ unittest
     testPostBlit!(const(S))();
 }
 
-// cannot define structs inside unit test block, or they become nested structs.
-version (CoreUnittest)
-{
-    struct S1
-    {
-        int x = 5;
-    }
-    struct S2
-    {
-        int x;
-        this(int x) {this.x = x;}
-    }
-    struct S3
-    {
-        int[4] x;
-        this(int x)
-        {this.x[] = x;}
-    }
-    struct S4
-    {
-        int *x;
-    }
-
-}
-
-unittest
-{
-    auto s1 = new S1;
-    assert(s1.x == 5);
-    assert(GC.getAttr(s1) == BlkAttr.NO_SCAN);
-
-    auto s2 = new S2(3);
-    assert(s2.x == 3);
-    assert(GC.getAttr(s2) == BlkAttr.NO_SCAN);
-
-    auto s3 = new S3(1);
-    assert(s3.x == [1,1,1,1]);
-    assert(GC.getAttr(s3) == BlkAttr.NO_SCAN);
-    debug(SENTINEL) {} else
-        assert(GC.sizeOf(s3) == 16);
-
-    auto s4 = new S4;
-    assert(s4.x == null);
-    assert(GC.getAttr(s4) == 0);
-}
-
 unittest
 {
     // Bugzilla 3454 - Inconsistent flag setting in GC.realloc()
@@ -2731,41 +2658,6 @@ unittest
     assert(!test!InvalidMemoryOperationError);
 }
 
-// test struct finalizers exception handling
-debug(SENTINEL) {} else
-unittest
-{
-    bool test(E)()
-    {
-        import core.exception;
-        static struct S1
-        {
-            E exc;
-            ~this() { throw exc; }
-        }
-
-        bool caught = false;
-        S1* s = new S1(new E("test onFinalizeError"));
-        try
-        {
-            GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]);
-        }
-        catch (FinalizeError err)
-        {
-            caught = true;
-        }
-        catch (E)
-        {
-        }
-        GC.free(s);
-        return caught;
-    }
-
-    assert( test!Exception);
-    import core.exception : InvalidMemoryOperationError;
-    assert(!test!InvalidMemoryOperationError);
-}
-
 // test bug 14126
 unittest
 {
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index c6e61f78fd0..d3ebf74468c 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-8ab95ded5265379e74d507fdc252ff3d2305fc26
+8d3800bee23db56f71ef4066f74bce057fcce256
 
 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/iteration.d b/libphobos/src/std/algorithm/iteration.d
index 9f5a6ac7bc9..55ccb512b73 100644
--- a/libphobos/src/std/algorithm/iteration.d
+++ b/libphobos/src/std/algorithm/iteration.d
@@ -7939,15 +7939,23 @@ See_Also:
 $(REF nextPermutation, std,algorithm,sorting).
 */
 Permutations!Range permutations(Range)(Range r)
-if (isRandomAccessRange!Range && hasLength!Range)
 {
+    static assert(isRandomAccessRange!Range, Range.stringof,
+            " must be a RandomAccessRange");
+    static assert(hasLength!Range, Range.stringof
+            , " must have a length");
+
     return typeof(return)(r);
 }
 
 /// ditto
 struct Permutations(Range)
-if (isRandomAccessRange!Range && hasLength!Range)
 {
+    static assert(isRandomAccessRange!Range, Range.stringof,
+            " must be a RandomAccessRange");
+    static assert(hasLength!Range, Range.stringof
+            , " must have a length");
+
     private size_t[] _indices, _state;
     private Range _r;
     private bool _empty;
diff --git a/libphobos/src/std/bigint.d b/libphobos/src/std/bigint.d
index 33d0eae7ced..50f88da6055 100644
--- a/libphobos/src/std/bigint.d
+++ b/libphobos/src/std/bigint.d
@@ -254,11 +254,11 @@ public:
 
         static if (op=="+")
         {
-            data = BigUint.addOrSubInt(data, u, sign != (y<0), sign);
+            data = BigUint.addOrSubInt!ulong(data, u, wantSub: sign != (y<0), sign);
         }
         else static if (op=="-")
         {
-            data = BigUint.addOrSubInt(data, u, sign == (y<0), sign);
+            data = BigUint.addOrSubInt!ulong(data, u, wantSub: sign == (y<0), sign);
         }
         else static if (op=="*")
         {
@@ -613,7 +613,7 @@ public:
         static if (op == "-")
         {
             r.sign = sign;
-            r.data = BigUint.addOrSubInt(data, u, sign == (y<0), r.sign);
+            r.data = BigUint.addOrSubInt!ulong(data, u, wantSub: sign == (y<0), r.sign);
             r.negate();
         }
         return r;
@@ -670,12 +670,12 @@ public:
     {
         static if (op=="++")
         {
-            data = BigUint.addOrSubInt(data, 1UL, sign, sign);
+            data = BigUint.addOrSubInt!ulong(data, 1UL, wantSub: sign, sign);
             return this;
         }
         else static if (op=="--")
         {
-            data = BigUint.addOrSubInt(data, 1UL, !sign, sign);
+            data = BigUint.addOrSubInt!ulong(data, 1UL, wantSub: !sign, sign);
             return this;
         }
     }
diff --git a/libphobos/src/std/checkedint.d b/libphobos/src/std/checkedint.d
index 79597e8dacc..cec1dc1a2db 100644
--- a/libphobos/src/std/checkedint.d
+++ b/libphobos/src/std/checkedint.d
@@ -2129,16 +2129,16 @@ static:
         {
             // Not value convertible, only viable option is rhs fits within the
             // bounds of Lhs
-            static if (ProperCompare.hookOpCmp(Rhs.min, Lhs.min) < 0)
+            static if (ProperCompare.hookOpCmp!(Rhs, Lhs)(lhs: Rhs.min, rhs: Lhs.min) < 0)
             {
                 // Example: hookOpCast!short(int(42)), hookOpCast!uint(int(42))
-                if (ProperCompare.hookOpCmp(rhs, Lhs.min) < 0)
+                if (ProperCompare.hookOpCmp!(Rhs, Lhs)(lhs: rhs, rhs: Lhs.min) < 0)
                     return defaultValue!Lhs;
             }
-            static if (ProperCompare.hookOpCmp(Rhs.max, Lhs.max) > 0)
+            static if (ProperCompare.hookOpCmp!(Rhs, Lhs)(lhs: Rhs.max, rhs: Lhs.max) > 0)
             {
                 // Example: hookOpCast!int(uint(42))
-                if (ProperCompare.hookOpCmp(rhs, Lhs.max) > 0)
+                if (ProperCompare.hookOpCmp!(Rhs, Lhs)(lhs: rhs, rhs: Lhs.max) > 0)
                     return defaultValue!Lhs;
             }
             return cast(Lhs) rhs;
diff --git a/libphobos/src/std/conv.d b/libphobos/src/std/conv.d
index aef23655f2a..89d4e5eafa2 100644
--- a/libphobos/src/std/conv.d
+++ b/libphobos/src/std/conv.d
@@ -102,21 +102,6 @@ private auto convError(S, T)(S source, string fn = __FILE__, size_t ln = __LINE_
     return new ConvException(msg, fn, ln);
 }
 
-private auto convError(S, T)(S source, int radix, string fn = __FILE__, size_t ln = __LINE__)
-{
-    string msg;
-
-    if (source.empty)
-        msg = text("Unexpected end of input when converting from type " ~ S.stringof ~ " base ", radix,
-                " to type " ~ T.stringof);
-    else
-        msg = text("Unexpected '", source.front,
-            "' when converting from type " ~ S.stringof ~ " base ", radix,
-            " to type " ~ T.stringof);
-
-    return new ConvException(msg, fn, ln);
-}
-
 @safe pure/* nothrow*/  // lazy parameter bug
 private auto parseError(lazy string msg, string fn = __FILE__, size_t ln = __LINE__)
 {
@@ -1023,7 +1008,15 @@ if (!(is(S : T) &&
     else static if (isIntegral!S && !is(S == enum))
     {
         // other integral-to-string conversions with default radix
-        return toImpl!(T, S)(value, 10);
+
+        import core.internal.string : signedToTempString, unsignedToTempString;
+
+        alias EEType = Unqual!(ElementEncodingType!T);
+        EEType[long.sizeof * 3 + 1] buf = void;
+        EEType[] t = isSigned!S
+            ?   signedToTempString!(10, false, EEType)(value, buf)
+            : unsignedToTempString!(10, false, EEType)(value, buf);
+        return t.dup;
     }
     else static if (is(S == void[]) || is(S == const(void)[]) || is(S == immutable(void)[]))
     {
@@ -5726,33 +5719,13 @@ if ((radix == 2 || radix == 8 || radix == 10 || radix == 16) &&
         {
             void initialize(UT value)
             {
-                bool neg = false;
-                if (value < 10)
-                {
-                    if (value >= 0)
-                    {
-                        lwr = 0;
-                        upr = 1;
-                        buf[0] = cast(char)(cast(uint) value + '0');
-                        return;
-                    }
-                    value = -value;
-                    neg = true;
-                }
-                auto i = cast(uint) buf.length - 1;
-                while (cast(Unsigned!UT) value >= 10)
-                {
-                    buf[i] = cast(ubyte)('0' + cast(Unsigned!UT) value % 10);
-                    value = unsigned(value) / 10;
-                    --i;
-                }
-                buf[i] = cast(char)(cast(uint) value + '0');
-                if (neg)
-                {
-                    buf[i - 1] = '-';
-                    --i;
-                }
-                lwr = i;
+                import core.internal.string : signedToTempString, unsignedToTempString;
+
+                char[] t = value < 0
+                    ?   signedToTempString!(10, false, char)(value, buf)
+                    : unsignedToTempString!(10, false, char)(value, buf);
+
+                lwr = cast(uint) (buf.length - t.length);
                 upr = cast(uint) buf.length;
             }
 
diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d
index de9afbbf7d5..02d5cf8b6d3 100644
--- a/libphobos/src/std/experimental/allocator/mallocator.d
+++ b/libphobos/src/std/experimental/allocator/mallocator.d
@@ -376,17 +376,17 @@ version (Posix)
 {
     // https://issues.dlang.org/show_bug.cgi?id=16398
     // test the "pseudo" alignedReallocate for Posix
-    void[] s = AlignedMallocator.instance.alignedAllocate(16, 32);
-    (cast(ubyte[]) s)[] = ubyte(1);
-    AlignedMallocator.instance.alignedReallocate(s, 32, 32);
+    void[] b = AlignedMallocator.instance.alignedAllocate(16, 32);
+    (cast(ubyte[]) b)[] = ubyte(1);
+    AlignedMallocator.instance.alignedReallocate(b, 32, 32);
     ubyte[16] o;
     o[] = 1;
-    assert((cast(ubyte[]) s)[0 .. 16] == o);
-    AlignedMallocator.instance.alignedReallocate(s, 4, 32);
-    assert((cast(ubyte[]) s)[0 .. 3] == o[0 .. 3]);
-    AlignedMallocator.instance.alignedReallocate(s, 128, 32);
-    assert((cast(ubyte[]) s)[0 .. 3] == o[0 .. 3]);
-    AlignedMallocator.instance.deallocate(s);
+    assert((cast(ubyte[]) b)[0 .. 16] == o);
+    AlignedMallocator.instance.alignedReallocate(b, 4, 32);
+    assert((cast(ubyte[]) b)[0 .. 3] == o[0 .. 3]);
+    AlignedMallocator.instance.alignedReallocate(b, 128, 32);
+    assert((cast(ubyte[]) b)[0 .. 3] == o[0 .. 3]);
+    AlignedMallocator.instance.deallocate(b);
 
     void[] c;
     AlignedMallocator.instance.alignedReallocate(c, 32, 32);
diff --git a/libphobos/src/std/getopt.d b/libphobos/src/std/getopt.d
index 42aeb4099e7..cb97eebe31b 100644
--- a/libphobos/src/std/getopt.d
+++ b/libphobos/src/std/getopt.d
@@ -685,6 +685,7 @@ private void getoptImpl(T...)(ref string[] args, ref configuration cfg,
 
     import std.algorithm.mutation : remove;
     import std.conv : to;
+    import std.uni : toLower;
     static if (opts.length)
     {
         static if (is(typeof(opts[0]) : config))
@@ -708,7 +709,10 @@ private void getoptImpl(T...)(ref string[] args, ref configuration cfg,
 
             if (optionHelp.optLong.length)
             {
-                assert(optionHelp.optLong !in visitedLongOpts,
+                auto name = optionHelp.optLong;
+                if (!cfg.caseSensitive)
+                    name = name.toLower();
+                assert(name !in visitedLongOpts,
                     "Long option " ~ optionHelp.optLong ~ " is multiply defined");
 
                 visitedLongOpts[optionHelp.optLong] = [];
@@ -716,7 +720,10 @@ private void getoptImpl(T...)(ref string[] args, ref configuration cfg,
 
             if (optionHelp.optShort.length)
             {
-                assert(optionHelp.optShort !in visitedShortOpts,
+                auto name = optionHelp.optShort;
+                if (!cfg.caseSensitive)
+                    name = name.toLower();
+                assert(name !in visitedShortOpts,
                     "Short option " ~ optionHelp.optShort
                     ~ " is multiply defined");
 
@@ -1779,6 +1786,14 @@ void defaultGetoptFormatter(Output)(Output output, string text, Option[] opt, st
     assertThrown!AssertError(getopt(args, "abc", &abc, "abc", &abc));
     assertThrown!AssertError(getopt(args, "abc|a", &abc, "def|a", &def));
     assertNotThrown!AssertError(getopt(args, "abc", &abc, "def", &def));
+
+    // https://issues.dlang.org/show_bug.cgi?id=23940
+    assertThrown!AssertError(getopt(args,
+            "abc", &abc, "ABC", &def));
+    assertThrown!AssertError(getopt(args, config.caseInsensitive,
+            "abc", &abc, "ABC", &def));
+    assertNotThrown!AssertError(getopt(args, config.caseSensitive,
+            "abc", &abc, "ABC", &def));
 }
 
 // https://issues.dlang.org/show_bug.cgi?id=17327 repeated option use
diff --git a/libphobos/src/std/path.d b/libphobos/src/std/path.d
index 63d60d1d77f..e81f2b6b855 100644
--- a/libphobos/src/std/path.d
+++ b/libphobos/src/std/path.d
@@ -3955,7 +3955,7 @@ if (isConvertibleToString!Range)
     }
     -----
 */
-string expandTilde(string inputPath) @safe nothrow
+string expandTilde(return scope const string inputPath) @safe nothrow
 {
     version (Posix)
     {
@@ -4138,7 +4138,7 @@ string expandTilde(string inputPath) @safe nothrow
 }
 
 ///
-@system unittest
+@safe unittest
 {
     version (Posix)
     {
@@ -4153,7 +4153,7 @@ string expandTilde(string inputPath) @safe nothrow
     }
 }
 
-@system unittest
+@safe unittest
 {
     version (Posix)
     {
@@ -4205,6 +4205,26 @@ string expandTilde(string inputPath) @safe nothrow
     }
 }
 
+@safe unittest
+{
+    version (Posix)
+    {
+        import std.process : environment;
+
+        string testPath(scope const string source_path) {
+            return source_path.expandTilde;
+        }
+
+        auto oldHome = environment["HOME"];
+        scope(exit) environment["HOME"] = oldHome;
+
+        environment["HOME"] = "dmd/test";
+        assert(testPath("~/") == "dmd/test/");
+        assert(testPath("~") == "dmd/test");
+    }
+}
+
+
 version (StdUnittest)
 {
 private:
diff --git a/libphobos/src/std/range/package.d b/libphobos/src/std/range/package.d
index 7a724b0f718..d37c6416434 100644
--- a/libphobos/src/std/range/package.d
+++ b/libphobos/src/std/range/package.d
@@ -232,7 +232,7 @@ module std.range;
 public import std.array;
 public import std.range.interfaces;
 public import std.range.primitives;
-public import std.typecons : Flag, Yes, No;
+public import std.typecons : Flag, Yes, No, Rebindable, rebindable;
 
 import std.internal.attributes : betterC;
 import std.meta : aliasSeqOf, allSatisfy, anySatisfy, staticMap;
@@ -978,6 +978,11 @@ if (Ranges.length > 0 &&
             static if (bidirectional) size_t backIndex;
             else enum backIndex = source.length;
 
+            this(typeof(Result.tupleof) fields)
+            {
+                this.tupleof = fields;
+            }
+
         public:
             this(R input)
             {
@@ -1376,25 +1381,34 @@ if (Ranges.length > 0 &&
             static if (allSatisfy!(hasLength, R) && allSatisfy!(hasSlicing, R))
                 auto opSlice(size_t begin, size_t end) return scope
                 {
-                    auto result = this;
+                    // force staticMap type conversion to Rebindable
+                    static struct ResultRanges
+                    {
+                        staticMap!(Rebindable, Ranges) fields;
+                    }
+                    auto sourceI(size_t i)() => rebindable(this.source[i]);
+                    auto resultRanges = ResultRanges(staticMap!(sourceI, aliasSeqOf!(R.length.iota))).fields;
+                    size_t resultFrontIndex = this.frontIndex;
+                    static if (bidirectional)
+                        size_t resultBackIndex = this.backIndex;
 
                     sw: switch (frontIndex)
                     {
                         static foreach (i; 0 .. R.length)
                         {
                         case i:
-                            immutable len = result.source[i].length;
+                            immutable len = resultRanges[i].length;
                             if (len <= begin)
                             {
-                                result.source[i] = result.source[i]
+                                resultRanges[i] = resultRanges[i]
                                     [len .. len];
                                 begin -= len;
-                                result.frontIndex++;
+                                resultFrontIndex++;
                                 goto case;
                             }
                             else
                             {
-                                result.source[i] = result.source[i]
+                                resultRanges[i] = resultRanges[i]
                                     [begin .. len];
                                 break sw;
                             }
@@ -1418,18 +1432,18 @@ if (Ranges.length > 0 &&
                         static foreach_reverse (i; 1 .. R.length + 1)
                         {
                         case i:
-                            immutable len = result.source[i-1].length;
+                            immutable len = resultRanges[i-1].length;
                             if (len <= cut)
                             {
-                                result.source[i-1] = result.source[i-1]
+                                resultRanges[i-1] = resultRanges[i-1]
                                     [0 .. 0];
                                 cut -= len;
-                                result.backIndex--;
+                                resultBackIndex--;
                                 goto case;
                             }
                             else
                             {
-                                result.source[i-1] = result.source[i-1]
+                                resultRanges[i-1] = resultRanges[i-1]
                                     [0 .. len - cut];
                                 break sw2;
                             }
@@ -1445,7 +1459,10 @@ if (Ranges.length > 0 &&
                         assert(0, "Internal library error. Please report it.");
                     }
 
-                    return result;
+                    static if (bidirectional)
+                        return Result(resultRanges, resultFrontIndex, resultBackIndex);
+                    else
+                        return Result(resultRanges, resultFrontIndex);
                 }
         }
         return Result(rs);
@@ -1643,6 +1660,18 @@ pure @safe unittest
     assert(equal(r, "foobar"));
 }
 
+// https://issues.dlang.org/show_bug.cgi?id=23844
+pure @safe unittest
+{
+    struct S
+    {
+        immutable int value;
+    }
+
+    auto range = chain(only(S(5)), only(S(6)));
+    assert(range.array == [S(5), S(6)]);
+}
+
 pure @safe nothrow @nogc unittest
 {
     // support non-copyable items
diff --git a/libphobos/src/std/system.d b/libphobos/src/std/system.d
index 55fcfd773b7..aa672a59dd3 100644
--- a/libphobos/src/std/system.d
+++ b/libphobos/src/std/system.d
@@ -82,5 +82,77 @@ immutable
     /// The endianness that the program was compiled for.
     version (LittleEndian) Endian endian = Endian.littleEndian;
     else                  Endian endian = Endian.bigEndian;
+    /++
+        Instruction Set Architecture.
+
+        Note:
+            This is intended for cases where you need a value representing the
+            instruction set architecture at runtime. If you're doing something
+            which should compile differently depending on instruction set
+            architecture, then please use `version (X86_64)`, `version (ARM)`,
+            etc.
+
+        See_Also:
+            $(DDSUBLINK spec/version,PredefinedVersions, Predefined Versions)
+      +/
+    enum ISA
+    {
+        x86,   /// Intel and AMD 32-bit processors
+        x86_64, /// Intel and AMD 64-bit processors
+        arm, /// The ARM architecture (32-bit) (AArch32 et al)
+        aarch64, /// The Advanced RISC Machine architecture (64-bit)
+        asmJS, /// The asm.js intermediate programming language
+        avr, /// 8-bit Atmel AVR Microcontrollers
+        epiphany, /// The Epiphany architecture
+        ppc, /// The PowerPC architecture, 32-bit
+        ppc64, /// The PowerPC architecture, 64-bit
+        ia64, /// The Itanium architecture (64-bit)
+        mips32, /// The MIPS architecture, 32-bit
+        mips64, /// The MIPS architecture, 64-bit
+        msp430, /// The MSP430 architecture
+        nvptx, /// The Nvidia Parallel Thread Execution (PTX) architecture, 32-bit
+        nvptx64, /// The Nvidia Parallel Thread Execution (PTX) architecture, 64-bit
+        riscv32, /// The RISC-V architecture, 32-bit
+        riscv64, /// The RISC-V architecture, 64-bit
+        sparc, /// The SPARC architecture, 32-bit
+        sparc64, /// The SPARC architecture, 64-bit
+        s390, /// The System/390 architecture, 32-bit
+        systemZ, /// The System Z architecture, 64-bit
+        hppa, /// The HP PA-RISC architecture, 32-bit
+        hppa64, /// The HP PA-RISC architecture, 64-bit
+        sh, /// The SuperH architecture, 32-bit
+        webAssembly, /// The WebAssembly virtual ISA (instruction set architecture), 32-bit
+        alpha, /// The Alpha architecture
+        unknown, /// Unknown
+    }
+
+    /// The instruction set architecture that the program was compiled for.
+    version (X86) ISA instructionSetArchitecture = ISA.x86;
+    else version (X86_64)   ISA instructionSetArchitecture = ISA.x86_64;
+    else version (ARM)      ISA instructionSetArchitecture = ISA.arm;
+    else version (AArch64)  ISA instructionSetArchitecture = ISA.aarch64;
+    else version (AsmJS)    ISA instructionSetArchitecture = ISA.asmJS;
+    else version (AVR)      ISA instructionSetArchitecture = ISA.avr;
+    else version (Epiphany) ISA instructionSetArchitecture = ISA.epiphany;
+    else version (PPC)      ISA instructionSetArchitecture = ISA.ppc;
+    else version (PPC64)    ISA instructionSetArchitecture = ISA.ppc64;
+    else version (IA64)     ISA instructionSetArchitecture = ISA.ia64;
+    else version (MIPS32)   ISA instructionSetArchitecture = ISA.mips32;
+    else version (MIPS64)   ISA instructionSetArchitecture = ISA.mips64;
+    else version (MSP430)   ISA instructionSetArchitecture = ISA.msp430;
+    else version (NVPTX)    ISA instructionSetArchitecture = ISA.nvptx;
+    else version (NVPTX64)  ISA instructionSetArchitecture = ISA.nvptx64;
+    else version (RISCV32)  ISA instructionSetArchitecture = ISA.riscv32;
+    else version (RISCV64)  ISA instructionSetArchitecture = ISA.riscv64;
+    else version (SPARC)    ISA instructionSetArchitecture = ISA.sparc;
+    else version (SPARC64)  ISA instructionSetArchitecture = ISA.sparc64;
+    else version (S390)     ISA instructionSetArchitecture = ISA.s390;
+    else version (SystemZ)  ISA instructionSetArchitecture = ISA.systemZ;
+    else version (HPPA)     ISA instructionSetArchitecture = ISA.hppa;
+    else version (HPPA64)   ISA instructionSetArchitecture = ISA.hppa64;
+    else version (SH)       ISA instructionSetArchitecture = ISA.sh;
+    else version (WebAssembly) ISA instructionSetArchitecture = ISA.webAssembly;
+    else version (Alpha)    ISA instructionSetArchitecture = ISA.alpha;
+    else ISA instructionSetArchitecture = ISA.unknown;
 }
 
diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d
index d267e711e6a..0748d5251e0 100644
--- a/libphobos/src/std/typecons.d
+++ b/libphobos/src/std/typecons.d
@@ -7406,11 +7406,11 @@ pure @system unittest
     foreach (MyRefCounted; AliasSeq!(SafeRefCounted, RefCounted))
     {
         MyRefCounted!int* p;
+        auto rc1 = MyRefCounted!int(5);
+        p = &rc1;
+        assert(rc1 == 5);
+        assert(rc1._refCounted._store._count == 1);
         {
-            auto rc1 = MyRefCounted!int(5);
-            p = &rc1;
-            assert(rc1 == 5);
-            assert(rc1._refCounted._store._count == 1);
             auto rc2 = rc1;
             assert(rc1._refCounted._store._count == 2);
             // Reference semantics
@@ -7421,6 +7421,8 @@ pure @system unittest
             rc1 = rc2;
             assert(rc1._refCounted._store._count == 2);
         }
+        // Artificially end scope of rc1 by calling ~this() explicitly
+        rc1.__xdtor();
         assert(p._refCounted._store == null);
 
         // [Safe]RefCounted as a member
