diff mbox series

[12,committed] d: Merge upstream dmd a53934d18, phobos 604534d7c.

Message ID 20220515231413.3908645-1-ibuclaw@gdcproject.org
State New
Headers show
Series [12,committed] d: Merge upstream dmd a53934d18, phobos 604534d7c. | expand

Commit Message

Iain Buclaw May 15, 2022, 11:14 p.m. UTC
Hi,

Upstream dmd has now released v2.100.0, this patch merges in the
latest bug fixes since the last sync-up of the release branch.

D front-end changes:

    - Import dmd v2.100.0 release.
    - The new behavior of issuing deprecation messages for scope
      violations has been reverted until next release.

Phobos changes:

    - Import phobos v2.100.0 release.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and
committed to the releases/gcc-12 branch.

Regards,
Iain.

---
gcc/d/ChangeLog:

	* dmd/MERGE: Merge upstream dmd a53934d18.
	* dmd/VERSION: Update version to v2.100.0.
	* d-codegen.cc (d_decl_context): Use resolvedLinkage to get
	declaration linkage.
	(build_struct_literal): Track offset in bits.
	* d-gimplify.cc (d_gimplify_modify_expr): Check both operands for a
	bit-field reference.
	* d-lang.cc (d_post_options): Set flag_rtti and flag_exceptions if
	-fno-druntime was seen on command-line.
	(d_type_promotes_to): Use resolvedLinkage to get declaration linkage.
	* decl.cc (make_thunk): Likewise.
	* types.cc (layout_aggregate_members): Ignore anonymous fields in
	total count.

libphobos/ChangeLog:

	* src/MERGE: Merge upstream phobos 604534d7c.
---
 gcc/d/d-codegen.cc                            | 17 ++++-----
 gcc/d/d-gimplify.cc                           |  3 +-
 gcc/d/d-lang.cc                               | 16 +++++++--
 gcc/d/decl.cc                                 |  4 +--
 gcc/d/dmd/MERGE                               |  2 +-
 gcc/d/dmd/VERSION                             |  2 +-
 gcc/d/dmd/clone.d                             | 22 +++++++-----
 gcc/d/dmd/dclass.d                            |  2 +-
 gcc/d/dmd/declaration.d                       | 10 ++++--
 gcc/d/dmd/declaration.h                       |  3 +-
 gcc/d/dmd/dmangle.d                           | 10 +++---
 gcc/d/dmd/dsymbolsem.d                        | 20 +++++------
 gcc/d/dmd/dtemplate.d                         |  2 +-
 gcc/d/dmd/dtoh.d                              | 19 ++++++----
 gcc/d/dmd/escape.d                            |  2 +-
 gcc/d/dmd/expressionsem.d                     | 35 +++++++++++++++++--
 gcc/d/dmd/func.d                              | 17 ++++-----
 gcc/d/dmd/initsem.d                           | 12 +++++++
 gcc/d/dmd/json.d                              |  2 +-
 gcc/d/dmd/mtype.d                             | 25 +++++++++++--
 gcc/d/dmd/objc.d                              |  6 ++--
 gcc/d/dmd/semantic2.d                         | 15 ++++----
 gcc/d/dmd/semantic3.d                         |  2 +-
 gcc/d/dmd/traits.d                            |  6 ++--
 gcc/d/types.cc                                | 10 ++++--
 gcc/testsuite/gdc.test/compilable/test23097.d | 33 +++++++++++++++++
 .../extra-files/test23109/object.d            | 17 +++++++++
 .../gdc.test/fail_compilation/fail12604.d     |  4 +--
 .../gdc.test/fail_compilation/fail23108a.d    | 16 +++++++++
 .../gdc.test/fail_compilation/fail23108b.d    | 18 ++++++++++
 .../gdc.test/fail_compilation/fail23109.d     | 12 +++++++
 .../gdc.test/fail_compilation/fail3703.d      |  4 +--
 .../gdc.test/fail_compilation/fail_scope.d    | 30 ++++++++--------
 .../gdc.test/fail_compilation/ice23097.d      | 28 +++++++++++++++
 .../fail_compilation/imports/test23109a.d     | 10 ++++++
 .../fail_compilation/imports/test23109b.d     | 10 ++++++
 .../fail_compilation/imports/test23109c.d     |  3 ++
 .../gdc.test/fail_compilation/test9150.d      |  2 +-
 gcc/testsuite/gdc.test/runnable/test20734.d   | 28 +++++++++++++++
 libphobos/src/MERGE                           |  2 +-
 40 files changed, 375 insertions(+), 106 deletions(-)
 create mode 100644 gcc/testsuite/gdc.test/compilable/test23097.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/extra-files/test23109/object.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23108a.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23108b.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23109.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/ice23097.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/test23109a.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/test23109b.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/test23109c.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/test20734.d
diff mbox series

Patch

diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index bb96b2f8d28..22090a8c755 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -76,7 +76,7 @@  d_decl_context (Dsymbol *dsym)
 	 but only for extern(D) symbols.  */
       if (parent->isModule ())
 	{
-	  if ((decl != NULL && decl->linkage != LINK::d)
+	  if ((decl != NULL && decl->resolvedLinkage () != LINK::d)
 	      || (ad != NULL && ad->classKind != ClassKind::d))
 	    return NULL_TREE;
 
@@ -1165,7 +1165,7 @@  build_struct_literal (tree type, vec <constructor_elt, va_gc> *init)
     }
 
   vec <constructor_elt, va_gc> *ve = NULL;
-  HOST_WIDE_INT offset = 0;
+  HOST_WIDE_INT bitoffset = 0;
   bool constant_p = true;
   bool finished = false;
 
@@ -1210,11 +1210,11 @@  build_struct_literal (tree type, vec <constructor_elt, va_gc> *init)
 
       if (is_initialized)
 	{
-	  HOST_WIDE_INT fieldpos = int_byte_position (field);
+	  HOST_WIDE_INT fieldpos = int_bit_position (field);
 	  gcc_assert (value != NULL_TREE);
 
 	  /* Must not initialize fields that overlap.  */
-	  if (fieldpos < offset)
+	  if (fieldpos < bitoffset)
 	    {
 	      /* Find the nearest user defined type and field.  */
 	      tree vtype = type;
@@ -1243,12 +1243,9 @@  build_struct_literal (tree type, vec <constructor_elt, va_gc> *init)
 	    finished = true;
 	}
 
-      /* Move offset to the next position in the struct.  */
-      if (TREE_CODE (type) == RECORD_TYPE)
-	{
-	  offset = int_byte_position (field)
-	    + int_size_in_bytes (TREE_TYPE (field));
-	}
+      /* Move bit offset to the next position in the struct.  */
+      if (TREE_CODE (type) == RECORD_TYPE && DECL_SIZE (field))
+	bitoffset = int_bit_position (field) + tree_to_shwi (DECL_SIZE (field));
 
       /* If all initializers have been assigned, there's nothing else to do.  */
       if (vec_safe_is_empty (init))
diff --git a/gcc/d/d-gimplify.cc b/gcc/d/d-gimplify.cc
index a98089b7cca..36b76da3acc 100644
--- a/gcc/d/d-gimplify.cc
+++ b/gcc/d/d-gimplify.cc
@@ -109,7 +109,8 @@  d_gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
     }
 
   /* Same as above, but for bit-field assignments.  */
-  if (bit_field_ref (op0) && TREE_TYPE (op0) != TREE_TYPE (op1))
+  if ((bit_field_ref (op0) || bit_field_ref (op1))
+      && TREE_TYPE (op0) != TREE_TYPE (op1))
     {
       TREE_OPERAND (*expr_p, 1) = convert (TREE_TYPE (op0), op1);
       return GS_OK;
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index 9adcabdf7cf..dc8560f799a 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -904,16 +904,26 @@  d_post_options (const char ** fn)
 	? CHECKENABLEoff : CHECKENABLEon;
     }
 
+  /* When not linking against D runtime, turn off all code generation that
+     would otherwise reference it.  */
   if (global.params.betterC)
     {
       if (!OPTION_SET_P (flag_moduleinfo))
 	global.params.useModuleInfo = false;
 
+      /* Ensure that the front-end options are in sync with the `-frtti' and
+	 `-fexceptions' flags.  */
       if (!OPTION_SET_P (flag_rtti))
-	global.params.useTypeInfo = false;
+	{
+	  global.params.useTypeInfo = false;
+	  flag_rtti = false;
+	}
 
       if (!OPTION_SET_P (flag_exceptions))
-	global.params.useExceptions = false;
+	{
+	  global.params.useExceptions = false;
+	  flag_exceptions = false;
+	}
 
       global.params.checkAction = CHECKACTION_C;
     }
@@ -1558,7 +1568,7 @@  d_type_promotes_to (tree type)
   /* Promotions are only applied on unnamed function arguments for declarations
      with `extern(C)' or `extern(C++)' linkage.  */
   if (cfun && DECL_LANG_FRONTEND (cfun->decl)
-      && DECL_LANG_FRONTEND (cfun->decl)->linkage != LINK::d)
+      && DECL_LANG_FRONTEND (cfun->decl)->resolvedLinkage () != LINK::d)
     {
       /* In [type/integer-promotions], integer promotions are conversions of the
 	 following types:
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index 86ea1761f4f..f5c21078aad 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -1845,7 +1845,7 @@  make_thunk (FuncDeclaration *decl, int offset)
      forcing a D local thunk to be emitted.  */
   const char *ident;
 
-  if (decl->linkage == LINK::cpp)
+  if (decl->resolvedLinkage () == LINK::cpp)
     ident = target.cpp.thunkMangle (decl, offset);
   else
     {
@@ -1862,7 +1862,7 @@  make_thunk (FuncDeclaration *decl, int offset)
 
   d_keep (thunk);
 
-  if (decl->linkage != LINK::cpp)
+  if (decl->resolvedLinkage () != LINK::cpp)
     free (CONST_CAST (char *, ident));
 
   if (!DECL_EXTERNAL (function))
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 73697fba8e6..d538621ba83 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@ 
-88de5e369b2c322e55174ae4f3bef5ad0c0c0930
+a53934d18eecccbf677cd32a4febeff3bc0ee292
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION
index 0ad60f92b8f..5ea2ba0d8ec 100644
--- a/gcc/d/dmd/VERSION
+++ b/gcc/d/dmd/VERSION
@@ -1 +1 @@ 
-v2.100.0-rc.1
+v2.100.0
diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d
index 9c8c1c316bf..75a16bd2da4 100644
--- a/gcc/d/dmd/clone.d
+++ b/gcc/d/dmd/clone.d
@@ -563,9 +563,12 @@  FuncDeclaration buildXopEquals(StructDeclaration sd, Scope* sc)
         e = new DotIdExp(sd.loc, e, Id.object);
         e = new DotIdExp(sd.loc, e, id);
         e = e.expressionSemantic(sc);
-        Dsymbol s = getDsymbol(e);
-        assert(s);
-        sd.xerreq = s.isFuncDeclaration();
+        if (!e.isErrorExp())
+        {
+            Dsymbol s = getDsymbol(e);
+            assert(s);
+            sd.xerreq = s.isFuncDeclaration();
+        }
     }
     Loc declLoc; // loc is unnecessary so __xopEquals is never called directly
     Loc loc; // loc is unnecessary so errors are gagged
@@ -684,9 +687,12 @@  FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc)
         e = new DotIdExp(sd.loc, e, Id.object);
         e = new DotIdExp(sd.loc, e, id);
         e = e.expressionSemantic(sc);
-        Dsymbol s = getDsymbol(e);
-        assert(s);
-        sd.xerrcmp = s.isFuncDeclaration();
+        if (!e.isErrorExp())
+        {
+            Dsymbol s = getDsymbol(e);
+            assert(s);
+            sd.xerrcmp = s.isFuncDeclaration();
+        }
     }
     Loc declLoc; // loc is unnecessary so __xopCmp is never called directly
     Loc loc; // loc is unnecessary so errors are gagged
@@ -867,7 +873,7 @@  void buildDtors(AggregateDeclaration ad, Scope* sc)
 
     // Build the field destructor (`ad.fieldDtor`), if needed.
     // If the user dtor is an extern(C++) prototype, then we expect it performs a full-destruction and skip building.
-    const bool dtorIsCppPrototype = ad.userDtors.dim && ad.userDtors[0].linkage == LINK.cpp && !ad.userDtors[0].fbody;
+    const bool dtorIsCppPrototype = ad.userDtors.dim && ad.userDtors[0]._linkage == LINK.cpp && !ad.userDtors[0].fbody;
     if (!dtorIsCppPrototype)
     {
         Expression e = null;
@@ -1019,7 +1025,7 @@  void buildDtors(AggregateDeclaration ad, Scope* sc)
 
     // Set/build `ad.dtor`.
     // On Windows, the dtor in the vtable is a shim with different signature.
-    ad.dtor = (ad.aggrDtor && ad.aggrDtor.linkage == LINK.cpp && !target.cpp.twoDtorInVtable)
+    ad.dtor = (ad.aggrDtor && ad.aggrDtor._linkage == LINK.cpp && !target.cpp.twoDtorInVtable)
         ? buildWindowsCppDtor(ad, ad.aggrDtor, sc)
         : ad.aggrDtor;
 
diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d
index 15ac8d91735..a4a2abf4144 100644
--- a/gcc/d/dmd/dclass.d
+++ b/gcc/d/dmd/dclass.d
@@ -984,7 +984,7 @@  extern (C++) class ClassDeclaration : AggregateDeclaration
             auto var = new VarDeclaration(loc, vtype, Identifier.idPool("__vtbl"), null, STC.immutable_ | STC.static_);
             var.addMember(null, this);
             var.isdataseg = 1;
-            var.linkage = LINK.d;
+            var._linkage = LINK.d;
             var.semanticRun = PASS.semanticdone; // no more semantic wanted
             vtblsym = var;
         }
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index a533d30ca80..7b50c050487 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -221,7 +221,7 @@  extern (C++) abstract class Declaration : Dsymbol
     Type originalType;  // before semantic analysis
     StorageClass storage_class = STC.undefined_;
     Visibility visibility;
-    LINK linkage = LINK.default_;
+    LINK _linkage = LINK.default_; // may be `LINK.system`; use `resolvedLinkage()` to resolve it
     short inuse;          // used to detect cycles
 
     ubyte adFlags;         // control re-assignment of AliasDeclaration (put here for packing reasons)
@@ -420,6 +420,12 @@  extern (C++) abstract class Declaration : Dsymbol
         return (storage_class & STC.static_) != 0;
     }
 
+    /// Returns the linkage, resolving the target-specific `System` one.
+    final LINK resolvedLinkage() const
+    {
+        return _linkage == LINK.system ? target.systemLinkage() : _linkage;
+    }
+
     bool isDelete()
     {
         return false;
@@ -1919,7 +1925,7 @@  extern (C++) class TypeInfoDeclaration : VarDeclaration
         this.tinfo = tinfo;
         storage_class = STC.static_ | STC.gshared;
         visibility = Visibility(Visibility.Kind.public_);
-        linkage = LINK.c;
+        _linkage = LINK.c;
         alignment.set(target.ptrsize);
     }
 
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index 7e51b057dc1..6fe4a221c3b 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -115,7 +115,7 @@  public:
     Type *originalType;         // before semantic analysis
     StorageClass storage_class;
     Visibility visibility;
-    LINK linkage;
+    LINK _linkage;              // may be `LINK::system`; use `resolvedLinkage()` to resolve it
     short inuse;                // used to detect cycles
     uint8_t adFlags;
     Symbol* isym;               // import version of csym
@@ -127,6 +127,7 @@  public:
     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
 
     bool isStatic() const { return (storage_class & STCstatic) != 0; }
+    LINK resolvedLinkage() const; // returns the linkage, resolving the target-specific `System` one
     virtual bool isDelete();
     virtual bool isDataseg();
     virtual bool isThreadlocal();
diff --git a/gcc/d/dmd/dmangle.d b/gcc/d/dmd/dmangle.d
index 3d9730348f5..76042969b9b 100644
--- a/gcc/d/dmd/dmangle.d
+++ b/gcc/d/dmd/dmangle.d
@@ -1337,17 +1337,17 @@  extern (D) const(char)[] externallyMangledIdentifier(Declaration d)
 {
     assert(!d.mangleOverride, "mangle overrides should have been handled earlier");
 
+    const linkage = d.resolvedLinkage();
     const par = d.toParent(); //toParent() skips over mixin templates
-    if (!par || par.isModule() || d.linkage == LINK.cpp ||
-        (d.linkage == LINK.c && d.isCsymbol() &&
+    if (!par || par.isModule() || linkage == LINK.cpp ||
+        (linkage == LINK.c && d.isCsymbol() &&
          (d.isFuncDeclaration() ||
           (d.isVarDeclaration() && d.isDataseg() && d.storage_class & STC.extern_))))
     {
-        if (d.linkage != LINK.d && d.localNum)
+        if (linkage != LINK.d && d.localNum)
             d.error("the same declaration cannot be in multiple scopes with non-D linkage");
 
-        const l = d.linkage == LINK.system ? target.systemLinkage() : d.linkage;
-        final switch (l)
+        final switch (linkage)
         {
             case LINK.d:
                 break;
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 5415401e0e4..be8f9150903 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -376,7 +376,7 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
         // https://issues.dlang.org/show_bug.cgi?id=19482
         if ((dsym.storage_class & (STC.foreach_ | STC.local)) == (STC.foreach_ | STC.local))
         {
-            dsym.linkage = LINK.d;
+            dsym._linkage = LINK.d;
             dsym.visibility = Visibility(Visibility.Kind.public_);
             dsym.overlapped = false; // unset because it is modified early on this function
             dsym.userAttribDecl = null; // unset because it is set by Dsymbol.setScope()
@@ -389,7 +389,7 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
             dsym.storage_class |= (sc.stc & ~(STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_));
             dsym.userAttribDecl = sc.userAttribDecl;
             dsym.cppnamespace = sc.namespace;
-            dsym.linkage = sc.linkage;
+            dsym._linkage = sc.linkage;
             dsym.visibility = sc.visibility;
             dsym.alignment = sc.alignment();
         }
@@ -1191,7 +1191,7 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
 
     override void visit(TypeInfoDeclaration dsym)
     {
-        assert(dsym.linkage == LINK.c);
+        assert(dsym._linkage == LINK.c);
     }
 
     override void visit(BitFieldDeclaration dsym)
@@ -2174,7 +2174,7 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
 
                 em.semanticRun = PASS.semantic;
                 em.type = Type.tint32;
-                em.linkage = LINK.c;
+                em._linkage = LINK.c;
                 em.storage_class |= STC.manifest;
                 if (em.value)
                 {
@@ -2264,7 +2264,7 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
         em.semanticRun = PASS.semantic;
 
         em.visibility = em.ed.isAnonymous() ? em.ed.visibility : Visibility(Visibility.Kind.public_);
-        em.linkage = LINK.d;
+        em._linkage = LINK.d;
         em.storage_class |= STC.manifest;
 
         // https://issues.dlang.org/show_bug.cgi?id=9701
@@ -3024,7 +3024,7 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
         if (sc.flags & SCOPE.compile)
             funcdecl.flags |= FUNCFLAG.compileTimeOnly; // don't emit code for this function
 
-        funcdecl.linkage = sc.linkage;
+        funcdecl._linkage = sc.linkage;
         if (auto fld = funcdecl.isFuncLiteralDeclaration())
         {
             if (fld.treq)
@@ -3037,7 +3037,7 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
                     fld.tok = TOK.function_;
                 else
                     assert(0);
-                funcdecl.linkage = treq.nextOf().toTypeFunction().linkage;
+                funcdecl._linkage = treq.nextOf().toTypeFunction().linkage;
             }
         }
 
@@ -3048,7 +3048,7 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
         // check pragma(crt_constructor)
         if (funcdecl.flags & (FUNCFLAG.CRTCtor | FUNCFLAG.CRTDtor))
         {
-            if (funcdecl.linkage != LINK.c)
+            if (funcdecl._linkage != LINK.c)
             {
                 funcdecl.error("must be `extern(C)` for `pragma(%s)`",
                     (funcdecl.flags & FUNCFLAG.CRTCtor) ? "crt_constructor".ptr : "crt_destructor".ptr);
@@ -3057,7 +3057,7 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
 
         funcdecl.visibility = sc.visibility;
         funcdecl.userAttribDecl = sc.userAttribDecl;
-        UserAttributeDeclaration.checkGNUABITag(funcdecl, funcdecl.linkage);
+        UserAttributeDeclaration.checkGNUABITag(funcdecl, funcdecl._linkage);
         checkMustUseReserved(funcdecl);
 
         if (!funcdecl.originalType)
@@ -3193,7 +3193,7 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
                 tf.isScopeQual = false;
             }
 
-            sc.linkage = funcdecl.linkage;
+            sc.linkage = funcdecl._linkage;
 
             if (!tf.isNaked() && !(funcdecl.isThis() || funcdecl.isNested()))
             {
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index fb41e2bd05f..ed0126eeef6 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -2777,7 +2777,7 @@  void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
             fd.storage_class == m.lastf.storage_class &&
             fd.parent == m.lastf.parent &&
             fd.visibility == m.lastf.visibility &&
-            fd.linkage == m.lastf.linkage)
+            fd._linkage == m.lastf._linkage)
         {
             if (fd.fbody && !m.lastf.fbody)
                 goto LfIsBetter;
diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d
index 41fb82b8266..17abb7d3b00 100644
--- a/gcc/d/dmd/dtoh.d
+++ b/gcc/d/dmd/dtoh.d
@@ -966,12 +966,13 @@  public:
         if (vd.storage_class & (AST.STC.static_ | AST.STC.extern_ | AST.STC.gshared) ||
         vd.parent && vd.parent.isModule())
         {
-            if (vd.linkage != LINK.c && vd.linkage != LINK.cpp && !(tdparent && (this.linkage == LINK.c || this.linkage == LINK.cpp)))
+            const vdLinkage = vd.resolvedLinkage();
+            if (vdLinkage != LINK.c && vdLinkage != LINK.cpp && !(tdparent && (this.linkage == LINK.c || this.linkage == LINK.cpp)))
             {
                 ignored("variable %s because of linkage", vd.toPrettyChars());
                 return;
             }
-            if (vd.mangleOverride && vd.linkage != LINK.c)
+            if (vd.mangleOverride && vdLinkage != LINK.c)
             {
                 ignored("variable %s because C++ doesn't support explicit mangling", vd.toPrettyChars());
                 return;
@@ -987,7 +988,7 @@  public:
                 return;
             }
             writeProtection(vd.visibility.kind);
-            if (vd.linkage == LINK.c)
+            if (vdLinkage == LINK.c)
                 buf.writestring("extern \"C\" ");
             else if (!adparent)
                 buf.writestring("extern ");
@@ -2805,7 +2806,10 @@  public:
 
         // Check against the internal information which might be missing, e.g. inside of template declarations
         if (auto dec = sym.isDeclaration())
-            return dec.linkage == LINK.cpp || dec.linkage == LINK.c;
+        {
+            const l = dec.resolvedLinkage();
+            return l == LINK.cpp || l == LINK.c;
+        }
 
         if (auto ad = sym.isAggregateDeclaration())
             return ad.classKind == ClassKind.cpp;
@@ -2853,8 +2857,11 @@  public:
         if (!res)
         {
             // Check against the internal information which might be missing, e.g. inside of template declarations
-            auto dec = sym.isDeclaration();
-            res = dec && (dec.linkage == LINK.cpp || dec.linkage == LINK.c);
+            if (auto dec = sym.isDeclaration())
+            {
+                const l = dec.resolvedLinkage();
+                res = (l == LINK.cpp || l == LINK.c);
+            }
         }
 
         // Remember result for later calls
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index 44c3757248b..7c7ba96db0d 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -2360,5 +2360,5 @@  private bool setUnsafeDIP1000(FuncDeclaration f)
 {
     return global.params.useDIP1000 == FeatureState.enabled
         ? f.setUnsafe()
-        : f.isSafeBypassingInference();
+        : false; // reverted for 2.100, retry in 2.101
 }
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index d4e96bb0f09..717420910aa 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -2064,7 +2064,8 @@  private bool functionParameters(const ref Loc loc, Scope* sc,
                     ale.type = ale.type.nextOf().sarrayOf(ale.elements ? ale.elements.length : 0);
                     auto tmp = copyToTemp(0, "__arrayliteral_on_stack", ale);
                     auto declareTmp = new DeclarationExp(ale.loc, tmp);
-                    auto castToSlice = new CastExp(ale.loc, new VarExp(ale.loc, tmp), p.type);
+                    auto castToSlice = new CastExp(ale.loc, new VarExp(ale.loc, tmp),
+                        p.type.substWildTo(MODFlags.mutable));
                     arg = CommaExp.combine(declareTmp, castToSlice);
                     arg = arg.expressionSemantic(sc);
                 }
@@ -6625,6 +6626,14 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
 
             exp.type = exp.type.addMod(t1.mod);
 
+            // https://issues.dlang.org/show_bug.cgi?id=23109
+            // Run semantic on the DotVarExp type
+            if (auto handle = exp.type.isClassHandle())
+            {
+                if (handle.semanticRun < PASS.semanticdone && !handle.isBaseInfoComplete())
+                    handle.dsymbolSemantic(null);
+            }
+
             Dsymbol vparent = exp.var.toParent();
             AggregateDeclaration ad = vparent ? vparent.isAggregateDeclaration() : null;
             if (Expression e1x = getRightThis(exp.loc, sc, ad, exp.e1, exp.var, 1))
@@ -8675,7 +8684,9 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
     {
         static if (LOGSEMANTIC)
         {
-            printf("AssignExp::semantic('%s')\n", exp.toChars());
+            if (exp.op == EXP.blit)      printf("BlitExp.toElem('%s')\n", exp.toChars());
+            if (exp.op == EXP.assign)    printf("AssignExp.toElem('%s')\n", exp.toChars());
+            if (exp.op == EXP.construct) printf("ConstructExp.toElem('%s')\n", exp.toChars());
         }
         //printf("exp.e1.op = %d, '%s'\n", exp.e1.op, EXPtoString(exp.e1.op).ptr);
         //printf("exp.e2.op = %d, '%s'\n", exp.e2.op, EXPtoString(exp.e2.op).ptr);
@@ -9425,6 +9436,23 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
             Expression e1x = exp.e1;
             Expression e2x = exp.e2;
 
+            /* C strings come through as static arrays. May need to adjust the size of the
+             * string to match the size of e1.
+             */
+            Type t2 = e2x.type.toBasetype();
+            if (sc.flags & SCOPE.Cfile && e2x.isStringExp() && t2.isTypeSArray())
+            {
+                uinteger_t dim1 = t1.isTypeSArray().dim.toInteger();
+                uinteger_t dim2 = t2.isTypeSArray().dim.toInteger();
+                if (dim1 + 1 == dim2 || dim2 < dim1)
+                {
+                    auto tsa2 = t2.isTypeSArray();
+                    auto newt = tsa2.next.sarrayOf(dim1).immutableOf();
+                    e2x = castTo(e2x, sc, newt);
+                    exp.e2 = e2x;
+                }
+            }
+
             if (e2x.implicitConvTo(e1x.type))
             {
                 if (exp.op != EXP.blit && (e2x.op == EXP.slice && (cast(UnaExp)e2x).e1.isLvalue() || e2x.op == EXP.cast_ && (cast(UnaExp)e2x).e1.isLvalue() || e2x.op != EXP.slice && e2x.isLvalue()))
@@ -9686,13 +9714,14 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 tsa2 = cast(TypeSArray)toStaticArrayType(se);
             else
                 tsa2 = t2.isTypeSArray();
+
             if (tsa1 && tsa2)
             {
                 uinteger_t dim1 = tsa1.dim.toInteger();
                 uinteger_t dim2 = tsa2.dim.toInteger();
                 if (dim1 != dim2)
                 {
-                    exp.error("mismatched array lengths, %d and %d", cast(int)dim1, cast(int)dim2);
+                    exp.error("mismatched array lengths %d and %d for assignment `%s`", cast(int)dim1, cast(int)dim2, exp.toChars());
                     return setError();
                 }
             }
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index 2e9c2bff1e0..55abe4d52e7 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -1207,12 +1207,12 @@  extern (C++) class FuncDeclaration : Declaration
 
     final bool isMain() const
     {
-        return ident == Id.main && linkage != LINK.c && !isMember() && !isNested();
+        return ident == Id.main && resolvedLinkage() != LINK.c && !isMember() && !isNested();
     }
 
     final bool isCMain() const
     {
-        return ident == Id.main && linkage == LINK.c && !isMember() && !isNested();
+        return ident == Id.main && resolvedLinkage() == LINK.c && !isMember() && !isNested();
     }
 
     final bool isWinMain() const
@@ -1220,24 +1220,24 @@  extern (C++) class FuncDeclaration : Declaration
         //printf("FuncDeclaration::isWinMain() %s\n", toChars());
         version (none)
         {
-            bool x = ident == Id.WinMain && linkage != LINK.c && !isMember();
+            bool x = ident == Id.WinMain && resolvedLinkage() != LINK.c && !isMember();
             printf("%s\n", x ? "yes" : "no");
             return x;
         }
         else
         {
-            return ident == Id.WinMain && linkage != LINK.c && !isMember();
+            return ident == Id.WinMain && resolvedLinkage() != LINK.c && !isMember();
         }
     }
 
     final bool isDllMain() const
     {
-        return ident == Id.DllMain && linkage != LINK.c && !isMember();
+        return ident == Id.DllMain && resolvedLinkage() != LINK.c && !isMember();
     }
 
     final bool isRtInit() const
     {
-        return ident == Id.rt_init && linkage == LINK.c && !isMember() && !isNested();
+        return ident == Id.rt_init && resolvedLinkage() == LINK.c && !isMember() && !isNested();
     }
 
     override final bool isExport() const
@@ -1776,7 +1776,7 @@  extern (C++) class FuncDeclaration : Declaration
         auto f = toAliasFunc();
         //printf("\ttoParent2() = '%s'\n", f.toParent2().toChars());
         return ((f.storage_class & STC.static_) == 0) &&
-                (f.linkage == LINK.d) &&
+                (f._linkage == LINK.d) &&
                 (f.toParent2().isFuncDeclaration() !is null ||
                  f.toParent2() !is f.toParentLocal());
     }
@@ -2663,7 +2663,7 @@  extern (C++) class FuncDeclaration : Declaration
             tf = new TypeFunction(ParameterList(fparams), treturn, LINK.c, stc);
             fd = new FuncDeclaration(Loc.initial, Loc.initial, id, STC.static_, tf);
             fd.visibility = Visibility(Visibility.Kind.public_);
-            fd.linkage = LINK.c;
+            fd._linkage = LINK.c;
 
             st.insert(fd);
         }
@@ -2723,6 +2723,7 @@  extern (C++) class FuncDeclaration : Declaration
         const nparams = tf.parameterList.length;
         bool argerr;
 
+        const linkage = resolvedLinkage();
         if (linkage == LINK.d)
         {
             if (nparams == 1)
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index c84a9f69ffa..16e7c3a5936 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -502,6 +502,18 @@  extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
                 i.exp = se.castTo(sc, t);
                 goto L1;
             }
+
+            /* Lop off terminating 0 of initializer for:
+             *  static char s[5] = "hello";
+             */
+            if (sc.flags & SCOPE.Cfile &&
+                typeb.ty == Tsarray &&
+                tynto.isSomeChar &&
+                tb.isTypeSArray().dim.toInteger() + 1 == typeb.isTypeSArray().dim.toInteger())
+            {
+                i.exp = se.castTo(sc, t);
+                goto L1;
+            }
         }
         /* C11 6.7.9-14..15
          * Initialize an array of unknown size with a string.
diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d
index fc270390fa4..b7ffa19d6ff 100644
--- a/gcc/d/dmd/json.d
+++ b/gcc/d/dmd/json.d
@@ -446,7 +446,7 @@  public:
             return;
         jsonProperties(cast(Dsymbol)d);
         propertyStorageClass("storageClass", d.storage_class);
-        property("linkage", d.linkage);
+        property("linkage", d._linkage);
         property("type", "deco", d.type);
         // Emit originalType if it differs from type
         if (d.type != d.originalType && d.originalType)
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index 13df0d71f3f..32f57d46773 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -4764,12 +4764,31 @@  extern (C++) final class TypeFunction : TypeNext
                                             s ~= "@safe ";
                                         if (!f.isNogc && sc.func.setGC())
                                             s ~= "nogc ";
-                                        s[$-1] = '\0';
-                                        buf.printf("`%s` copy constructor cannot be called from a `%s` context", f.type.toChars(), s.ptr);
-
+                                        if (s)
+                                        {
+                                            s[$-1] = '\0';
+                                            buf.printf("`%s` copy constructor cannot be called from a `%s` context", f.type.toChars(), s.ptr);
+                                        }
+                                        else if (f.isGenerated() && f.isDisabled())
+                                        {
+                                            /* https://issues.dlang.org/show_bug.cgi?id=23097
+                                             * Compiler generated copy constructor failed.
+                                             */
+                                            buf.printf("generating a copy constructor for `struct %s` failed, therefore instances of it are uncopyable",
+                                                       argStruct.toChars());
+                                        }
+                                        else
+                                        {
+                                            /* Although a copy constructor may exist, no suitable match was found.
+                                             * i.e: `inout` constructor creates `const` object, not mutable.
+                                             * Fallback to using the original generic error before bugzilla 22202.
+                                             */
+                                            goto Lnocpctor;
+                                        }
                                     }
                                     else
                                     {
+                                    Lnocpctor:
                                         buf.printf("`struct %s` does not define a copy constructor for `%s` to `%s` copies",
                                                argStruct.toChars(), targ.toChars(), tprm.toChars());
                                     }
diff --git a/gcc/d/dmd/objc.d b/gcc/d/dmd/objc.d
index 9e92212ada1..9afedc1c27b 100644
--- a/gcc/d/dmd/objc.d
+++ b/gcc/d/dmd/objc.d
@@ -578,7 +578,7 @@  extern(C++) private final class Supported : Objc
 
     override void checkLinkage(FuncDeclaration fd)
     {
-        if (fd.linkage != LINK.objc && fd.objc.selector)
+        if (fd._linkage != LINK.objc && fd.objc.selector)
             fd.error("must have Objective-C linkage to attach a selector");
     }
 
@@ -640,11 +640,11 @@  extern(C++) private final class Supported : Objc
         if (!fd.objc.isOptional)
             return;
 
-        if (fd.linkage != LINK.objc)
+        if (fd._linkage != LINK.objc)
         {
             fd.error("only functions with Objective-C linkage can be declared as optional");
 
-            const linkage = linkageToString(fd.linkage);
+            const linkage = linkageToString(fd._linkage);
 
             errorSupplemental(fd.loc, "function is declared with %.*s linkage",
                 cast(uint) linkage.length, linkage.ptr);
diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d
index cd65920e38b..73dcaa6c960 100644
--- a/gcc/d/dmd/semantic2.d
+++ b/gcc/d/dmd/semantic2.d
@@ -238,7 +238,7 @@  private extern(C++) final class Semantic2Visitor : Visitor
             return;
         }
 
-        UserAttributeDeclaration.checkGNUABITag(vd, vd.linkage);
+        UserAttributeDeclaration.checkGNUABITag(vd, vd._linkage);
 
         if (vd._init && !vd.toParent().isFuncDeclaration())
         {
@@ -379,6 +379,7 @@  private extern(C++) final class Semantic2Visitor : Visitor
             alias f1 = fd;
             auto tf1 = cast(TypeFunction) f1.type;
             auto parent1 = f1.toParent2();
+            const linkage1 = f1.resolvedLinkage();
 
             overloadApply(f1, (Dsymbol s)
             {
@@ -391,7 +392,7 @@  private extern(C++) final class Semantic2Visitor : Visitor
                     return 0;
 
                 // Functions with different manglings can never conflict
-                if (f1.linkage != f2.linkage)
+                if (linkage1 != f2.resolvedLinkage())
                     return 0;
 
                 // Functions with different names never conflict
@@ -428,12 +429,12 @@  private extern(C++) final class Semantic2Visitor : Visitor
                 // @@@DEPRECATED_2.104@@@
                 // Deprecated in 2020-08, make this an error in 2.104
                 if (parent1.isModule() &&
-                    f1.linkage != LINK.d && f1.linkage != LINK.cpp &&
+                    linkage1 != LINK.d && linkage1 != LINK.cpp &&
                     (!sameAttr || !sameParams)
                 )
                 {
                     f2.deprecation("cannot overload `extern(%s)` function at %s",
-                            linkageToChars(f1.linkage),
+                            linkageToChars(f1._linkage),
                             f1.loc.toChars());
                     return 0;
                 }
@@ -443,7 +444,7 @@  private extern(C++) final class Semantic2Visitor : Visitor
                     return 0;
 
                 // Different attributes don't conflict in extern(D)
-                if (!sameAttr && f1.linkage == LINK.d)
+                if (!sameAttr && linkage1 == LINK.d)
                     return 0;
 
                 error(f2.loc, "%s `%s%s` conflicts with previous declaration at %s",
@@ -460,7 +461,7 @@  private extern(C++) final class Semantic2Visitor : Visitor
             return;
         TypeFunction f = cast(TypeFunction) fd.type;
 
-        UserAttributeDeclaration.checkGNUABITag(fd, fd.linkage);
+        UserAttributeDeclaration.checkGNUABITag(fd, fd._linkage);
         //semantic for parameters' UDAs
         foreach (i, param; f.parameterList)
         {
@@ -643,7 +644,7 @@  private extern(C++) final class Semantic2Visitor : Visitor
                     {
                         //printf("            found\n");
                         // Check that calling conventions match
-                        if (fd.linkage != ifd.linkage)
+                        if (fd._linkage != ifd._linkage)
                             fd.error("linkage doesn't match interface function");
 
                         // Check that it is current
diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d
index 2e459b1857f..41f8d525929 100644
--- a/gcc/d/dmd/semantic3.d
+++ b/gcc/d/dmd/semantic3.d
@@ -1353,7 +1353,7 @@  private extern(C++) final class Semantic3Visitor : Visitor
             if (funcdecl.isCtorDeclaration()) // https://issues.dlang.org/show_bug.cgi?id=#15665
                 f.isctor = true;
             sc.stc = 0;
-            sc.linkage = funcdecl.linkage; // https://issues.dlang.org/show_bug.cgi?id=8496
+            sc.linkage = funcdecl._linkage; // https://issues.dlang.org/show_bug.cgi?id=8496
             funcdecl.type = f.typeSemantic(funcdecl.loc, sc);
             sc = sc.pop();
         }
diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d
index db77107e4ae..9db0012dd01 100644
--- a/gcc/d/dmd/traits.d
+++ b/gcc/d/dmd/traits.d
@@ -1381,7 +1381,7 @@  Expression semanticTraits(TraitsExp e, Scope* sc)
                 e.error("argument to `__traits(getFunctionVariadicStyle, %s)` is not a function", o.toChars());
                 return ErrorExp.get();
             }
-            link = fd.linkage;
+            link = fd._linkage;
             varargs = fd.getParameterList().varargs;
         }
         string style;
@@ -1515,7 +1515,7 @@  Expression semanticTraits(TraitsExp e, Scope* sc)
 
         if (tf)
         {
-            link = fd ? fd.toAliasFunc().linkage : tf.linkage;
+            link = fd ? fd.toAliasFunc()._linkage : tf.linkage;
         }
         else
         {
@@ -1529,7 +1529,7 @@  Expression semanticTraits(TraitsExp e, Scope* sc)
             }
 
             if (d !is null)
-                link = d.linkage;
+                link = d._linkage;
             else
             {
                 // Resolves forward references
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index d897ec4c5e4..c54049dfb98 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -375,7 +375,7 @@  fixup_anonymous_offset (tree fields, tree offset)
 
 /* Iterate over all MEMBERS of an aggregate, and add them as fields to CONTEXT.
    If INHERITED_P is true, then the members derive from a base class.
-   Returns the number of fields found.  */
+   Returns the number of named fields found.  */
 
 static size_t
 layout_aggregate_members (Dsymbols *members, tree context, bool inherited_p)
@@ -418,7 +418,8 @@  layout_aggregate_members (Dsymbols *members, tree context, bool inherited_p)
 	  /* Insert the field declaration at its given offset.  */
 	  if (var->isField ())
 	    {
-	      const char *ident = var->ident ? var->ident->toChars () : NULL;
+	      const char *ident = (var->ident && !var->ident->isAnonymous ())
+		? var->ident->toChars () : NULL;
 	      tree field = create_field_decl (declaration_type (var), ident,
 					      inherited_p, inherited_p);
 	      apply_user_attributes (var, field);
@@ -442,7 +443,10 @@  layout_aggregate_members (Dsymbols *members, tree context, bool inherited_p)
 		  var->csym = field;
 		}
 
-	      fields += 1;
+	      /* Only count the named fields in an aggregate.  */
+	      if (ident != NULL)
+		fields += 1;
+
 	      continue;
 	    }
 	}
diff --git a/gcc/testsuite/gdc.test/compilable/test23097.d b/gcc/testsuite/gdc.test/compilable/test23097.d
new file mode 100644
index 00000000000..092bd774f22
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23097.d
@@ -0,0 +1,33 @@ 
+/* https://issues.dlang.org/show_bug.cgi?id=23097
+REQUIRED_ARGS: -verrors=spec
+TEST_OUTPUT:
+---
+(spec:2) compilable/test23097.d(14): Error: `inout` constructor `test23097.S23097.this` creates const object, not mutable
+(spec:2) compilable/test23097.d(14): Error: `inout` constructor `test23097.S23097.this` creates const object, not mutable
+(spec:1) compilable/test23097.d(14): Error: generated function `test23097.S23097.opAssign(S23097 p)` is not callable using argument types `(const(S23097))`
+(spec:2) compilable/test23097.d(14): Error: `inout` constructor `test23097.S23097.this` creates const object, not mutable
+(spec:1) compilable/test23097.d(14):        `struct S23097` does not define a copy constructor for `const(S23097)` to `S23097` copies
+---
+*/
+void emplaceRef(UT, Args)(UT chunk, Args args)
+{
+    static if (__traits(compiles, chunk = args))
+        chunk = args;
+}
+
+struct CpCtor23097(T)
+{
+    T* payload;
+    this(ref inout typeof(this)) { }
+    ref opAssign(typeof(this)) { }
+}
+
+struct S23097
+{
+    CpCtor23097!int payload;
+}
+
+void test23097(S23097 lhs, const S23097 rhs)
+{
+    emplaceRef(lhs, rhs);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/extra-files/test23109/object.d b/gcc/testsuite/gdc.test/fail_compilation/extra-files/test23109/object.d
new file mode 100644
index 00000000000..747b6e9cc4d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/extra-files/test23109/object.d
@@ -0,0 +1,17 @@ 
+module object;
+
+alias size_t = typeof(int.sizeof);
+class Object {}
+auto opEquals(Object ) { return true; }
+class TypeInfo {}
+class TypeInfo_Const {}
+bool _xopEquals() { return true; }
+
+bool __equals(T1, T2)(T1[] lhs, T2[] rhs)
+{
+    static at(R)(R[] r, size_t i) { return r.ptr[i]; }
+    foreach (u; 0 .. lhs.length)
+        if (at(lhs, u) != at(rhs, u))
+            return false;
+    return true;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail12604.d b/gcc/testsuite/gdc.test/fail_compilation/fail12604.d
index 2ed8ebf9cc9..bed87351bc5 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail12604.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail12604.d
@@ -66,8 +66,8 @@  void test12606b()   // ExpInitializer::semantic
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail12604.d(77): Error: mismatched array lengths, 4 and 3
-fail_compilation/fail12604.d(78): Error: mismatched array lengths, 4 and 3
+fail_compilation/fail12604.d(77): Error: mismatched array lengths 4 and 3 for assignment `sa1[0..4] = [1, 2, 3]`
+fail_compilation/fail12604.d(78): Error: mismatched array lengths 4 and 3 for assignment `sa1[0..4] = sa2`
 ---
 */
 void testc()
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23108a.d b/gcc/testsuite/gdc.test/fail_compilation/fail23108a.d
new file mode 100644
index 00000000000..a974871a38a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23108a.d
@@ -0,0 +1,16 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23108
+/* TEST_OUTPUT:
+---
+fail_compilation/fail23108a.d(9): Error: undefined identifier `_xopEquals` in module `object`
+---
+*/
+module object;
+
+struct Interface
+{
+    void[] vtbl;
+}
+
+class TypeInfo
+{
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23108b.d b/gcc/testsuite/gdc.test/fail_compilation/fail23108b.d
new file mode 100644
index 00000000000..10eae37c401
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23108b.d
@@ -0,0 +1,18 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23108
+/* TEST_OUTPUT:
+---
+fail_compilation/fail23108b.d(10): Error: undefined identifier `_xopEquals` in module `object`
+fail_compilation/fail23108b.d(10): Error: undefined identifier `_xopCmp` in module `object`
+---
+*/
+module object;
+
+struct Interface
+{
+    void[] vtbl;
+    int opCmp() { return 0; }
+}
+
+class TypeInfo
+{
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23109.d b/gcc/testsuite/gdc.test/fail_compilation/fail23109.d
new file mode 100644
index 00000000000..91b4e79ad2d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23109.d
@@ -0,0 +1,12 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23109
+/*
+EXTRA_FILES: imports/test23109a.d imports/test23109b.d imports/test23109c.d
+EXTRA_SOURCES: extra-files/test23109/object.d
+TEST_OUTPUT:
+---
+Error: no property `getHash` for type `object.TypeInfo_Const`
+Error: no property `getHash` for type `object.TypeInfo_Const`
+fail_compilation/imports/test23109a.d(10): Error: template instance `imports.test23109a.Array!(Ensure)` error instantiating
+---
+*/
+import imports.test23109a;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail3703.d b/gcc/testsuite/gdc.test/fail_compilation/fail3703.d
index 6b4edd5b629..d2d277f5065 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail3703.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail3703.d
@@ -3,8 +3,8 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail3703.d(18): Error: mismatched array lengths, 2 and 1
-fail_compilation/fail3703.d(20): Error: mismatched array lengths, 2 and 1
+fail_compilation/fail3703.d(18): Error: mismatched array lengths 2 and 1 for assignment `b[] = a`
+fail_compilation/fail3703.d(20): Error: mismatched array lengths 2 and 1 for assignment `b[] = a`
 fail_compilation/fail3703.d(22): Error: mismatched array lengths, 3 and 2
 fail_compilation/fail3703.d(23): Error: mismatched array lengths, 2 and 3
 fail_compilation/fail3703.d(25): Error: mismatched array lengths, 3 and 2
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d b/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
index 07c3766d490..41a8c2d85e3 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
@@ -2,13 +2,6 @@ 
 REQUIRED_ARGS:
 TEST_OUTPUT:
 ---
-fail_compilation/fail_scope.d(29): Deprecation: scope variable `da` may not be returned
-fail_compilation/fail_scope.d(31): Deprecation: scope variable `o` may not be returned
-fail_compilation/fail_scope.d(32): Deprecation: scope variable `dg` may not be returned
-fail_compilation/fail_scope.d(34): Deprecation: scope variable `da` may not be returned
-fail_compilation/fail_scope.d(36): Deprecation: scope variable `o` may not be returned
-fail_compilation/fail_scope.d(37): Deprecation: scope variable `dg` may not be returned
-fail_compilation/fail_scope.d(39): Deprecation: scope variable `p` may not be returned
 fail_compilation/fail_scope.d(44): Error: returning `cast(char[])string` escapes a reference to local variable `string`
 fail_compilation/fail_scope.d(62): Error: returning `s.bar()` escapes a reference to local variable `s`
 fail_compilation/fail_scope.d(73): Error: `fail_scope.foo8` called with argument types `(int)` matches both:
@@ -22,19 +15,26 @@  fail_compilation/fail_scope.d(107): Deprecation: escaping reference to outer loc
 fail_compilation/fail_scope.d(126): Error: returning `s.bar()` escapes a reference to local variable `s`
 fail_compilation/fail_scope.d(136): Error: returning `foo16226(i)` escapes a reference to local variable `i`
 ---
+//fail_compilation/fail_scope.d(30): Error: scope variable `da` may not be returned
+//fail_compilation/fail_scope.d(32): Error: scope variable `o` may not be returned
+//fail_compilation/fail_scope.d(33): Error: scope variable `dg` may not be returned
+//fail_compilation/fail_scope.d(35): Error: scope variable `da` may not be returned
+//fail_compilation/fail_scope.d(37): Error: scope variable `o` may not be returned
+//fail_compilation/fail_scope.d(38): Error: scope variable `dg` may not be returned
+//fail_compilation/fail_scope.d(40): Error: scope variable `p` may not be returned
 */
 
 alias int delegate() dg_t;
 
-int[]  checkEscapeScope1(scope int[]  da) @safe { return da; }
-int[3] checkEscapeScope2(scope int[3] sa) @safe { return sa; }
-Object checkEscapeScope3(scope Object o)  @safe { return o;  }
-dg_t   checkEscapeScope4(scope dg_t   dg) @safe { return dg; }
+int[]  checkEscapeScope1(scope int[]  da) { return da; }
+int[3] checkEscapeScope2(scope int[3] sa) { return sa; }
+Object checkEscapeScope3(scope Object o)  { return o;  }
+dg_t   checkEscapeScope4(scope dg_t   dg) { return dg; }
 
-int[]  checkEscapeScope1() @safe { scope int[]  da = [];           return da; }
-int[3] checkEscapeScope2() @safe { scope int[3] sa = [1,2,3];      return sa; }
-Object checkEscapeScope3() @safe { scope Object  o = new Object;   return o;  }   // same with fail7294.d
-dg_t   checkEscapeScope4() @safe { scope dg_t   dg = () => 1;      return dg; }
+int[]  checkEscapeScope1() { scope int[]  da = [];           return da; }
+int[3] checkEscapeScope2() { scope int[3] sa = [1,2,3];      return sa; }
+Object checkEscapeScope3() { scope Object  o = new Object;   return o;  }   // same with fail7294.d
+dg_t   checkEscapeScope4() { scope dg_t   dg = () => 1;      return dg; }
 
 int* test(scope int* p) @safe { return p; }
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice23097.d b/gcc/testsuite/gdc.test/fail_compilation/ice23097.d
new file mode 100644
index 00000000000..4fd1f61f828
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice23097.d
@@ -0,0 +1,28 @@ 
+/* https://issues.dlang.org/show_bug.cgi?id=23097
+TEST_OUTPUT:
+---
+fail_compilation/ice23097.d(12): Error: undefined identifier `ICE`
+fail_compilation/ice23097.d(27): Error: template instance `ice23097.ice23097!(S23097)` error instantiating
+fail_compilation/ice23097.d(27): Error: function `ice23097.ice23097!(S23097).ice23097(S23097 _param_0)` is not callable using argument types `(S23097)`
+fail_compilation/ice23097.d(27):        generating a copy constructor for `struct S23097` failed, therefore instances of it are uncopyable
+---
+*/
+auto ice23097(I)(I)
+{
+    ICE;
+}
+
+struct Cpctor23097
+{
+    this(ref typeof(this)) { }
+}
+
+struct S23097
+{
+    Cpctor23097 cpctor;
+}
+
+auto fail23097(S23097 s)
+{
+    s.ice23097;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test23109a.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test23109a.d
new file mode 100644
index 00000000000..5a11d9124c8
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test23109a.d
@@ -0,0 +1,10 @@ 
+module imports.test23109a;
+import imports.test23109c;
+import imports.test23109b;
+struct Array(T)
+{
+    T[] data;
+    enum SMALLARRAYCAP = 1;
+    T[SMALLARRAYCAP] smallarray;
+}
+alias Ensures = Array!Ensure;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test23109b.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test23109b.d
new file mode 100644
index 00000000000..38680d3b986
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test23109b.d
@@ -0,0 +1,10 @@ 
+module imports.test23109b;
+import imports.test23109a;
+import imports.test23109c;
+struct Ensure
+{
+    Statement ensure;
+    Ensures* arraySyntaxCopy()
+    {
+    }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test23109c.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test23109c.d
new file mode 100644
index 00000000000..c6faf5c12da
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test23109c.d
@@ -0,0 +1,3 @@ 
+module imports.test23109c;
+import imports.test23109b;
+class Statement {}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test9150.d b/gcc/testsuite/gdc.test/fail_compilation/test9150.d
index e65afece6ff..5f66b360fec 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test9150.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test9150.d
@@ -3,7 +3,7 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/test9150.d(14): Error: mismatched array lengths, 5 and 3
+fail_compilation/test9150.d(14): Error: mismatched array lengths 5 and 3 for assignment `row[] = __r2[__key3]`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/runnable/test20734.d b/gcc/testsuite/gdc.test/runnable/test20734.d
new file mode 100644
index 00000000000..264602bccc5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test20734.d
@@ -0,0 +1,28 @@ 
+/*
+REQUIRED_ARGS: -betterC -preview=dip1000
+*/
+
+__gshared int numDtor;
+
+struct S
+{
+    int a;
+    ~this() nothrow @nogc @trusted { ++numDtor; }
+}
+
+void takeScopeSlice(const scope S[] slice) nothrow @nogc @safe {}
+
+extern(C) int main() nothrow @nogc @safe
+{
+    takeScopeSlice([ S(1), S(2) ]); // @nogc => no GC allocation
+    (() @trusted { assert(numDtor == 2); })(); // stack-allocated array literal properly destructed
+    return 0;
+}
+
+// https://issues.dlang.org/show_bug.cgi?id=23098
+void f23098(scope inout(int)[] d) @safe {}
+
+void test23098() @safe
+{
+    f23098([10, 20]);
+}
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index c51d237983d..ed9a02e1a0c 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@ 
-dba1bbe271a9b2d7f24edeebbc77846e29904e41
+604534d7cb29d49a6474f0aaaa5d166057a44f72
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/phobos repository.