[gcc r16-7181] d: Merge upstream dmd, druntime 1017635a96, phobos 5a142da0a

Iain Buclaw ibuclaw@gcc.gnu.org
Fri Jan 30 10:26:17 GMT 2026


https://gcc.gnu.org/g:919b6fa6adcc102f95b17c13e8bdc26fd4ec1394

commit r16-7181-g919b6fa6adcc102f95b17c13e8bdc26fd4ec1394
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Fri Jan 30 10:25:49 2026 +0100

    d: Merge upstream dmd, druntime 1017635a96, phobos 5a142da0a
    
    D front-end changes:
    
            - Import dmd v2.112.0-beta.1.
    
    D runtime changes:
    
            - Import druntime v2.112.0-beta.1.
            - Added 64-bit `mul' and `udivmod' overloads to `core.int128'.
    
    Phobos changes:
    
            - Added `lazyCache' to `std.algorithm.iteration'.
            - Added `writeText', `writeWText', and `writeDText' to
              `std.conv'.
    
    gcc/d/ChangeLog:
    
            * dmd/MERGE: Merge upstream dmd 1017635a96.
            * dmd/VERSION: Bump version to v2.112.0-beta.1.
            * decl.cc (DeclVisitor::finish_vtable): Update for new front-end
            interface.
            (DeclVisitor::visit): Likewise.
            * typeinfo.cc (TypeInfoVisitor::visit): Likewise.
    
    libphobos/ChangeLog:
    
            * libdruntime/MERGE: Merge upstream druntime 1017635a96.
            * libdruntime/Makefile.am (DRUNTIME_DSOURCES_LINUX): Add
            core/sys/linux/sys/syscall.d, core/sys/linux/syscall.d.
            * libdruntime/Makefile.in: Regenerate.
            * src/MERGE: Merge upstream phobos 5a142da0a.
            * src/Makefile.am (PHOBOS_DSOURCES): Remove
            std/internal/windows/bcrypt.d.
            * src/Makefile.in: Regenerate.
    
    gcc/testsuite/ChangeLog:
    
            * gdc.dg/asm1.d: Adjust test.

Diff:
---
 gcc/d/decl.cc                                      |    4 +-
 gcc/d/dmd/MERGE                                    |    2 +-
 gcc/d/dmd/VERSION                                  |    2 +-
 gcc/d/dmd/aggregate.d                              |    2 -
 gcc/d/dmd/aggregate.h                              |    6 +-
 gcc/d/dmd/arraytypes.d                             |    1 +
 gcc/d/dmd/arraytypes.h                             |    2 +
 gcc/d/dmd/attrib.d                                 |    5 -
 gcc/d/dmd/attrib.h                                 |    1 -
 gcc/d/dmd/cond.d                                   |  116 +-
 gcc/d/dmd/cond.h                                   |    4 -
 gcc/d/dmd/cparse.d                                 |  332 +++---
 gcc/d/dmd/cxxfrontend.d                            |   27 +-
 gcc/d/dmd/dcast.d                                  |   44 +-
 gcc/d/dmd/dclass.d                                 |  212 ----
 gcc/d/dmd/declaration.d                            |  103 --
 gcc/d/dmd/declaration.h                            |    4 +-
 gcc/d/dmd/delegatize.d                             |    1 +
 gcc/d/dmd/dinterpret.d                             |   64 +-
 gcc/d/dmd/dmodule.d                                |   99 +-
 gcc/d/dmd/dscope.d                                 |    2 +-
 gcc/d/dmd/dstruct.d                                |  223 +---
 gcc/d/dmd/dsymbol.d                                |   79 +-
 gcc/d/dmd/dsymbol.h                                |    5 +-
 gcc/d/dmd/dsymbolsem.d                             |  893 +++++++++++++-
 gcc/d/dmd/dtemplate.d                              |   17 +-
 gcc/d/dmd/enumsem.d                                |  140 +--
 gcc/d/dmd/expression.d                             |   43 +-
 gcc/d/dmd/expression.h                             |   29 +-
 gcc/d/dmd/expressionsem.d                          |  364 ++++--
 gcc/d/dmd/func.d                                   |    6 +-
 gcc/d/dmd/funcsem.d                                | 1252 ++++++++++++--------
 gcc/d/dmd/hdrgen.d                                 |   14 +-
 gcc/d/dmd/iasmgcc.d                                |   53 +-
 gcc/d/dmd/id.d                                     |    1 -
 gcc/d/dmd/imphint.d                                |   24 +
 gcc/d/dmd/importc.d                                |  132 ++-
 gcc/d/dmd/initsem.d                                |   47 +-
 gcc/d/dmd/location.d                               |  127 +-
 gcc/d/dmd/mangle/package.d                         |    6 +-
 gcc/d/dmd/mtype.d                                  |   10 +-
 gcc/d/dmd/mtype.h                                  |    2 +
 gcc/d/dmd/nogc.d                                   |   57 +-
 gcc/d/dmd/nspace.d                                 |    6 -
 gcc/d/dmd/nspace.h                                 |    1 -
 gcc/d/dmd/optimize.d                               |    3 +-
 gcc/d/dmd/parse.d                                  |   81 +-
 gcc/d/dmd/semantic2.d                              |   16 +-
 gcc/d/dmd/semantic3.d                              |    4 +-
 gcc/d/dmd/statementsem.d                           |   32 +-
 gcc/d/dmd/template.h                               |    2 +-
 gcc/d/dmd/templatesem.d                            |   13 +-
 gcc/d/dmd/traits.d                                 |    2 +-
 gcc/d/dmd/typesem.d                                |   95 +-
 gcc/d/typeinfo.cc                                  |    4 +-
 gcc/testsuite/gdc.dg/asm1.d                        |   12 +-
 .../gdc.test/compilable/imports/cstuff3.c          |   13 +
 .../gdc.test/compilable/imports/imp18127a.c        |   74 ++
 .../gdc.test/compilable/imports/imp18127b.c        |   74 ++
 .../gdc.test/compilable/imports/imp20344.c         |    2 +
 .../gdc.test/compilable/imports/imp20499.c         |    8 +
 gcc/testsuite/gdc.test/compilable/test18127.d      |    5 +
 gcc/testsuite/gdc.test/compilable/test20344.d      |   14 +
 gcc/testsuite/gdc.test/compilable/test20499.d      |    3 +
 gcc/testsuite/gdc.test/compilable/test3004.d       |    2 +-
 gcc/testsuite/gdc.test/compilable/testcstuff3.d    |   19 +
 gcc/testsuite/gdc.test/compilable/uda_lambda.d     |    3 +
 gcc/testsuite/gdc.test/compilable/vcg-ast.d        |   11 +
 gcc/testsuite/gdc.test/fail_compilation/b23686.d   |    2 +-
 .../gdc.test/fail_compilation/checkimports2.d      |   10 +-
 .../gdc.test/fail_compilation/diag10405.d          |   11 -
 .../gdc.test/fail_compilation/diag20888.d          |   10 +-
 .../gdc.test/fail_compilation/diag23384.d          |    4 +-
 gcc/testsuite/gdc.test/fail_compilation/diag9679.d |   19 +-
 .../fail_compilation/diag_ptr_conversion.d         |   17 +
 .../fail_compilation/enum_auto_increment.d         |   18 +
 gcc/testsuite/gdc.test/fail_compilation/fail109.d  |   14 +-
 .../gdc.test/fail_compilation/fail11714.d          |    6 +-
 .../gdc.test/fail_compilation/fail15361.d          |    3 +-
 .../gdc.test/fail_compilation/fail15616b.d         |    2 +-
 gcc/testsuite/gdc.test/fail_compilation/fail16.d   |    5 +-
 gcc/testsuite/gdc.test/fail_compilation/fail163.d  |   16 +-
 .../gdc.test/fail_compilation/fail18219.d          |   11 +-
 .../gdc.test/fail_compilation/fail19103.d          |    4 +-
 gcc/testsuite/gdc.test/fail_compilation/fail196.d  |    2 +-
 .../gdc.test/fail_compilation/fail21547.d          |    6 +-
 .../gdc.test/fail_compilation/fail23439.d          |    3 +-
 gcc/testsuite/gdc.test/fail_compilation/fail305.d  |   11 -
 gcc/testsuite/gdc.test/fail_compilation/fail336.d  |    3 +-
 gcc/testsuite/gdc.test/fail_compilation/fail347.d  |    8 +-
 gcc/testsuite/gdc.test/fail_compilation/fail41.d   |   18 -
 gcc/testsuite/gdc.test/fail_compilation/fail98.d   |    5 +-
 .../gdc.test/fail_compilation/fail_pretty_errors.d |    2 +-
 .../gdc.test/fail_compilation/failcontracts.d      |   17 +-
 gcc/testsuite/gdc.test/fail_compilation/fix19613.d |   16 +
 gcc/testsuite/gdc.test/fail_compilation/fix20075.d |   21 +
 gcc/testsuite/gdc.test/fail_compilation/fix20318.d |   46 +
 gcc/testsuite/gdc.test/fail_compilation/fix20867.d |   20 +
 gcc/testsuite/gdc.test/fail_compilation/fix21042.d |   15 +
 gcc/testsuite/gdc.test/fail_compilation/fix21165.d |   30 +
 gcc/testsuite/gdc.test/fail_compilation/fix21166.d |   13 +
 .../gdc.test/fail_compilation/hidden_ctor.d        |   27 +
 gcc/testsuite/gdc.test/fail_compilation/ice11153.d |    5 +-
 gcc/testsuite/gdc.test/fail_compilation/ice19755.d |    5 +-
 .../gdc.test/fail_compilation/imports/imp18127a.c  |   83 ++
 .../gdc.test/fail_compilation/imports/imp18127b.c  |   80 ++
 gcc/testsuite/gdc.test/fail_compilation/lookup.d   |   10 +-
 .../gdc.test/fail_compilation/mixinprop.d          |    4 +-
 .../fail_compilation/named_arguments_error.d       |   35 +-
 .../fail_compilation/named_arguments_ifti_error.d  |   15 +-
 gcc/testsuite/gdc.test/fail_compilation/nogc3.d    |   30 +
 .../gdc.test/fail_compilation/nonvoid_return.d     |   37 +
 .../gdc.test/fail_compilation/noreturn2.d          |    2 +-
 .../gdc.test/fail_compilation/powinline.d          |   38 +
 .../gdc.test/fail_compilation/retscope3.d          |   10 +
 .../gdc.test/fail_compilation/seq_assign.d         |   43 +
 .../gdc.test/fail_compilation/test15989.d          |    8 +-
 .../gdc.test/fail_compilation/test18127.d          |  106 ++
 .../gdc.test/fail_compilation/test19661.d          |    3 +-
 .../gdc.test/fail_compilation/test20489.d          |   20 +
 .../gdc.test/fail_compilation/test21215.d          |   35 +
 .../gdc.test/fail_compilation/test21304.d          |    6 +
 .../gdc.test/fail_compilation/test21317.d          |   39 +
 .../gdc.test/fail_compilation/testrvaluecpctor.d   |    2 +-
 .../gdc.test/fail_compilation/uda_lambda.d         |    7 +
 .../gdc.test/fail_compilation/union_conv.d         |    2 +-
 gcc/testsuite/gdc.test/runnable/placenew.d         |   43 +
 gcc/testsuite/gdc.test/runnable/powinline.d        |   64 +
 gcc/testsuite/gdc.test/runnable/testaa2.d          |   21 +
 gcc/testsuite/gdc.test/runnable/testinvariant.d    |   47 +-
 libphobos/libdruntime/MERGE                        |    2 +-
 libphobos/libdruntime/Makefile.am                  |    5 +-
 libphobos/libdruntime/Makefile.in                  |   12 +-
 libphobos/libdruntime/core/int128.d                |  245 ++--
 .../libdruntime/core/internal/array/capacity.d     |  344 +++++-
 .../core/internal/array/concatenation.d            |   47 +-
 .../libdruntime/core/internal/array/construction.d |    6 +-
 libphobos/libdruntime/core/internal/array/utils.d  |   25 +
 libphobos/libdruntime/core/internal/lifetime.d     |   19 +
 libphobos/libdruntime/core/stdc/fenv.d             |    5 +
 libphobos/libdruntime/core/stdc/math.d             |   36 +-
 libphobos/libdruntime/core/stdc/stdarg.d           |    2 +-
 libphobos/libdruntime/core/sys/bionic/err.d        |    2 +-
 libphobos/libdruntime/core/sys/bionic/string.d     |    2 +-
 libphobos/libdruntime/core/sys/darwin/err.d        |    2 +-
 libphobos/libdruntime/core/sys/darwin/string.d     |    2 +-
 libphobos/libdruntime/core/sys/dragonflybsd/err.d  |    2 +-
 .../libdruntime/core/sys/dragonflybsd/string.d     |    2 +-
 libphobos/libdruntime/core/sys/freebsd/err.d       |    2 +-
 libphobos/libdruntime/core/sys/freebsd/string.d    |    2 +-
 libphobos/libdruntime/core/sys/linux/err.d         |    2 +-
 .../libdruntime/core/sys/linux/linux/if_packet.d   |    2 +-
 libphobos/libdruntime/core/sys/linux/netinet/in_.d |   14 +-
 libphobos/libdruntime/core/sys/linux/perf_event.d  |   77 +-
 libphobos/libdruntime/core/sys/linux/sched.d       |   30 +-
 libphobos/libdruntime/core/sys/linux/string.d      |    2 +-
 libphobos/libdruntime/core/sys/linux/sys/syscall.d |  127 ++
 libphobos/libdruntime/core/sys/linux/sys/time.d    |    8 +-
 libphobos/libdruntime/core/sys/linux/syscall.d     |   14 +
 libphobos/libdruntime/core/sys/linux/unistd.d      |    5 +
 libphobos/libdruntime/core/sys/netbsd/err.d        |    2 +-
 libphobos/libdruntime/core/sys/netbsd/string.d     |    2 +-
 .../libdruntime/core/sys/netbsd/sys/featuretest.d  |    2 +-
 libphobos/libdruntime/core/sys/openbsd/err.d       |    2 +-
 libphobos/libdruntime/core/sys/openbsd/string.d    |    2 +-
 libphobos/libdruntime/core/sys/posix/netdb.d       |   20 +-
 libphobos/libdruntime/core/sys/posix/netinet/in_.d |  202 ++--
 libphobos/libdruntime/core/sys/posix/signal.d      |   21 +-
 libphobos/libdruntime/core/sys/posix/sys/ioctl.d   |   10 +-
 libphobos/libdruntime/core/sys/posix/sys/select.d  |  104 +-
 libphobos/libdruntime/core/sys/posix/sys/socket.d  |   14 +-
 libphobos/libdruntime/core/sys/posix/sys/stat.d    |  162 +--
 libphobos/libdruntime/core/sys/posix/sys/wait.d    |  152 +--
 libphobos/libdruntime/core/sys/solaris/err.d       |    2 +-
 libphobos/libdruntime/core/sys/windows/basetsd.d   |   38 +-
 libphobos/libdruntime/core/sys/windows/commctrl.d  |    4 +-
 libphobos/libdruntime/core/sys/windows/dde.d       |   60 +-
 libphobos/libdruntime/core/sys/windows/mmsystem.d  |   26 +-
 libphobos/libdruntime/core/sys/windows/ntdef.d     |    8 +-
 libphobos/libdruntime/core/sys/windows/ntsecapi.d  |    2 +-
 libphobos/libdruntime/core/sys/windows/oleauto.d   |    2 +-
 libphobos/libdruntime/core/sys/windows/shlobj.d    |  146 +--
 libphobos/libdruntime/core/sys/windows/stat.d      |   10 +-
 libphobos/libdruntime/core/sys/windows/threadaux.d |    4 +-
 libphobos/libdruntime/core/sys/windows/vfw.d       |  138 +--
 libphobos/libdruntime/core/sys/windows/winbase.d   |   16 +-
 libphobos/libdruntime/core/sys/windows/wincrypt.d  |   10 +-
 libphobos/libdruntime/core/sys/windows/winnt.d     |   46 +-
 libphobos/libdruntime/core/sys/windows/winuser.d   |   12 +-
 libphobos/libdruntime/core/volatile.d              |    2 +-
 libphobos/libdruntime/object.d                     |   19 +-
 libphobos/libdruntime/rt/lifetime.d                |  366 ------
 libphobos/libdruntime/rt/minfo.d                   |    3 +
 libphobos/src/MERGE                                |    2 +-
 libphobos/src/Makefile.am                          |   17 +-
 libphobos/src/Makefile.in                          |   19 +-
 libphobos/src/std/algorithm/iteration.d            |  361 ++++--
 libphobos/src/std/algorithm/searching.d            |   75 +-
 libphobos/src/std/complex.d                        |   41 +-
 libphobos/src/std/container/rbtree.d               |   25 +
 libphobos/src/std/conv.d                           |  533 +++++++--
 libphobos/src/std/encoding.d                       |    2 +-
 libphobos/src/std/file.d                           |   27 +-
 libphobos/src/std/format/internal/write.d          |   20 +-
 libphobos/src/std/format/write.d                   |   11 +-
 libphobos/src/std/functional.d                     |    1 -
 libphobos/src/std/internal/math/biguintcore.d      |   83 +-
 libphobos/src/std/internal/windows/bcrypt.d        |   65 -
 libphobos/src/std/json.d                           |   47 +
 libphobos/src/std/math/algebraic.d                 |   48 +-
 libphobos/src/std/math/exponential.d               |   43 +-
 libphobos/src/std/net/curl.d                       |    3 +-
 libphobos/src/std/path.d                           |    7 +-
 libphobos/src/std/random.d                         |   84 +-
 libphobos/src/std/sumtype.d                        |   26 +-
 libphobos/src/std/traits.d                         |    9 +-
 libphobos/src/std/uuid.d                           |   60 +-
 libphobos/src/std/variant.d                        |   52 +-
 218 files changed, 6741 insertions(+), 3845 deletions(-)

diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index c43270c61e2c..0b915b5632a4 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -534,7 +534,7 @@ public:
       {
 	FuncDeclaration *fd = d->vtbl[i]->isFuncDeclaration ();
 
-	if (!fd || (!fd->fbody && d->isAbstract ()))
+	if (!fd || (!fd->fbody && dmd::isAbstract (d)))
 	  continue;
 
 	/* Ensure function has a return value.  */
@@ -643,7 +643,7 @@ public:
       {
 	FuncDeclaration *fd = d->vtbl[i]->isFuncDeclaration ();
 
-	if (fd && (fd->fbody || !d->isAbstract ()))
+	if (fd && (fd->fbody || !dmd::isAbstract (d)))
 	  {
 	    CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
 				    build_address (get_symbol_decl (fd)));
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 58d19b4e951d..62d90e5770b5 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-956e73d64e532a68213970316c2590c572ec03f3
+1017635a9636ef6a7a4bda35b1e091875d829871
 
 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 e972d6e93a4d..67e32f8d7ef1 100644
--- a/gcc/d/dmd/VERSION
+++ b/gcc/d/dmd/VERSION
@@ -1 +1 @@
-v2.111.0
+v2.112.0-beta.1
diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d
index 51d6fc459539..6359674d4471 100644
--- a/gcc/d/dmd/aggregate.d
+++ b/gcc/d/dmd/aggregate.d
@@ -187,8 +187,6 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
         return fields.length - isNested() - (vthis2 !is null);
     }
 
-    abstract void finalizeSize();
-
     override final uinteger_t size(Loc loc)
     {
         //printf("+AggregateDeclaration::size() %s, scope = %p, sizeok = %d\n", toChars(), _scope, sizeok);
diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h
index 82f8aeca0808..d89755cea27c 100644
--- a/gcc/d/dmd/aggregate.h
+++ b/gcc/d/dmd/aggregate.h
@@ -120,7 +120,6 @@ public:
     Sizeok sizeok;              // set when structsize contains valid data
 
     virtual Scope *newScope(Scope *sc);
-    virtual void finalizeSize() = 0;
     uinteger_t size(Loc loc) override final;
     Type *getType() override final;
     bool isDeprecated() const override final; // is aggregate deprecated?
@@ -172,7 +171,6 @@ public:
     static StructDeclaration *create(Loc loc, Identifier *id, bool inObject);
     StructDeclaration *syntaxCopy(Dsymbol *s) override;
     const char *kind() const override;
-    void finalizeSize() override final;
     bool isPOD();
     bool zeroInit() const;          // !=0 if initialize with 0 fill
     bool zeroInit(bool v);
@@ -196,7 +194,7 @@ public:
 
     unsigned numArgTypes() const;
     Type *argType(unsigned index);
-    bool hasRegularCtor(bool checkDisabled = false);
+    bool hasRegularCtor(bool ignoreDisabled = false);
 };
 
 class UnionDeclaration final : public StructDeclaration
@@ -287,13 +285,11 @@ public:
     virtual bool isBaseOf(ClassDeclaration *cd, int *poffset);
 
     bool isBaseInfoComplete();
-    void finalizeSize() override;
     bool hasMonitor();
     bool isCOMclass() const;
     virtual bool isCOMinterface() const;
     bool isCPPclass() const;
     virtual bool isCPPinterface() const;
-    bool isAbstract();
     virtual int vtblOffset() const;
     const char *kind() const override;
 
diff --git a/gcc/d/dmd/arraytypes.d b/gcc/d/dmd/arraytypes.d
index 2cd446ea5ed7..bed684b3a425 100644
--- a/gcc/d/dmd/arraytypes.d
+++ b/gcc/d/dmd/arraytypes.d
@@ -29,6 +29,7 @@ alias Strings = Array!(const(char)*);
 alias Identifiers = Array!(Identifier);
 alias TemplateParameters = Array!(TemplateParameter);
 alias Expressions = Array!(Expression);
+alias ArgumentLabels = Array!(ArgumentLabel);
 alias Statements = Array!(Statement);
 alias BaseClasses = Array!(BaseClass*);
 alias ClassDeclarations = Array!(ClassDeclaration);
diff --git a/gcc/d/dmd/arraytypes.h b/gcc/d/dmd/arraytypes.h
index 28165f3ed8ea..a06144332db5 100644
--- a/gcc/d/dmd/arraytypes.h
+++ b/gcc/d/dmd/arraytypes.h
@@ -17,6 +17,8 @@ typedef Array<class TemplateParameter *> TemplateParameters;
 
 typedef Array<class Expression *> Expressions;
 
+typedef Array<struct ArgumentLabel> ArgumentLabels;
+
 typedef Array<class Statement *> Statements;
 
 typedef Array<struct BaseClass *> BaseClasses;
diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d
index 1bfe7902a920..a03e7bbdc0e5 100644
--- a/gcc/d/dmd/attrib.d
+++ b/gcc/d/dmd/attrib.d
@@ -110,11 +110,6 @@ extern (C++) abstract class AttribDeclaration : Dsymbol
         return "attribute";
     }
 
-    override final bool hasPointers()
-    {
-        return this.include(null).foreachDsymbol( (s) { return s.hasPointers(); } ) != 0;
-    }
-
     /****************************************
      */
     override final void addObjcSymbols(ClassDeclarations* classes, ClassDeclarations* categories)
diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h
index ef37e0adece1..24d91abc6275 100644
--- a/gcc/d/dmd/attrib.h
+++ b/gcc/d/dmd/attrib.h
@@ -29,7 +29,6 @@ class AttribDeclaration : public Dsymbol
 public:
     Dsymbols *decl;     // array of Dsymbol's
     const char *kind() const override;
-    bool hasPointers() override final;
     void accept(Visitor *v) override { v->visit(this); }
 };
 
diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d
index 1b11a9f1803b..31c01f1853e6 100644
--- a/gcc/d/dmd/cond.d
+++ b/gcc/d/dmd/cond.d
@@ -24,7 +24,6 @@ import dmd.dscope;
 import dmd.dsymbol;
 import dmd.errors;
 import dmd.expression;
-import dmd.expressionsem : evalStaticCondition;
 import dmd.globals;
 import dmd.identifier;
 import dmd.location;
@@ -71,8 +70,6 @@ extern (C++) abstract class Condition : ASTNode
 
     abstract Condition syntaxCopy();
 
-    abstract int include(Scope* sc);
-
     inout(DebugCondition) isDebugCondition() inout
     {
         return null;
@@ -324,39 +321,6 @@ extern (C++) final class DebugCondition : DVCondition
         super(loc, mod, ident);
     }
 
-    override int include(Scope* sc)
-    {
-        //printf("DebugCondition::include() level = %d, debuglevel = %d\n", level, global.params.debuglevel);
-        if (inc != Include.notComputed)
-        {
-            return inc == Include.yes;
-        }
-        inc = Include.no;
-        bool definedInModule = false;
-        if (ident)
-        {
-            if (mod.debugids && findCondition(*mod.debugids, ident))
-            {
-                inc = Include.yes;
-                definedInModule = true;
-            }
-            else if (findCondition(global.debugids, ident))
-                inc = Include.yes;
-            else
-            {
-                if (!mod.debugidsNot)
-                    mod.debugidsNot = new Identifiers();
-                mod.debugidsNot.push(ident);
-            }
-        }
-        else if (global.params.debugEnabled)
-            inc = Include.yes;
-
-        if (!definedInModule)
-            printDepsConditional(sc, this, "depsDebug ");
-        return (inc == Include.yes);
-    }
-
     override inout(DebugCondition) isDebugCondition() inout
     {
         return this;
@@ -390,7 +354,7 @@ extern (C++) final class VersionCondition : DVCondition
      * Returns:
      *   `true` if it is reserved, `false` otherwise
      */
-    extern(D) private static bool isReserved(const(char)[] ident) @safe
+    extern(D) public static bool isReserved(const(char)[] ident) @safe
     {
         // This list doesn't include "D_*" versions, see the last return
         switch (ident)
@@ -599,41 +563,6 @@ extern (C++) final class VersionCondition : DVCondition
         super(loc, mod, ident);
     }
 
-    override int include(Scope* sc)
-    {
-        //printf("VersionCondition::include() level = %d, versionlevel = %d\n", level, global.params.versionlevel);
-        //if (ident) printf("\tident = '%s'\n", ident.toChars());
-        if (inc != Include.notComputed)
-        {
-            return inc == Include.yes;
-        }
-
-        inc = Include.no;
-        bool definedInModule = false;
-        if (ident)
-        {
-            if (mod.versionids && findCondition(*mod.versionids, ident))
-            {
-                inc = Include.yes;
-                definedInModule = true;
-            }
-            else if (findCondition(global.versionids, ident))
-                inc = Include.yes;
-            else
-            {
-                if (!mod.versionidsNot)
-                    mod.versionidsNot = new Identifiers();
-                mod.versionidsNot.push(ident);
-            }
-        }
-        if (!definedInModule &&
-            (!ident || (!isReserved(ident.toString()) && ident != Id._unittest && ident != Id._assert)))
-        {
-            printDepsConditional(sc, this, "depsVersion ");
-        }
-        return (inc == Include.yes);
-    }
-
     override inout(VersionCondition) isVersionCondition() inout
     {
         return this;
@@ -662,47 +591,6 @@ extern (C++) final class StaticIfCondition : Condition
         return new StaticIfCondition(loc, exp.syntaxCopy());
     }
 
-    override int include(Scope* sc)
-    {
-        // printf("StaticIfCondition::include(sc = %p) this=%p inc = %d\n", sc, this, inc);
-
-        int errorReturn()
-        {
-            if (!global.gag)
-                inc = Include.no; // so we don't see the error message again
-            return 0;
-        }
-
-        if (inc != Include.notComputed)
-        {
-            return inc == Include.yes;
-        }
-
-        if (!sc)
-        {
-            error(loc, "`static if` conditional cannot be at global scope");
-            inc = Include.no;
-            return 0;
-        }
-
-        import dmd.staticcond;
-        bool errors;
-
-        bool result = evalStaticCondition(sc, exp, exp, errors);
-
-        // Prevent repeated condition evaluation.
-        // See: fail_compilation/fail7815.d
-        if (inc != Include.notComputed)
-            return (inc == Include.yes);
-        if (errors)
-            return errorReturn();
-        if (result)
-            inc = Include.yes;
-        else
-            inc = Include.no;
-        return (inc == Include.yes);
-    }
-
     override void accept(Visitor v)
     {
         v.visit(this);
@@ -734,7 +622,7 @@ bool findCondition(ref Identifiers ids, Identifier ident) @safe nothrow pure
 }
 
 // Helper for printing dependency information
-private void printDepsConditional(Scope* sc, DVCondition condition, const(char)[] depType)
+public void printDepsConditional(Scope* sc, DVCondition condition, const(char)[] depType)
 {
     if (!global.params.moduleDeps.buffer || global.params.moduleDeps.name)
         return;
diff --git a/gcc/d/dmd/cond.h b/gcc/d/dmd/cond.h
index 174a8fb9aafc..0afa042f9daa 100644
--- a/gcc/d/dmd/cond.h
+++ b/gcc/d/dmd/cond.h
@@ -38,7 +38,6 @@ public:
     DYNCAST dyncast() const override final { return DYNCAST_CONDITION; }
 
     virtual Condition *syntaxCopy() = 0;
-    virtual int include(Scope *sc) = 0;
     virtual DebugCondition *isDebugCondition() { return nullptr; }
     virtual VersionCondition *isVersionCondition() { return nullptr; }
     void accept(Visitor *v) override { v->visit(this); }
@@ -70,7 +69,6 @@ class DebugCondition final : public DVCondition
 public:
     static void addGlobalIdent(const char *ident);
 
-    int include(Scope *sc) override;
     void accept(Visitor *v) override { v->visit(this); }
 };
 
@@ -80,7 +78,6 @@ public:
     static void addGlobalIdent(const char *ident);
     static void addPredefinedGlobalIdent(const char *ident);
 
-    int include(Scope *sc) override;
     void accept(Visitor *v) override { v->visit(this); }
 };
 
@@ -90,6 +87,5 @@ public:
     Expression *exp;
 
     StaticIfCondition *syntaxCopy() override;
-    int include(Scope *sc) override;
     void accept(Visitor *v) override { v->visit(this); }
 };
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index 1a2a1e9470ea..70369ba20c7a 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -832,8 +832,8 @@ final class CParser(AST) : Parser!AST
                     const len2 = token.len;
                     len = len1 + len2;
                     auto s2 = cast(char*)mem.xmalloc_noscan(len * char.sizeof);
-                    memcpy(s2, s, len1 * char.sizeof);
-                    memcpy(s2 + len1, token.ustring, len2 * char.sizeof);
+                    s2[0 .. len1] = s[0 .. len1];
+                    s2[len1 .. len1 + len2] = token.ustring[0 .. len2];
                     s = s2;
                 }
                 else
@@ -982,6 +982,7 @@ final class CParser(AST) : Parser!AST
      *    sizeof unary-expression
      *    sizeof ( type-name )
      *    _Alignof ( type-name )
+     *    _Alignof unary-expression // gcc extension
      *
      * unary-operator:
      *    & * + - ~ !
@@ -1044,8 +1045,10 @@ final class CParser(AST) : Parser!AST
             e = new AST.ComExp(loc, e);
             break;
 
+        case TOK._Alignof:
         case TOK.sizeof_:
         {
+            Identifier id = token.value == TOK.sizeof_? Id.__sizeof : Id.__xalignof;
             nextToken();
             if (token.value == TOK.leftParenthesis)
             {
@@ -1084,7 +1087,7 @@ final class CParser(AST) : Parser!AST
                 e = cparseUnaryExp();
             }
 
-            e = new AST.DotIdExp(loc, e, Id.__sizeof);
+            e = new AST.DotIdExp(loc, e, id);
             break;
         }
 
@@ -1096,17 +1099,6 @@ final class CParser(AST) : Parser!AST
             e = cparseCastExp();
             break;
 
-        case TOK._Alignof:
-        {
-            nextToken();
-            check(TOK.leftParenthesis);
-            auto t = cparseTypeName();
-            check(TOK.rightParenthesis);
-            e = new AST.TypeExp(loc, t);
-            e = new AST.DotIdExp(loc, e, Id.__xalignof);
-            break;
-        }
-
         default:
             e = cparsePostfixExp(e);
             break;
@@ -1728,6 +1720,34 @@ final class CParser(AST) : Parser!AST
     /********************************* Declaration Parser ***************************/
     //{
 
+    void declareTag(AST.TypeTag tt, ref Specifier specifier, bool generate_enum_id = false)
+    {
+        if (!tt.id && (generate_enum_id || tt.tok != TOK.enum_)) tt.id = Identifier.generateId("__tag");
+        /* `struct tag;` and `struct tag { ... };`
+         * always result in a declaration in the current scope
+         */
+        auto stag = (tt.tok == TOK.struct_) ? new AST.StructDeclaration(tt.loc, tt.id, false) :
+                    (tt.tok == TOK.union_)  ? new AST.UnionDeclaration(tt.loc, tt.id) :
+                                              new AST.EnumDeclaration(tt.loc, tt.id, tt.base);
+        if (!tt.alignExps && !tt.packalign.isUnknown())
+        {
+            // saw `struct __declspec(align(N)) Tag ...`
+            auto st = stag.isStructDeclaration();
+            st.alignment = tt.packalign;
+        }
+        stag.members = tt.members;
+        tt.members = null;
+        if (!symbols)
+            symbols = new AST.Dsymbols();
+        AST.Dsymbol stags = stag;
+        if (tt.alignExps)
+        {
+            auto decls = new AST.Dsymbols(1);
+            (*decls)[0] = stags;
+            stags = new AST.AlignDeclaration(stags.loc, tt.alignExps, decls);
+        }
+        symbols.push(stags);
+    }
     /*************************************
      * C11 6.7
      * declaration:
@@ -1775,28 +1795,9 @@ final class CParser(AST) : Parser!AST
         specifier.packalign = this.packalign;
         auto tspec = cparseDeclarationSpecifiers(level, specifier);
 
-        AST.Dsymbol declareTag(AST.TypeTag tt, ref Specifier specifier)
-        {
-            /* `struct tag;` and `struct tag { ... };`
-             * always result in a declaration in the current scope
-             */
-            auto stag = (tt.tok == TOK.struct_) ? new AST.StructDeclaration(tt.loc, tt.id, false) :
-                        (tt.tok == TOK.union_)  ? new AST.UnionDeclaration(tt.loc, tt.id) :
-                                                  new AST.EnumDeclaration(tt.loc, tt.id, tt.base);
-            if (!tt.packalign.isUnknown())
-            {
-                // saw `struct __declspec(align(N)) Tag ...`
-                auto st = stag.isStructDeclaration();
-                st.alignment = tt.packalign;
-            }
-            stag.members = tt.members;
-            tt.members = null;
-            if (!symbols)
-                symbols = new AST.Dsymbols();
-            auto stags = applySpecifier(stag, specifier);
-            symbols.push(stags);
-            return stags;
-        }
+        // Defer declaring a tagged type (struct/union/enum) so
+        // that anonymous types can use a typedef as their id.
+
 
         /* If a declarator does not follow, it is unnamed
          */
@@ -1822,12 +1823,13 @@ final class CParser(AST) : Parser!AST
                 !tt.id && (tt.tok == TOK.struct_ || tt.tok == TOK.union_))
                 return; // legal but meaningless empty declaration, ignore it
 
-            auto stags = declareTag(tt, specifier);
+            if (tt.members || tt.tok != TOK.enum_)
+                declareTag(tt, specifier);
 
             if (0 && tt.tok == TOK.enum_)    // C11 proscribes enums with no members, but we allow it
             {
                 if (!tt.members)
-                    error(tt.loc, "`enum %s` has no members", stags.toChars());
+                    error(tt.loc, "`enum %s` has no members", tt.toChars());
             }
             return;
         }
@@ -1840,6 +1842,15 @@ final class CParser(AST) : Parser!AST
             return;
         }
 
+        if (auto tt = tspec.isTypeTag())
+        {
+            if (tt.id && tt.members)
+            {
+                // Valid tag decl with name and members, go ahead and declare it now.
+                declareTag(tt, specifier);
+            }
+        }
+
         if (tspec && specifier.mod & MOD.xconst)
         {
             tspec = toConst(tspec);
@@ -1867,7 +1878,7 @@ final class CParser(AST) : Parser!AST
         {
             Identifier id;
             AST.StringExp asmName;
-            auto dt = cparseDeclarator(DTR.xdirect, tspec, id, specifier);
+            auto dt = cparseDeclarator(DTR.xdirect_fd, tspec, id, specifier);
             if (!dt)
             {
                 panic();
@@ -1913,10 +1924,14 @@ final class CParser(AST) : Parser!AST
                     break;
             }
 
-            if (specifier.alignExps && dt.isTypeFunction())
-                error("no alignment-specifier for function declaration"); // C11 6.7.5-2
-            if (specifier.alignExps && specifier.scw == SCW.xregister)
-                error("no alignment-specifier for `register` storage class"); // C11 6.7.5-2
+
+            // Check alignasExp and not alignExps so that gnu
+            // __atribute__((aligned())) is silently allowed, matching the
+            // behavior of other compilers.
+            if (specifier.alignasExp && dt.isTypeFunction())
+                error(specifier.alignasExp.loc, "no alignment-specifier for function declaration"); // C11 6.7.5-2
+            if (specifier.alignasExp && specifier.scw == SCW.xregister)
+                error(specifier.alignasExp.loc, "no alignment-specifier for `register` storage class"); // C11 6.7.5-2
 
             /* C11 6.9.1 Function Definitions
              * function-definition:
@@ -1952,7 +1967,7 @@ final class CParser(AST) : Parser!AST
             typedefTab.setDim(typedefTabLengthSave);
             symbols = symbolsSave;
             if (!symbols)
-                symbols = new AST.Dsymbols;     // lazilly create it
+                symbols = new AST.Dsymbols;     // lazily create it
 
             if (level != LVL.global && !tspec && !specifier.scw && !specifier.mod)
                 error("declaration-specifier-seq required");
@@ -1960,8 +1975,8 @@ final class CParser(AST) : Parser!AST
             {
                 if (token.value == TOK.assign)
                     error("no initializer for typedef declaration");
-                if (specifier.alignExps)
-                    error("no alignment-specifier for typedef declaration"); // C11 6.7.5-2
+                if (specifier.alignasExp)
+                    error(specifier.alignasExp.loc, "no alignment-specifier for typedef declaration"); // C11 6.7.5-2
 
                 if (specifier.vector_size)
                 {
@@ -1973,38 +1988,33 @@ final class CParser(AST) : Parser!AST
 
                 bool isalias = true;
                 Identifier idt;
-                if (auto ts = dt.isTypeStruct())
-                {
-                    if (ts.sym.isAnonymous())
-                    {
-                        // This is a typedef for an anonymous struct-or-union.
-                        // Directly set the ident for the struct-or-union.
-                        ts.sym.ident = id;
-                        isalias = false;
-                    }
-                    idt = ts.sym.ident;
-                }
-                else if (auto te = dt.isTypeEnum())
-                {
-                    if (te.sym.isAnonymous())
-                    {
-                        // This is a typedef for an anonymous enum.
-                        te.sym.ident = id;
-                        isalias = false;
-                    }
-                    idt = te.sym.ident;
-                }
-                else if (auto tt = dt.isTypeTag())
+                if (auto tt = dt.isTypeTag())
                 {
                     if (!tt.id && id)
                         /* This applies for enums declared as
                          * typedef enum {A} E;
+                         * Or for similar structs and unions.
                          */
                         tt.id = id;
-                    Specifier spec;
-                    declareTag(tt, spec);
+                    if (tt.members)
+                    {
+                        Specifier spec;
+                        declareTag(tt, spec);
+                    }
                     idt = tt.id;
                 }
+                else if (auto tt = tspec.isTypeTag())
+                {
+                    // The unusual situation of an anonymous typedef struct where the
+                    // first typedef can't be used as its name.
+                    // Just declare it now so we can get a valid id.
+                    if (!tt.id && tt.members)
+                    {
+                        Specifier spec;
+                        declareTag(tt, spec, true);
+                        idt = tt.id;
+                    }
+                }
                 if (isalias)
                 {
                     //printf("AliasDeclaration %s %s\n", id.toChars(), dt.toChars());
@@ -2033,6 +2043,16 @@ final class CParser(AST) : Parser!AST
                 if (dt.ty == AST.Tvoid)
                     error("`void` has no value");
 
+                if (auto tt = tspec.isTypeTag())
+                {
+                    // Anonymous struct being used as a var decl type
+                    if (!tt.id && tt.members && tt.tok != TOK.enum_)
+                    {
+                        Specifier spec;
+                        declareTag(tt, spec);
+                    }
+                }
+
                 AST.Initializer initializer;
                 bool hasInitializer;
                 if (token.value == TOK.assign)
@@ -2456,25 +2476,7 @@ final class CParser(AST) : Parser!AST
                     const sloc = token.loc;
                     nextToken();
 
-                    Specifier tagSpecifier;
-
-                    /* GNU Extensions
-                     * struct-or-union-specifier:
-                     *    struct-or-union gnu-attributes (opt) identifier (opt) { struct-declaration-list } gnu-attributes (opt)
-                     *    struct-or-union gnu-attribute (opt) identifier
-                     */
-                    while (1)
-                    {
-                        if (token.value == TOK.__attribute__)
-                            cparseGnuAttributes(tagSpecifier);
-                        else if (token.value == TOK.__declspec)
-                            cparseDeclspec(tagSpecifier);
-                        else if (token.value == TOK.__pragma)
-                            uupragmaDirective(sloc);
-                        else
-                            break;
-                    }
-                    t = cparseStruct(sloc, structOrUnion, tagSpecifier.packalign, symbols);
+                    t = cparseStruct(sloc, structOrUnion, symbols);
                     tkwx = TKW.xtag;
                     break;
                 }
@@ -2536,6 +2538,7 @@ final class CParser(AST) : Parser!AST
                     if (!specifier.alignExps)
                         specifier.alignExps = new AST.Expressions(0);
                     specifier.alignExps.push(exp);
+                    specifier.alignasExp = exp;
 
                     check(TOK.rightParenthesis);
                     break;
@@ -2839,6 +2842,18 @@ final class CParser(AST) : Parser!AST
         //printf("cparseDeclarator(%d, %s)\n", declarator, tbase.toChars());
         AST.Types constTypes; // all the Types that will need `const` applied to them
 
+        // this.symbols can get changed to the symbol table for the
+        // parameter-type-list if we parse a function type.
+        // Callers are only ready to handle this if they pass DTR.xdirect_fd,
+        // so remember to restore this.symbols.
+        bool restore_symbols = true;
+        if (declarator == DTR.xdirect_fd)
+        {
+            declarator = DTR.xdirect;
+            restore_symbols = false;
+        }
+
+
         /* Insert tx -> t into
          *   ts -> ... -> t
          * so that
@@ -3030,7 +3045,7 @@ final class CParser(AST) : Parser!AST
                         //tf = tf.addSTC(storageClass);  // TODO
                         insertTx(ts, tf, t);  // ts -> ... -> tf -> t
 
-                        if (ts != tf)
+                        if (ts != tf || restore_symbols)
                             this.symbols = symbolsSave;
                         break;
                     }
@@ -3511,12 +3526,12 @@ final class CParser(AST) : Parser!AST
 
                 case TOK.colonColon:  // treat as two separate : tokens for iasmgcc
                     *ptoklist = allocateToken();
-                    memcpy(*ptoklist, &token, Token.sizeof);
+                    **ptoklist = this.token;
                     (*ptoklist).value = TOK.colon;
                     ptoklist = &(*ptoklist).next;
 
                     *ptoklist = allocateToken();
-                    memcpy(*ptoklist, &token, Token.sizeof);
+                    **ptoklist = this.token;
                     (*ptoklist).value = TOK.colon;
                     ptoklist = &(*ptoklist).next;
 
@@ -3526,7 +3541,7 @@ final class CParser(AST) : Parser!AST
 
                 default:
                     *ptoklist = allocateToken();
-                    memcpy(*ptoklist, &token, Token.sizeof);
+                    **ptoklist = this.token;
                     ptoklist = &(*ptoklist).next;
                     *ptoklist = null;
                     nextToken();
@@ -3620,26 +3635,18 @@ final class CParser(AST) : Parser!AST
                 if (token.value == TOK.leftParenthesis)
                 {
                     nextToken();
-                    if (token.value == TOK.int32Literal)
-                    {
-                        const n = token.unsvalue;
-                        if (n < 1 || n & (n - 1) || ushort.max < n)
-                            error("__attribute__((aligned(%lld))) must be an integer positive power of 2 and be <= 32,768", cast(ulong)n);
-                        specifier.packalign.set(cast(uint)n);
-                        specifier.packalign.setPack(true);
-                        nextToken();
-                    }
-                    else
-                    {
-                        error("alignment value expected, not `%s`", token.toChars());
-                        nextToken();
-                    }
-
+                    AST.Expression exp = cparseConstantExp();
+                    if (!specifier.alignExps)
+                        specifier.alignExps = new AST.Expressions(0);
+                    specifier.alignExps.push(exp);
                     check(TOK.rightParenthesis);
                 }
-                /* ignore __attribute__((aligned)), which sets the alignment to the largest value for any data
-                 * type on the target machine. It's the opposite of __attribute__((packed))
-                 */
+                else
+                {
+                    /* ignore __attribute__((aligned)), which sets the alignment to the largest value for any data
+                     * type on the target machine. It's the opposite of __attribute__((packed))
+                     */
+                }
             }
             else if (token.ident == Id.packed)
             {
@@ -3951,7 +3958,7 @@ final class CParser(AST) : Parser!AST
          * redeclaration, or reference to existing declaration.
          * Defer to the semantic() pass with a TypeTag.
          */
-        return new AST.TypeTag(loc, TOK.enum_, tag, structalign_t.init, base, members);
+        return new AST.TypeTag(loc, TOK.enum_, tag, structalign_t.init, null, base, members);
     }
 
     /*************************************
@@ -3978,8 +3985,25 @@ final class CParser(AST) : Parser!AST
      * Returns:
      *  type of the struct
      */
-    private AST.Type cparseStruct(Loc loc, TOK structOrUnion, structalign_t packalign, ref AST.Dsymbols* symbols)
+    private AST.Type cparseStruct(Loc loc, TOK structOrUnion, ref AST.Dsymbols* symbols)
     {
+        /* GNU Extensions
+         * struct-or-union-specifier:
+         *    struct-or-union gnu-attributes (opt) identifier (opt) { struct-declaration-list } gnu-attributes (opt)
+         *    struct-or-union gnu-attribute (opt) identifier
+         */
+        Specifier tagSpecifier;
+        while (1)
+        {
+            if (token.value == TOK.__attribute__)
+                cparseGnuAttributes(tagSpecifier);
+            else if (token.value == TOK.__declspec)
+                cparseDeclspec(tagSpecifier);
+            else if (token.value == TOK.__pragma)
+                uupragmaDirective(loc);
+            else
+                break;
+        }
         Identifier tag;
 
         if (token.value == TOK.identifier)
@@ -3995,7 +4019,7 @@ final class CParser(AST) : Parser!AST
             members = new AST.Dsymbols();          // so `members` will be non-null even with 0 members
             while (token.value != TOK.rightCurly)
             {
-                cparseStructDeclaration(members, packalign);
+                cparseStructDeclaration(members, tagSpecifier.packalign);
 
                 if (token.value == TOK.endOfFile)
                     break;
@@ -4013,18 +4037,18 @@ final class CParser(AST) : Parser!AST
             /* GNU Extensions
              * Parse the postfix gnu-attributes (opt)
              */
-            Specifier specifier;
             if (token.value == TOK.__attribute__)
-                cparseGnuAttributes(specifier);
-            if (!specifier.packalign.isUnknown)
+                cparseGnuAttributes(tagSpecifier);
+            if (!tagSpecifier.packalign.isUnknown)
             {
-                packalign.set(specifier.packalign.get());
-                packalign.setPack(specifier.packalign.isPack());
                 foreach (ref d; (*members)[])
                 {
+                    // skip possible static assert declarations
+                    if (d.isStaticAssert()) continue;
+
                     auto decls = new AST.Dsymbols(1);
                     (*decls)[0] = d;
-                    d = new AST.AlignDeclaration(d.loc, specifier.packalign, decls);
+                    d = new AST.AlignDeclaration(d.loc, tagSpecifier.packalign, decls);
                 }
             }
         }
@@ -4032,14 +4056,14 @@ final class CParser(AST) : Parser!AST
             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());
+        if (tagSpecifier.packalign.isUnknown() && !this.packalign.isUnknown())
+            tagSpecifier.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.
          */
-        return new AST.TypeTag(loc, structOrUnion, tag, packalign, null, members);
+        return new AST.TypeTag(loc, structOrUnion, tag, tagSpecifier.packalign, tagSpecifier.alignExps, null, members);
     }
 
     /*************************************
@@ -4103,7 +4127,7 @@ final class CParser(AST) : Parser!AST
              *   struct { ... members ... };
              * C11 6.7.2.1-13
              */
-            if (!tt.id && tt.members)
+            if (!tt.id && tt.members && tt.tok != TOK.enum_)
             {
                 /* members of anonymous struct are considered members of
                  * the containing struct
@@ -4119,17 +4143,19 @@ final class CParser(AST) : Parser!AST
             /* `struct tag;` and `struct tag { ... };`
              * always result in a declaration in the current scope
              */
-            // TODO: merge in specifier
-            auto stag = (tt.tok == TOK.struct_)
-                ? new AST.StructDeclaration(tt.loc, tt.id, false)
-                : new AST.UnionDeclaration(tt.loc, tt.id);
-            stag.members = tt.members;
-            if (!symbols)
-                symbols = new AST.Dsymbols();
-            auto s = applySpecifier(stag, specifier);
-            symbols.push(s);
+            Specifier spec;
+            declareTag(tt, spec);
             return;
         }
+        if (auto tt = tspec.isTypeTag())
+        {
+            // Declare the tagged type at this point.
+            if (tt.members)
+            {
+                Specifier spec;
+                declareTag(tt, spec);
+            }
+        }
 
         while (1)
         {
@@ -4178,8 +4204,8 @@ final class CParser(AST) : Parser!AST
                 error("specifier-qualifier-list required");
             else if (width)
             {
-                if (specifier.alignExps)
-                    error("no alignment-specifier for bit field declaration"); // C11 6.7.5-2
+                if (specifier.alignasExp)
+                    error(specifier.alignasExp.loc, "no alignment-specifier for bit field declaration"); // C11 6.7.5-2
                 auto s = new AST.BitFieldDeclaration(width.loc, dt, id, width);
                 members.push(s);
             }
@@ -4998,6 +5024,7 @@ final class CParser(AST) : Parser!AST
                     return false;
                 break;
 
+            case TOK._Alignof:
             case TOK.sizeof_:
                 t = peek(t);
                 if (t.value == TOK.leftParenthesis)
@@ -5015,15 +5042,6 @@ final class CParser(AST) : Parser!AST
                     return false;
                 break;
 
-            case TOK._Alignof:
-                t = peek(t);
-                if (t.value != TOK.leftParenthesis)
-                    return false;
-                t = peek(t);
-                if (!isTypeName(t) || t.value != TOK.rightParenthesis)
-                    return false;
-                break;
-
             default:
                 // Compound literals are handled by cast and sizeof expressions,
                 // so be content with just seeing a primary expression.
@@ -5104,6 +5122,7 @@ final class CParser(AST) : Parser!AST
     /// Types of declarator to parse
     enum DTR
     {
+        xdirect_fd = 0, /// C11 6.7.6 direct-declarator, allow to start function definition
         xdirect    = 1, /// C11 6.7.6 direct-declarator
         xabstract  = 2, /// C11 6.7.7 abstract-declarator
         xparameter = 3, /// parameter declarator may be either direct or abstract
@@ -5155,6 +5174,7 @@ final class CParser(AST) : Parser!AST
         SCW scw;        /// storage-class specifiers
         MOD mod;        /// type qualifiers
         AST.Expressions*  alignExps;  /// alignment
+        AST.Expression alignasExp; /// Last _Alignas() for errors
         structalign_t packalign;  /// #pragma pack alignment value
     }
 
@@ -6050,6 +6070,8 @@ final class CParser(AST) : Parser!AST
             //printf("addSym() %s\n", s.toChars());
             if (auto v = s.isVarDeclaration())
                 v.isCmacro(true);       // mark it as coming from a C #define
+            if (auto td = s.isTemplateDeclaration())
+                td.isCmacro = true; // mark as coming from a C #define
             /* If it's already defined, replace the earlier
              * definition
              */
@@ -6073,6 +6095,14 @@ final class CParser(AST) : Parser!AST
             }
         }
 
+        void nextLine()
+        {
+            // scan to end of line
+            while (*p)
+                ++p;
+            ++p; // advance to start of next line
+        }
+
         while (p < endp)
         {
             //printf("|%s|\n", p);
@@ -6084,6 +6114,13 @@ final class CParser(AST) : Parser!AST
                 if (token.value == TOK.identifier)
                 {
                     auto id = token.ident;
+                    // https://github.com/dlang/dmd/issues/20423
+                    // skip macros that could shadow special builtins
+                    if (id == Id.va_arg)
+                    {
+                        nextLine();
+                        continue;
+                    }
                     const params = *p == '(';
                     nextToken();
 
@@ -6181,7 +6218,7 @@ final class CParser(AST) : Parser!AST
                                 /* Declare manifest constant:
                                  *  enum id = "string";
                                  */
-                                AST.Expression e = new AST.StringExp(scanloc, str[0 .. len], len, 1, postfix);
+                                AST.Expression e = new AST.StringExp(scanloc, str[0 .. len], len, 1, postfix, true);
                                 auto v = new AST.VarDeclaration(scanloc, null, id, new AST.ExpInitializer(scanloc, e), STC.manifest);
                                 addSym(v);
                                 ++p;
@@ -6329,10 +6366,7 @@ final class CParser(AST) : Parser!AST
                 if (token.value == TOK.identifier)
                     removeSym(token.ident);
             }
-            // scan to end of line
-            while (*p)
-                ++p;
-            ++p; // advance to start of next line
+            nextLine();
         }
 
         if (newSymbols.length)
diff --git a/gcc/d/dmd/cxxfrontend.d b/gcc/d/dmd/cxxfrontend.d
index 234b6523afbf..b61137ff20fa 100644
--- a/gcc/d/dmd/cxxfrontend.d
+++ b/gcc/d/dmd/cxxfrontend.d
@@ -112,11 +112,6 @@ void mangleToBuffer(TemplateInstance ti, ref OutBuffer buf)
 /***********************************************************
  * dmodule.d
  */
-void getLocalClasses(Module mod, ref ClassDeclarations aclasses)
-{
-    return dmd.dmodule.getLocalClasses(mod, aclasses);
-}
-
 FuncDeclaration findGetMembers(ScopeDsymbol dsym)
 {
     return dmd.dmodule.findGetMembers(dsym);
@@ -192,6 +187,24 @@ Dsymbol vtblSymbol(ClassDeclaration cd)
     return dmd.dsymbolsem.vtblSymbol(cd);
 }
 
+bool isAbstract(ClassDeclaration cd)
+{
+    import dmd.dsymbolsem;
+    return dmd.dsymbolsem.isAbstract(cd);
+}
+
+bool hasPointers(Dsymbol d)
+{
+    import dmd.dsymbolsem;
+    return dmd.dsymbolsem.hasPointers(d);
+}
+
+void getLocalClasses(Module mod, ref ClassDeclarations aclasses)
+{
+    import dmd.dsymbolsem;
+    return dmd.dsymbolsem.getLocalClasses(mod, aclasses);
+}
+
 /***********************************************************
  * dtemplate.d
  */
@@ -256,7 +269,7 @@ Expression getDefaultValue(EnumDeclaration ed, Loc loc)
 /***********************************************************
  * expression.d
  */
-void expandTuples(Expressions* exps, Identifiers* names = null)
+void expandTuples(Expressions* exps, ArgumentLabels* names = null)
 {
     return dmd.expression.expandTuples(exps, names);
 }
@@ -305,7 +318,7 @@ bool functionSemantic3(FuncDeclaration fd)
     return dmd.funcsem.functionSemantic3(fd);
 }
 
-MATCH leastAsSpecialized(FuncDeclaration fd, FuncDeclaration g, Identifiers* names)
+MATCH leastAsSpecialized(FuncDeclaration fd, FuncDeclaration g, ArgumentLabels* names)
 {
     import dmd.funcsem;
     return dmd.funcsem.leastAsSpecialized(fd, g, names);
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index 86d2f0f07c3f..9e35dde29697 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -27,7 +27,6 @@ import dmd.dstruct;
 import dmd.dsymbol;
 import dmd.dsymbolsem;
 import dmd.errors;
-import dmd.escape;
 import dmd.expression;
 import dmd.expressionsem;
 import dmd.func;
@@ -149,8 +148,40 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
                 //type = type.typeSemantic(loc, sc);
                 //printf("type %s t %s\n", type.deco, t.deco);
                 auto ts = toAutoQualChars(e.type, t);
-                error(e.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`",
-                    e.toErrMsg(), ts[0], ts[1]);
+
+                // Special case for improved diagnostic when const to mutable conversion
+                // fails due to struct/union having pointers
+                if (e.type.ty == Tstruct && t.ty == Tstruct &&
+                    e.type.isTypeStruct().sym == t.isTypeStruct().sym &&
+                    e.type.mod == MODFlags.const_ && t.mod == 0 && e.type.hasPointers)
+                {
+                    auto sym = e.type.isTypeStruct().sym;
+                    error(e.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s` because %s `%s` contains pointers or references",
+                        e.toErrMsg(), ts[0], ts[1], sym.kind(), sym.toErrMsg());
+                    return ErrorExp.get();
+                }
+
+                // Special case for pointer conversions
+                if (e.type.toBasetype().ty == Tpointer && t.toBasetype().ty == Tpointer)
+                {
+                    Type fromPointee = e.type.nextOf();
+                    Type toPointee = t.nextOf();
+                    // Const -> mutable conversion (disallowed)
+                    if (fromPointee.isConst() && !toPointee.isConst())
+                    {
+                        error(e.loc, "cannot implicitly convert `%s` to `%s`", e.type.toChars(), t.toChars());
+                        errorSupplemental(e.loc, "Note: Converting const to mutable requires an explicit cast (`cast(int*)`).");
+                        return ErrorExp.get();
+                    }
+                    // Incompatible pointee types (e.g., int* -> float* )
+                    else if (fromPointee.toBasetype().ty != toPointee.toBasetype().ty)
+                    {
+                        error(e.loc, "cannot implicitly convert `%s` to `%s`", e.type.toChars(), t.toChars());
+                        errorSupplemental(e.loc, "Note: Pointer types point to different base types (`%s` vs `%s`)", fromPointee.toChars(), toPointee.toChars());
+                        return ErrorExp.get();
+                    }
+                }
+                error(e.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`", e.toErrMsg(), ts[0], ts[1]);
             }
         }
         return ErrorExp.get();
@@ -2715,13 +2746,6 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
         ArrayLiteralExp ae = e;
 
         Type tb = t.toBasetype();
-        if (tb.ty == Tarray)
-        {
-            if (checkArrayLiteralEscape(*sc, ae, false))
-            {
-                return ErrorExp.get();
-            }
-        }
 
         if (e.type == t)
         {
diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d
index 80d39fac4267..51ac939ade09 100644
--- a/gcc/d/dmd/dclass.d
+++ b/gcc/d/dmd/dclass.d
@@ -23,7 +23,6 @@ import dmd.gluelayer;
 import dmd.declaration;
 import dmd.dscope;
 import dmd.dsymbol;
-import dmd.dsymbolsem : dsymbolSemantic, addMember, setFieldOffset;
 import dmd.errors;
 import dmd.func;
 import dmd.id;
@@ -33,7 +32,6 @@ import dmd.mtype;
 import dmd.objc;
 import dmd.root.rmem;
 import dmd.target;
-import dmd.typesem : covariant, immutableOf, sarrayOf;
 import dmd.visitor;
 
 /***********************************************************
@@ -496,116 +494,6 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
         return null;
     }
 
-    final override void finalizeSize()
-    {
-        assert(sizeok != Sizeok.done);
-
-        // Set the offsets of the fields and determine the size of the class
-        if (baseClass)
-        {
-            assert(baseClass.sizeok == Sizeok.done);
-
-            alignsize = baseClass.alignsize;
-            if (classKind == ClassKind.cpp)
-                structsize = target.cpp.derivedClassOffset(baseClass);
-            else
-                structsize = baseClass.structsize;
-        }
-        else if (classKind == ClassKind.objc)
-            structsize = 0; // no hidden member for an Objective-C class
-        else if (isInterfaceDeclaration())
-        {
-            if (interfaces.length == 0)
-            {
-                alignsize = target.ptrsize;
-                structsize = target.ptrsize;      // allow room for __vptr
-            }
-        }
-        else
-        {
-            alignsize = target.ptrsize;
-            structsize = target.ptrsize;      // allow room for __vptr
-            if (hasMonitor())
-                structsize += target.ptrsize; // allow room for __monitor
-        }
-
-        //printf("finalizeSize() %s, sizeok = %d\n", toChars(), sizeok);
-        size_t bi = 0;                  // index into vtblInterfaces[]
-
-        /****
-         * Runs through the inheritance graph to set the BaseClass.offset fields.
-         * Recursive in order to account for the size of the interface classes, if they are
-         * more than just interfaces.
-         * Params:
-         *      cd = interface to look at
-         *      baseOffset = offset of where cd will be placed
-         * Returns:
-         *      subset of instantiated size used by cd for interfaces
-         */
-        uint membersPlace(ClassDeclaration cd, uint baseOffset)
-        {
-            //printf("    membersPlace(%s, %d)\n", cd.toChars(), baseOffset);
-            uint offset = baseOffset;
-
-            foreach (BaseClass* b; cd.interfaces)
-            {
-                if (b.sym.sizeok != Sizeok.done)
-                    b.sym.finalizeSize();
-                assert(b.sym.sizeok == Sizeok.done);
-
-                if (!b.sym.alignsize)
-                    b.sym.alignsize = target.ptrsize;
-                offset = alignmember(structalign_t(cast(ushort)b.sym.alignsize), b.sym.alignsize, offset);
-                assert(bi < vtblInterfaces.length);
-
-                BaseClass* bv = (*vtblInterfaces)[bi];
-                if (b.sym.interfaces.length == 0)
-                {
-                    //printf("\tvtblInterfaces[%d] b=%p b.sym = %s, offset = %d\n", bi, bv, bv.sym.toChars(), offset);
-                    bv.offset = offset;
-                    ++bi;
-                    // All the base interfaces down the left side share the same offset
-                    for (BaseClass* b2 = bv; b2.baseInterfaces.length; )
-                    {
-                        b2 = &b2.baseInterfaces[0];
-                        b2.offset = offset;
-                        //printf("\tvtblInterfaces[%d] b=%p   sym = %s, offset = %d\n", bi, b2, b2.sym.toChars(), b2.offset);
-                    }
-                }
-                membersPlace(b.sym, offset);
-                //printf(" %s size = %d\n", b.sym.toChars(), b.sym.structsize);
-                offset += b.sym.structsize;
-                if (alignsize < b.sym.alignsize)
-                    alignsize = b.sym.alignsize;
-            }
-            return offset - baseOffset;
-        }
-
-        structsize += membersPlace(this, structsize);
-
-        if (isInterfaceDeclaration())
-        {
-            sizeok = Sizeok.done;
-            return;
-        }
-
-        // FIXME: Currently setFieldOffset functions need to increase fields
-        // to calculate each variable offsets. It can be improved later.
-        fields.setDim(0);
-
-        FieldState fieldState;
-        fieldState.offset = structsize;
-        foreach (s; *members)
-        {
-            s.setFieldOffset(this, &fieldState, false);
-        }
-
-        sizeok = Sizeok.done;
-
-        // Calculate fields[i].overlapped
-        checkOverlappedFields();
-    }
-
     /**************
      * Returns: true if there's a __monitor field
      */
@@ -757,106 +645,6 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
         return false;
     }
 
-    /****************************************
-     */
-    final bool isAbstract()
-    {
-        enum log = false;
-        if (isabstract != ThreeState.none)
-            return isabstract == ThreeState.yes;
-
-        if (log) printf("isAbstract(%s)\n", toChars());
-
-        bool no()  { if (log) printf("no\n");  isabstract = ThreeState.no;  return false; }
-        bool yes() { if (log) printf("yes\n"); isabstract = ThreeState.yes; return true;  }
-
-        if (storage_class & STC.abstract_ || _scope && _scope.stc & STC.abstract_)
-            return yes();
-
-        if (errors)
-            return no();
-
-        /* https://issues.dlang.org/show_bug.cgi?id=11169
-         * Resolve forward references to all class member functions,
-         * and determine whether this class is abstract.
-         */
-        static int func(Dsymbol s, void*)
-        {
-            auto fd = s.isFuncDeclaration();
-            if (!fd)
-                return 0;
-            if (fd.storage_class & STC.static_)
-                return 0;
-
-            if (fd.isAbstract())
-                return 1;
-            return 0;
-        }
-
-        // opaque class is not abstract if it is not declared abstract
-        if (!members)
-            return no();
-
-        for (size_t i = 0; i < members.length; i++)
-        {
-            auto s = (*members)[i];
-            if (s.apply(&func, null))
-            {
-                return yes();
-            }
-        }
-
-        /* If the base class is not abstract, then this class cannot
-         * be abstract.
-         */
-        if (!isInterfaceDeclaration() && (!baseClass || !baseClass.isAbstract()))
-            return no();
-
-        /* If any abstract functions are inherited, but not overridden,
-         * then the class is abstract. Do this by checking the vtbl[].
-         * Need to do semantic() on class to fill the vtbl[].
-         */
-        this.dsymbolSemantic(null);
-
-        /* The next line should work, but does not because when ClassDeclaration.dsymbolSemantic()
-         * is called recursively it can set PASS.semanticdone without finishing it.
-         */
-        //if (semanticRun < PASS.semanticdone)
-        {
-            /* Could not complete semantic(). Try running semantic() on
-             * each of the virtual functions,
-             * which will fill in the vtbl[] overrides.
-             */
-            static int virtualSemantic(Dsymbol s, void*)
-            {
-                auto fd = s.isFuncDeclaration();
-                if (fd && !(fd.storage_class & STC.static_) && !fd.isUnitTestDeclaration())
-                    fd.dsymbolSemantic(null);
-                return 0;
-            }
-
-            for (size_t i = 0; i < members.length; i++)
-            {
-                auto s = (*members)[i];
-                s.apply(&virtualSemantic,null);
-            }
-        }
-
-        /* Finally, check the vtbl[]
-         */
-        foreach (i; 1 .. vtbl.length)
-        {
-            auto fd = vtbl[i].isFuncDeclaration();
-            //if (fd) printf("\tvtbl[%d] = [%s] %s\n", i, fd.loc.toChars(), fd.toPrettyChars());
-            if (!fd || fd.isAbstract())
-            {
-                return yes();
-            }
-        }
-
-        return no();
-    }
-
     /****************************************
      * Determine if slot 0 of the vtbl[] is reserved for something else.
      * For class objects, yes, this is where the classinfo ptr goes.
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index 4510927da711..25e5c31dcc6f 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -27,7 +27,6 @@ import dmd.dtemplate;
 import dmd.errors;
 import dmd.expression;
 import dmd.func;
-import dmd.funcsem : overloadApply, getLevelAndCheck;
 import dmd.globals;
 import dmd.gluelayer;
 import dmd.hdrgen;
@@ -783,25 +782,6 @@ extern (C++) final class OverDeclaration : Declaration
         return true;
     }
 
-    Dsymbol isUnique()
-    {
-        Dsymbol result = null;
-        overloadApply(aliassym, (Dsymbol s)
-        {
-            if (result)
-            {
-                result = null;
-                return 1; // ambiguous, done
-            }
-            else
-            {
-                result = s;
-                return 0;
-            }
-        });
-        return result;
-    }
-
     override void accept(Visitor v)
     {
         v.visit(this);
@@ -1054,12 +1034,6 @@ extern (C++) class VarDeclaration : Declaration
                 vbitoffset <  bitoffset + tbitsize;
     }
 
-    override final bool hasPointers()
-    {
-        //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type.ty);
-        return (!isDataseg() && type.hasPointers());
-    }
-
     /*************************************
      * Return true if we can take the address of this variable.
      */
@@ -1109,83 +1083,6 @@ extern (C++) class VarDeclaration : Declaration
         return e;
     }
 
-    /************************************
-     * Check to see if this variable is actually in an enclosing function
-     * rather than the current one.
-     * Update nestedrefs[], closureVars[] and outerVars[].
-     * Returns: true if error occurs.
-     */
-    extern (D) final bool checkNestedReference(Scope* sc, Loc loc)
-    {
-        //printf("VarDeclaration::checkNestedReference() %s\n", toChars());
-        if (sc.intypeof == 1 || sc.ctfe)
-            return false;
-        if (!parent || parent == sc.parent)
-            return false;
-        if (isDataseg() || (storage_class & STC.manifest))
-            return false;
-
-        // The current function
-        FuncDeclaration fdthis = sc.parent.isFuncDeclaration();
-        if (!fdthis)
-            return false; // out of function scope
-
-        Dsymbol p = toParent2();
-
-        // Function literals from fdthis to p must be delegates
-        ensureStaticLinkTo(fdthis, p);
-
-        // The function that this variable is in
-        FuncDeclaration fdv = p.isFuncDeclaration();
-        if (!fdv || fdv == fdthis)
-            return false;
-
-        // Add fdthis to nestedrefs[] if not already there
-        if (!nestedrefs.contains(fdthis))
-            nestedrefs.push(fdthis);
-
-        //printf("\tfdv = %s\n", fdv.toChars());
-        //printf("\tfdthis = %s\n", fdthis.toChars());
-        if (loc.isValid())
-        {
-            if (fdthis.getLevelAndCheck(loc, sc, fdv, this) == fdthis.LevelError)
-                return true;
-        }
-
-        // Add this VarDeclaration to fdv.closureVars[] if not already there
-        if (!sc.intypeof && !sc.traitsCompiles &&
-            // https://issues.dlang.org/show_bug.cgi?id=17605
-            (fdv.skipCodegen || !fdthis.skipCodegen))
-        {
-            if (!fdv.closureVars.contains(this))
-                fdv.closureVars.push(this);
-        }
-
-        if (!fdthis.outerVars.contains(this))
-            fdthis.outerVars.push(this);
-
-        //printf("fdthis is %s\n", fdthis.toChars());
-        //printf("var %s in function %s is nested ref\n", toChars(), fdv.toChars());
-        // __dollar creates problems because it isn't a real variable
-        // https://issues.dlang.org/show_bug.cgi?id=3326
-        if (ident == Id.dollar)
-        {
-            .error(loc, "cannnot use `$` inside a function literal");
-            return true;
-        }
-        if (ident == Id.withSym) // https://issues.dlang.org/show_bug.cgi?id=1759
-        {
-            ExpInitializer ez = _init.isExpInitializer();
-            assert(ez);
-            Expression e = ez.exp;
-            if (e.op == EXP.construct || e.op == EXP.blit)
-                e = (cast(AssignExp)e).e2;
-            return lambdaCheckForNestedRef(e, sc);
-        }
-
-        return false;
-    }
-
     override final Dsymbol toAlias()
     {
         //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym);
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index c7e45526084d..74ea20cb56f8 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -35,10 +35,11 @@ namespace dmd
     bool functionSemantic(FuncDeclaration* fd);
     bool functionSemantic3(FuncDeclaration* fd);
     bool checkClosure(FuncDeclaration* fd);
-    MATCH leastAsSpecialized(FuncDeclaration *f, FuncDeclaration *g, Identifiers *names);
+    MATCH leastAsSpecialized(FuncDeclaration *f, FuncDeclaration *g, ArgumentLabels *names);
     PURE isPure(FuncDeclaration *f);
     FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name, StorageClass stc=0);
     FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id, StorageClass stc=0);
+    bool isAbstract(ClassDeclaration *cd);
 }
 
 //enum STC : ulong from astenums.d:
@@ -297,7 +298,6 @@ public:
     bool isThreadlocal() override final;
     bool isCTFE();
     bool isOverlappedWith(VarDeclaration *v);
-    bool hasPointers() override final;
     bool canTakeAddressOf();
     bool needsScopeDtor();
     Dsymbol *toAlias() override final;
diff --git a/gcc/d/dmd/delegatize.d b/gcc/d/dmd/delegatize.d
index 344130b5e31d..1f5dca66b598 100644
--- a/gcc/d/dmd/delegatize.d
+++ b/gcc/d/dmd/delegatize.d
@@ -21,6 +21,7 @@ import dmd.dsymbol;
 import dmd.expression;
 import dmd.expressionsem;
 import dmd.func;
+import dmd.funcsem : checkNestedReference;
 import dmd.init;
 import dmd.initsem;
 import dmd.location;
diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d
index 13051db37897..543c0e22e39f 100644
--- a/gcc/d/dmd/dinterpret.d
+++ b/gcc/d/dmd/dinterpret.d
@@ -1027,12 +1027,6 @@ Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate)
          * assigning a larger array into a smaller one, such as:
          *    `a = [1, 2], a ~= [3]` => `[1, 2] ~= [3]` => `[1, 2] = [1, 2, 3]`
          */
-        if (isRuntimeHook(s.exp, Id._d_arrayappendT) || isRuntimeHook(s.exp, Id._d_arrayappendTTrace))
-        {
-            auto rs = new ReturnStatement(s.loc, e);
-            visitReturn(rs);
-            return;
-        }
 
         // Disallow returning pointers to stack-allocated variables (bug 7876)
         if (!stopPointersEscaping(s.loc, e))
@@ -3189,7 +3183,8 @@ public:
             if (cmp == -1)
             {
                 char dir = (e.op == EXP.greaterThan || e.op == EXP.greaterOrEqual) ? '<' : '>';
-                error(e.loc, "the ordering of pointers to unrelated memory blocks is indeterminate in CTFE. To check if they point to the same memory block, use both `>` and `<` inside `&&` or `||`, eg `%s && %s %c= %s + 1`", e.toChars(), e.e1.toChars(), dir, e.e2.toChars());
+                error(e.loc, "the ordering of pointers to unrelated memory blocks is indeterminate in CTFE.");
+                errorSupplemental(e.loc, "to check if they point to the same memory block, use both `>` and `<` inside `&&` or `||`, eg `%s && %s %c= %s + 1`", e.toChars(), e.e1.toChars(), dir, e.e2.toChars());
                 result = CTFEExp.cantexp;
                 return;
             }
@@ -5001,61 +4996,6 @@ public:
             printf("%s CommaExp::interpret() %s\n", e.loc.toChars(), e.toChars());
         }
 
-        bool isNewThrowableHook()
-        {
-            auto de = e.e1.isDeclarationExp();
-            if (de is null)
-                return false;
-
-            auto vd = de.declaration.isVarDeclaration();
-            if (vd is null)
-                return false;
-
-            auto ei = vd._init.isExpInitializer();
-            if (ei is null)
-                return false;
-
-            auto ce = ei.exp.isConstructExp();
-            if (ce is null)
-                return false;
-
-            return isRuntimeHook(ce.e2, Id._d_newThrowable) !is null;
-        }
-
-        if (auto ce = isRuntimeHook(e.e1, Id._d_arrayappendcTX))
-        {
-            // In expressionsem.d `arr ~= elem` was lowered to
-            // `_d_arrayappendcTX(arr, elem), arr[arr.length - 1] = elem, elem;`.
-            // The following code will rewrite it back to `arr ~= elem`
-            // and then interpret that expression.
-            assert(ce.arguments.length == 2);
-
-            auto arr = (*ce.arguments)[0];
-            auto elem = e.e2.isConstructExp().e2;
-            assert(elem);
-
-            auto cae = new CatAssignExp(e.loc, arr, elem);
-            cae.type = arr.type;
-
-            result = interpret(cae, istate);
-            return;
-        }
-        else if (isNewThrowableHook())
-        {
-            // In expressionsem.d `throw new Exception(args)` was lowered to
-            // `throw (tmp = _d_newThrowable!Exception(), tmp.ctor(args), tmp)`.
-            // The following code will rewrite it back to `throw new Exception(args)`
-            // and then interpret this expression instead.
-            auto ce = e.e2.isCallExp();
-            assert(ce);
-
-            auto ne = new NewExp(e.loc, null, null, e.type, ce.arguments);
-            ne.type = e.e1.type;
-
-            result = interpret(ne, istate);
-            return;
-        }
-
         // If it creates a variable, and there's no context for
         // the variable to be created in, we need to create one now.
         InterState istateComma;
diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d
index 0e0070aab588..33539d4bf0b8 100644
--- a/gcc/d/dmd/dmodule.d
+++ b/gcc/d/dmd/dmodule.d
@@ -30,7 +30,7 @@ import dmd.dmacro;
 import dmd.doc;
 import dmd.dscope;
 import dmd.dsymbol;
-import dmd.dsymbolsem : dsymbolSemantic, importAll, load, include;
+import dmd.dsymbolsem : dsymbolSemantic, importAll, load;
 import dmd.errors;
 import dmd.errorsink;
 import dmd.expression;
@@ -43,6 +43,7 @@ import dmd.id;
 import dmd.identifier;
 import dmd.location;
 import dmd.parse;
+import dmd.root.aav;
 import dmd.root.array;
 import dmd.root.file;
 import dmd.root.filename;
@@ -544,6 +545,8 @@ extern (C++) final class Module : Package
             }
             buf.printf("%s\t(%s)", ident.toChars(), m.srcfile.toChars());
             message("import    %s", buf.peekChars());
+            if (loc != Loc.initial)
+                message("(imported from %s)", loc.toChars());
         }
         if((m = m.parse()) is null) return null;
 
@@ -1008,22 +1011,31 @@ extern (C++) final class Module : Package
     extern (D) static void addDeferredSemantic(Dsymbol s)
     {
         //printf("Module::addDeferredSemantic('%s')\n", s.toChars());
-        if (!deferred.contains(s))
+        if (!s.deferred)
+        {
+            s.deferred = true;
             deferred.push(s);
+        }
     }
 
     extern (D) static void addDeferredSemantic2(Dsymbol s)
     {
         //printf("Module::addDeferredSemantic2('%s')\n", s.toChars());
-        if (!deferred2.contains(s))
+        if (!s.deferred2)
+        {
+            s.deferred2 = true;
             deferred2.push(s);
+        }
     }
 
     extern (D) static void addDeferredSemantic3(Dsymbol s)
     {
         //printf("Module::addDeferredSemantic3('%s')\n", s.toChars());
-        if (!deferred.contains(s))
+        if (!s.deferred3)
+        {
+            s.deferred3 = true;
             deferred3.push(s);
+        }
     }
 
     /******************************************
@@ -1057,6 +1069,8 @@ extern (C++) final class Module : Package
                 todoalloc = todo;
             }
             memcpy(todo, deferred.tdata(), len * Dsymbol.sizeof);
+            foreach (Dsymbol s; Module.deferred[])
+                s.deferred = false;
             deferred.setDim(0);
 
             foreach (i; 0..len)
@@ -1082,6 +1096,7 @@ extern (C++) final class Module : Package
         for (size_t i = 0; i < a.length; i++)
         {
             Dsymbol s = (*a)[i];
+            s.deferred2 = false;
             //printf("[%d] %s semantic2a\n", i, s.toPrettyChars());
             s.semantic2(null);
 
@@ -1099,6 +1114,7 @@ extern (C++) final class Module : Package
         for (size_t i = 0; i < a.length; i++)
         {
             Dsymbol s = (*a)[i];
+            s.deferred3 = false;
             //printf("[%d] %s semantic3a\n", i, s.toPrettyChars());
             s.semantic3(null);
 
@@ -1306,83 +1322,8 @@ extern (C++) struct ModuleDeclaration
     }
 }
 
-/****************************************
- * Create array of the local classes in the Module, suitable
- * for inclusion in ModuleInfo
- * Params:
- *      mod = the Module
- *      aclasses = array to fill in
- * Returns: array of local classes
- */
-void getLocalClasses(Module mod, ref ClassDeclarations aclasses)
-{
-    //printf("members.length = %d\n", mod.members.length);
-    int pushAddClassDg(size_t n, Dsymbol sm)
-    {
-        if (!sm)
-            return 0;
-
-        if (auto cd = sm.isClassDeclaration())
-        {
-            // compatibility with previous algorithm
-            if (cd.parent && cd.parent.isTemplateMixin())
-                return 0;
-
-            if (cd.classKind != ClassKind.objc)
-                aclasses.push(cd);
-        }
-        return 0;
-    }
-
-    _foreach(null, mod.members, &pushAddClassDg);
-}
-
-
 alias ForeachDg = int delegate(size_t idx, Dsymbol s);
 
-/***************************************
- * Expands attribute declarations in members in depth first
- * order. Calls dg(size_t symidx, Dsymbol *sym) for each
- * member.
- * If dg returns !=0, stops and returns that value else returns 0.
- * Use this function to avoid the O(N + N^2/2) complexity of
- * calculating dim and calling N times getNth.
- * Returns:
- *  last value returned by dg()
- */
-int _foreach(Scope* sc, Dsymbols* members, scope ForeachDg dg, size_t* pn = null)
-{
-    assert(dg);
-    if (!members)
-        return 0;
-    size_t n = pn ? *pn : 0; // take over index
-    int result = 0;
-    foreach (size_t i; 0 .. members.length)
-    {
-        import dmd.attrib : AttribDeclaration;
-        import dmd.dtemplate : TemplateMixin;
-
-        Dsymbol s = (*members)[i];
-        if (AttribDeclaration a = s.isAttribDeclaration())
-            result = _foreach(sc, a.include(sc), dg, &n);
-        else if (TemplateMixin tm = s.isTemplateMixin())
-            result = _foreach(sc, tm.members, dg, &n);
-        else if (s.isTemplateInstance())
-        {
-        }
-        else if (s.isUnitTestDeclaration())
-        {
-        }
-        else
-            result = dg(n++, s);
-        if (result)
-            break;
-    }
-    if (pn)
-        *pn = n; // update index
-    return result;
-}
-
 /**
  * Process the content of a source file
  *
diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d
index 725a55e94184..c70e7d381b56 100644
--- a/gcc/d/dmd/dscope.d
+++ b/gcc/d/dmd/dscope.d
@@ -64,7 +64,7 @@ private extern (D) struct BitFields
     bool inTemplateConstraint; /// inside template constraint
     Contract contract;
     bool ctfe;              /// inside a ctfe-only expression
-    bool traitsCompiles;    /// inside __traits(compile)
+    bool traitsCompiles;    /// inside __traits(compile) or is-expression
     /// ignore symbol visibility
     /// https://issues.dlang.org/show_bug.cgi?id=15907
     bool ignoresymbolvisibility;
diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d
index d07be2f13193..5aef3585cafe 100644
--- a/gcc/d/dmd/dstruct.d
+++ b/gcc/d/dmd/dstruct.d
@@ -151,127 +151,6 @@ extern (C++) class StructDeclaration : AggregateDeclaration
         return "struct";
     }
 
-    override final void finalizeSize()
-    {
-        //printf("StructDeclaration::finalizeSize() %s, sizeok = %d\n", toChars(), sizeok);
-        assert(sizeok != Sizeok.done);
-
-        if (sizeok == Sizeok.inProcess)
-        {
-            return;
-        }
-        sizeok = Sizeok.inProcess;
-
-        //printf("+StructDeclaration::finalizeSize() %s, fields.length = %d, sizeok = %d\n", toChars(), fields.length, sizeok);
-
-        fields.setDim(0);   // workaround
-
-        // Set the offsets of the fields and determine the size of the struct
-        FieldState fieldState;
-        bool isunion = isUnionDeclaration() !is null;
-        for (size_t i = 0; i < members.length; i++)
-        {
-            Dsymbol s = (*members)[i];
-            s.setFieldOffset(this, &fieldState, isunion);
-            if (type.ty == Terror)
-            {
-                errorSupplemental(s.loc, "error on member `%s`", s.toPrettyChars);
-                errors = true;
-                return;
-            }
-        }
-
-        if (structsize == 0)
-        {
-            hasNoFields = true;
-            alignsize = 1;
-
-            // A fine mess of what size a zero sized struct should be
-            final switch (classKind)
-            {
-                case ClassKind.d:
-                case ClassKind.cpp:
-                    structsize = 1;
-                    break;
-
-                case ClassKind.c:
-                case ClassKind.objc:
-                    if (target.c.bitFieldStyle == TargetC.BitFieldStyle.MS)
-                    {
-                        /* Undocumented MS behavior for:
-                         *   struct S { int :0; };
-                         */
-                        structsize = 4;
-                    }
-                    else
-                        structsize = 0;
-                    break;
-            }
-        }
-
-        // Round struct size up to next alignsize boundary.
-        // This will ensure that arrays of structs will get their internals
-        // aligned properly.
-        if (alignment.isDefault() || alignment.isPack())
-            structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
-        else
-            structsize = (structsize + alignment.get() - 1) & ~(alignment.get() - 1);
-
-        sizeok = Sizeok.done;
-
-        //printf("-StructDeclaration::finalizeSize() %s, fields.length = %d, structsize = %d\n", toChars(), cast(int)fields.length, cast(int)structsize);
-
-        if (errors)
-            return;
-
-        // Calculate fields[i].overlapped
-        if (checkOverlappedFields())
-        {
-            errors = true;
-            return;
-        }
-
-        // Determine if struct is all zeros or not
-        zeroInit = true;
-        auto lastOffset = -1;
-        foreach (vd; fields)
-        {
-            // First skip zero sized fields
-            if (vd.type.size(vd.loc) == 0)
-                continue;
-
-            // only consider first sized member of an (anonymous) union
-            if (vd.overlapped && vd.offset == lastOffset)
-                continue;
-            lastOffset = vd.offset;
-
-            if (vd._init)
-            {
-                if (vd._init.isVoidInitializer())
-                    /* Treat as 0 for the purposes of putting the initializer
-                     * in the BSS segment, or doing a mass set to 0
-                     */
-                    continue;
-
-                // Examine init to see if it is all 0s.
-                auto exp = vd.getConstInitializer();
-                if (!exp || !_isZeroInit(exp))
-                {
-                    zeroInit = false;
-                    break;
-                }
-            }
-            else if (!vd.type.isZeroInit(loc))
-            {
-                zeroInit = false;
-                break;
-            }
-        }
-
-
-        argTypes = target.toArgTypes(type);
-    }
-
     /// Compute cached type properties for `TypeStruct`
     extern(D) final void determineTypeProperties()
     {
@@ -279,13 +158,14 @@ extern (C++) class StructDeclaration : AggregateDeclaration
             return;
         foreach (vd; fields)
         {
+            import dmd.dsymbolsem : hasPointers;
             if (vd.storage_class & STC.ref_ || vd.hasPointers())
             {
                 hasPointerField = true;
                 hasUnsafeBitpatterns = true;
             }
 
-            if (vd._init && vd._init.isVoidInitializer() && vd.type.hasPointers())
+            if (vd._init && vd._init.isVoidInitializer() && vd.hasPointers())
                 hasVoidInitPointers = true;
 
             if (vd.storage_class & STC.system || vd.type.hasUnsafeBitpatterns())
@@ -399,13 +279,12 @@ extern (C++) class StructDeclaration : AggregateDeclaration
      * is not disabled.
      *
      * Params:
-     *      checkDisabled = if the struct has a regular
-                            non-disabled constructor
+     *      ignoreDisabled = true to ignore disabled constructors
      * Returns:
      *      true, if the struct has a regular (optionally,
      *      not disabled) constructor, false otherwise.
      */
-    final bool hasRegularCtor(bool checkDisabled = false)
+    final bool hasRegularCtor(bool ignoreDisabled = false)
     {
         if (!ctor)
             return false;
@@ -415,7 +294,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration
         {
             if (auto td = s.isTemplateDeclaration())
             {
-                if (checkDisabled && td.onemember)
+                if (ignoreDisabled && td.onemember)
                 {
                     if (auto ctorDecl = td.onemember.isCtorDeclaration())
                     {
@@ -428,7 +307,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration
             }
             if (auto ctorDecl = s.isCtorDeclaration())
             {
-                if (!ctorDecl.isCpCtor && (!checkDisabled || !(ctorDecl.storage_class & STC.disable)))
+                if (!ctorDecl.isCpCtor && (!ignoreDisabled || !(ctorDecl.storage_class & STC.disable)))
                 {
                     result = true;
                     return 1;
@@ -440,96 +319,6 @@ extern (C++) class StructDeclaration : AggregateDeclaration
     }
 }
 
-/**********************************
- * Determine if exp is all binary zeros.
- * Params:
- *      exp = expression to check
- * Returns:
- *      true if it's all binary 0
- */
-bool _isZeroInit(Expression exp)
-{
-    switch (exp.op)
-    {
-        case EXP.int64:
-            return exp.toInteger() == 0;
-
-        case EXP.null_:
-            return true;
-
-        case EXP.structLiteral:
-        {
-            auto sle = exp.isStructLiteralExp();
-            if (sle.sd.isNested())
-                return false;
-            const isCstruct = sle.sd.isCsymbol();  // C structs are default initialized to all zeros
-            foreach (i; 0 .. sle.sd.fields.length)
-            {
-                auto field = sle.sd.fields[i];
-                if (field.type.size(field.loc))
-                {
-                    auto e = sle.elements && i < sle.elements.length ? (*sle.elements)[i] : null;
-                    if (e ? !_isZeroInit(e)
-                          : !isCstruct && !field.type.isZeroInit(field.loc))
-                        return false;
-                }
-            }
-            return true;
-        }
-
-        case EXP.arrayLiteral:
-        {
-            auto ale = cast(ArrayLiteralExp)exp;
-
-            const dim = ale.elements ? ale.elements.length : 0;
-
-            if (ale.type.toBasetype().ty == Tarray) // if initializing a dynamic array
-                return dim == 0;
-
-            foreach (i; 0 .. dim)
-            {
-                if (!_isZeroInit(ale[i]))
-                    return false;
-            }
-
-            /* Note that true is returned for all T[0]
-             */
-            return true;
-        }
-
-        case EXP.string_:
-        {
-            auto se = cast(StringExp)exp;
-
-            if (se.type.toBasetype().ty == Tarray) // if initializing a dynamic array
-                return se.len == 0;
-
-            foreach (i; 0 .. se.len)
-            {
-                if (se.getIndex(i) != 0)
-                    return false;
-            }
-            return true;
-        }
-
-        case EXP.vector:
-        {
-            auto ve = cast(VectorExp) exp;
-            return _isZeroInit(ve.e1);
-        }
-
-        case EXP.float64:
-        case EXP.complex80:
-        {
-            import dmd.root.ctfloat : CTFloat;
-            return (exp.toReal()      is CTFloat.zero) &&
-                   (exp.toImaginary() is CTFloat.zero);
-        }
-
-        default:
-            return false;
-    }
-}
 
 /***********************************************************
  * Unions are a variation on structs.
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index 74ca9cbda4d3..e65068c7622b 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -51,7 +51,6 @@ import dmd.statement;
 import dmd.staticassert;
 import dmd.tokens;
 import dmd.visitor;
-import dmd.dsymbolsem;
 
 import dmd.common.outbuffer;
 
@@ -344,6 +343,11 @@ extern (C++) class Dsymbol : ASTNode
     {
         bool errors;            // this symbol failed to pass semantic()
         PASS semanticRun = PASS.initial;
+
+        // Queued for deferred semantics:
+        bool deferred;  // In Module.deferred
+        bool deferred2; // In Module.deferred2
+        bool deferred3; // In Module.deferred3
     }
     import dmd.common.bitfields;
     mixin(generateBitFields!(BitFields, ubyte));
@@ -900,78 +904,6 @@ extern (C++) class Dsymbol : ASTNode
         assert(0);
     }
 
-    /*****************************************
-     * Same as Dsymbol::oneMember(), but look at an array of Dsymbols.
-     */
-    extern (D) static bool oneMembers(Dsymbols* members, out Dsymbol ps, Identifier ident)
-    {
-        //printf("Dsymbol::oneMembers() %d\n", members ? members.length : 0);
-        Dsymbol s = null;
-        if (!members)
-        {
-            ps = null;
-            return true;
-        }
-
-        for (size_t i = 0; i < members.length; i++)
-        {
-            Dsymbol sx = (*members)[i];
-            bool x = sx.oneMember(ps, ident); //MYTODO: this temporarily creates a new dependency to dsymbolsem, will need to extract oneMembers() later
-            //printf("\t[%d] kind %s = %d, s = %p\n", i, sx.kind(), x, *ps);
-            if (!x)
-            {
-                //printf("\tfalse 1\n");
-                assert(ps is null);
-                return false;
-            }
-            if (ps)
-            {
-                assert(ident);
-                if (!ps.ident || !ps.ident.equals(ident))
-                    continue;
-                if (!s)
-                    s = ps;
-                else if (s.isOverloadable() && ps.isOverloadable())
-                {
-                    // keep head of overload set
-                    FuncDeclaration f1 = s.isFuncDeclaration();
-                    FuncDeclaration f2 = ps.isFuncDeclaration();
-                    if (f1 && f2)
-                    {
-                        assert(!f1.isFuncAliasDeclaration());
-                        assert(!f2.isFuncAliasDeclaration());
-                        for (; f1 != f2; f1 = f1.overnext0)
-                        {
-                            if (f1.overnext0 is null)
-                            {
-                                f1.overnext0 = f2;
-                                break;
-                            }
-                        }
-                    }
-                }
-                else // more than one symbol
-                {
-                    ps = null;
-                    //printf("\tfalse 2\n");
-                    return false;
-                }
-            }
-        }
-        ps = s; // s is the one symbol, null if none
-        //printf("\ttrue\n");
-        return true;
-    }
-
-    /*****************************************
-     * Is Dsymbol a variable that contains pointers?
-     */
-    bool hasPointers()
-    {
-        //printf("Dsymbol::hasPointers() %s\n", toChars());
-        return false;
-    }
-
     void addObjcSymbols(ClassDeclarations* classes, ClassDeclarations* categories)
     {
     }
@@ -1235,6 +1167,7 @@ extern (C++) class Dsymbol : ASTNode
             return null;
         }
     }
+    inout(AlignDeclaration)            isAlignDeclaration()            inout { return dsym == DSYM.alignDeclaration ? cast(inout(AlignDeclaration)) cast(void*) this : null; }
     inout(AnonDeclaration)             isAnonDeclaration()             inout { return dsym == DSYM.anonDeclaration ? cast(inout(AnonDeclaration)) cast(void*) this : null; }
     inout(CPPNamespaceDeclaration)     isCPPNamespaceDeclaration()     inout { return dsym == DSYM.cppNamespaceDeclaration ? cast(inout(CPPNamespaceDeclaration)) cast(void*) this : null; }
     inout(VisibilityDeclaration)       isVisibilityDeclaration()       inout { return dsym == DSYM.visibilityDeclaration ? cast(inout(VisibilityDeclaration)) cast(void*) this : null; }
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index 558d15608884..77e7dabcb6cf 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -243,7 +243,6 @@ public:
     virtual bool needThis();                    // need a 'this' pointer?
     virtual Visibility visible();
     virtual Dsymbol *syntaxCopy(Dsymbol *s);    // copy only syntax trees
-    virtual bool hasPointers();
     virtual void addObjcSymbols(ClassDeclarations *, ClassDeclarations *) { }
 
     virtual void addComment(const utf8_t *comment);
@@ -428,7 +427,5 @@ namespace dmd
     Dsymbols *include(Dsymbol *d, Scope *sc);
     void setScope(Dsymbol *d, Scope *sc);
     void importAll(Dsymbol *d, Scope *sc);
-    void addComment(Dsymbol *d, const char *comment);
-    bool oneMember(Dsymbol *d, Dsymbol *&ps, Identifier *ident);
-    bool hasStaticCtorOrDtor(Dsymbol *d);
+    bool hasPointers(Dsymbol *d);
 }
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index acbac7a0e047..43fb0b72e4ba 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -953,6 +953,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
         if (dsym.storage_class & STC.constscoperef)
             dsym.storage_class |= STC.scope_;
 
+        import dmd.typesem : hasPointers;
+
         if (dsym.storage_class & STC.scope_)
         {
             STC stc = dsym.storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.gshared);
@@ -3089,10 +3091,18 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
             StructDeclaration sym = ts.sym;
             if (sd.isCsymbol() && sym.isCsymbol())
             {
-                /* This is two structs imported from different C files.
-                 * Just ignore sd, the second one. The first one will always
-                 * be found when going through the type.
-                 */
+
+                if (!isCCompatible(sd, sym))
+                {
+                    // Already issued an error.
+                    errorSupplemental(sd.loc, "C %ss with the same name from different imports are merged", sd.kind);
+                }
+                else {
+                    /* This is two structs imported from different C files.
+                     * Just ignore sd, the second one. The first one will always
+                     * be found when going through the type.
+                     */
+                }
             }
             else
             {
@@ -3132,6 +3142,234 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
         //printf("-StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", sd, sd.toPrettyChars(), sd.sizeok);
     }
 
+    //
+    // Checks if two structs are compatible
+    // Implements the rules according to C23 6.2.7
+    //
+    static bool isCCompatible(StructDeclaration a, StructDeclaration b)
+    {
+        // Get the name of a type, while avoiding exposing "__tagXXX" anonymous structs
+        static const(char)* typeName(Type t)
+        {
+            if (TypeStruct ts = t.isTypeStruct())
+            {
+                if (ts.sym.ident.toString().startsWith("__tag"))
+                    return ts.sym.isUnionDeclaration() ? "(anonymous union)".ptr: "(anonymous struct)".ptr;
+            }
+            return t.toChars();
+        }
+
+        void incompatError()
+        {
+            .error(a.loc, "%s `%s` already exists with an incompatible definition.",
+                    a.kind, typeName(a.type));
+            errorSupplemental(b.loc, "previously declared here");
+        }
+
+
+        // For recursive calls into unnamed structs (so Type.equals() doesn't work).
+        static bool isCCompatibleUnnamedStruct(Type a, Type b)
+        {
+            TypeStruct ats = a.isTypeStruct();
+            if (!ats) return false;
+            TypeStruct bts = b.isTypeStruct();
+            if (!bts) return false;
+            // Hack, anonymous structs within a struct are given
+            // an anonymous id starting with __tag.
+            if (!ats.sym.ident.toString().startsWith("__tag"))
+                return false;
+            if (!bts.sym.ident.toString().startsWith("__tag"))
+                return false;
+            return isCCompatible(ats.sym, bts.sym);
+        }
+
+        if (a.fields.length != b.fields.length)
+        {
+            incompatError();
+            errorSupplemental(a.loc, "`%s` has %zu field(s) while `%s` has %zu field(s)",
+                    a.toPrettyChars(), a.fields.length, b.toPrettyChars(), b.fields.length);
+            return false;
+        }
+        // both are structs or both are unions
+        if ((a.isUnionDeclaration() is null) != (b.isUnionDeclaration() is null))
+        {
+            incompatError();
+            errorSupplemental(a.loc, "`%s` is a %s while `%s` is a %s",
+                    a.toPrettyChars(), a.kind, b.toPrettyChars(), b.kind);
+            return false;
+        }
+        if (a.alignment != b.alignment)
+        {
+            incompatError();
+            errorSupplemental(a.loc, "`%s` has different alignment or packing", a.toPrettyChars());
+            if (a.alignment.isDefault() && ! b.alignment.isDefault())
+            {
+                errorSupplemental(a.loc, "`%s` alignment: default", a.toPrettyChars());
+                errorSupplemental(b.loc, "`%s` alignment: %u",
+                        b.toPrettyChars(), cast(uint)b.alignment.get());
+            }
+            else if (!a.alignment.isDefault() && b.alignment.isDefault())
+            {
+                errorSupplemental(a.loc, "`%s` alignment: %u",
+                        a.toPrettyChars(), cast(uint)a.alignment.get());
+                errorSupplemental(b.loc, "`%s` alignment: default",
+                        b.toPrettyChars());
+            }
+            else if (a.alignment.get() != b.alignment.get())
+            {
+                errorSupplemental(a.loc, "`%s` alignment: %u",
+                        a.toPrettyChars(), cast(uint)a.alignment.get());
+                errorSupplemental(b.loc, "`%s` alignment: %u",
+                        b.toPrettyChars(), cast(uint)b.alignment.get());
+            }
+            if (a.alignment.isPack() != b.alignment.isPack())
+            {
+                errorSupplemental(a.loc, "`%s` packed: %s",
+                        a.toPrettyChars(), a.alignment.isPack()?"true".ptr:"false".ptr);
+                errorSupplemental(b.loc, "`%s` packed: %s",
+                        b.toPrettyChars(), b.alignment.isPack()?"true".ptr:"false".ptr);
+            }
+            return false;
+        }
+        foreach (size_t i, VarDeclaration a_field; a.fields[])
+        {
+            VarDeclaration b_field = b.fields[i];
+            //
+            // — there shall be a one-to-one correspondence between
+            //   their members such that each pair of corresponding
+            //   members are declared with compatible types;
+            //
+            if (!a_field.type.equals(b_field.type) && !isCCompatibleUnnamedStruct(a_field.type, b_field.type))
+            {
+                // Already errored, just bail
+                incompatError();
+                if (a_field.type.isTypeError()) return false;
+                if (b_field.type.isTypeError()) return false;
+
+                errorSupplemental(a_field.loc, "Field %zu differs in type", i);
+                errorSupplemental(a_field.loc, "typeof(%s): %s",
+                        a_field.toChars(), typeName(a_field.type));
+                errorSupplemental(b_field.loc, "typeof(%s): %s",
+                        b_field.toChars(), typeName(b_field.type));
+                return false;
+            }
+            //
+            // — if one member of the pair is declared with an
+            //   alignment specifier, the second is declared with an
+            //   equivalent alignment specifier;
+            //
+            if (a_field.alignment != b_field.alignment)
+            {
+                incompatError();
+                errorSupplemental(a_field.loc, "Field %zu differs in alignment or packing", i);
+                if (a_field.alignment.isDefault() && ! b_field.alignment.isDefault())
+                {
+                    errorSupplemental(a_field.loc, "`%s.%s` alignment: default",
+                            a.toPrettyChars(),a_field.toChars());
+                    errorSupplemental(b_field.loc, "`%s.%s` alignment: %u",
+                            b.toPrettyChars(), b_field.toChars(), cast(uint)b_field.alignment.get());
+                }
+                else if (!a_field.alignment.isDefault() && b_field.alignment.isDefault())
+                {
+                    errorSupplemental(a_field.loc, "`%s.%s` alignment: %u",
+                            a.toPrettyChars(), a_field.toChars(), cast(uint)a_field.alignment.get());
+                    errorSupplemental(b_field.loc, "`%s.%s` alignment: default",
+                            b.toPrettyChars(), b_field.toChars());
+                }
+                else if (a_field.alignment.get() != b_field.alignment.get())
+                {
+                    errorSupplemental(a_field.loc, "`%s.%s` alignment: %u",
+                            a.toPrettyChars(), a_field.toChars(),
+                            cast(uint)a_field.alignment.get());
+                    errorSupplemental(b_field.loc, "`%s.%s` alignment: %u",
+                            b.toPrettyChars(), b_field.toChars(),
+                            cast(uint)b_field.alignment.get());
+                }
+                if (a_field.alignment.isPack() != b_field.alignment.isPack())
+                {
+                    errorSupplemental(a_field.loc, "`%s.%s` packed: %s",
+                            a.toPrettyChars(), a_field.toChars(),
+                            a_field.alignment.isPack()?"true".ptr:"false".ptr);
+                    errorSupplemental(b_field.loc, "`%s.%s` packed: %s",
+                            b.toPrettyChars(), b_field.toChars(),
+                            b_field.alignment.isPack()?"true".ptr:"false".ptr);
+                }
+                return false;
+            }
+            //
+            // - and, if one member of the pair is declared with a
+            //   name, the second is declared with the same name.
+            //
+            if (a_field.ident.isAnonymous())
+            {
+                if (!b_field.ident.isAnonymous())
+                {
+                    incompatError();
+                    errorSupplemental(a_field.loc, "Field %zu differs in name", i);
+                    errorSupplemental(a_field.loc, "(anonymous)", a_field.ident.toChars());
+                    errorSupplemental(b_field.loc, "%s", b_field.ident.toChars());
+                    return false;
+                }
+            }
+            else if (b_field.ident.isAnonymous())
+            {
+                incompatError();
+                errorSupplemental(a_field.loc, "Field %zu differs in name", i);
+                errorSupplemental(a_field.loc, "%s", a_field.ident.toChars());
+                errorSupplemental(b_field.loc, "(anonymous)");
+                return false;
+            }
+            else if (a_field.ident != b_field.ident)
+            {
+                incompatError();
+                errorSupplemental(a_field.loc, "Field %zu differs in name", i);
+                errorSupplemental(a_field.loc, "%s", a_field.ident.toChars());
+                errorSupplemental(b_field.loc, "%s", b_field.ident.toChars());
+                return false;
+            }
+
+            //
+            // For two structures or unions, corresponding bit-fields shall have the same widths.
+            //
+            BitFieldDeclaration bfa = a_field.isBitFieldDeclaration();
+            BitFieldDeclaration bfb = b_field.isBitFieldDeclaration();
+            if ((bfa is null) != (bfb is null))
+            {
+                incompatError();
+                errorSupplemental(a_field.loc, "Field %zu differs in being a bitfield", i);
+                if (bfa is null)
+                {
+                    errorSupplemental(a_field.loc, "`%s.%s` is not a bitfield",
+                            a.toPrettyChars(), a_field.toChars());
+                    errorSupplemental(b_field.loc, "`%s.%s` is a bitfield",
+                            b.toPrettyChars(), b_field.toChars());
+                }
+                else if (bfb is null)
+                {
+                    errorSupplemental(a_field.loc, "`%s.%s` *is a bitfield",
+                            a.toPrettyChars(), a_field.toChars());
+                    errorSupplemental(b_field.loc, "`%s.%s` is not a bitfield",
+                            b.toPrettyChars(), b_field.toChars());
+                }
+                return false;
+            }
+            if (bfa !is null && bfb !is null)
+            {
+                if (bfa.fieldWidth != bfb.fieldWidth)
+                {
+                    incompatError();
+                    errorSupplemental(a_field.loc, "Field %zu differs in bitfield width", i);
+                    errorSupplemental(a_field.loc, "`%s.%s`: %u",
+                            a.toPrettyChars(), a_field.toChars(), bfa.fieldWidth);
+                    errorSupplemental(b_field.loc, "`%s.%s`: %u",
+                            b.toPrettyChars(), b_field.toChars(), bfb.fieldWidth);
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
     void interfaceSemantic(ClassDeclaration cd)
     {
         cd.vtblInterfaces = new BaseClasses();
@@ -4520,7 +4758,7 @@ private bool isDRuntimeHook(Identifier id)
         id == Id._d_arrayassign_l || id == Id._d_arrayassign_r ||
         id == Id._d_arraysetassign || id == Id._d_arraysetctor ||
         id == Id._d_arrayctor ||
-        id == Id._d_arraysetlengthTImpl || id == Id._d_arraysetlengthT ||
+        id == Id._d_arraysetlengthT ||
         id == Id._d_arraysetlengthTTrace ||
         id == Id._d_arrayappendT || id == Id._d_arrayappendTTrace ||
         id == Id._d_arrayappendcTX;
@@ -4903,7 +5141,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList
     if (tempinst.members.length)
     {
         Dsymbol s;
-        if (Dsymbol.oneMembers(tempinst.members, s, tempdecl.ident) && s)
+        if (oneMembers(tempinst.members, s, tempdecl.ident) && s)
         {
             //printf("tempdecl.ident = %s, s = `%s %s`\n", tempdecl.ident.toChars(), s.kind(), s.toPrettyChars());
             //printf("setting aliasdecl\n");
@@ -4948,7 +5186,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList
     if (tempinst.members.length)
     {
         Dsymbol s;
-        if (Dsymbol.oneMembers(tempinst.members, s, tempdecl.ident) && s)
+        if (oneMembers(tempinst.members, s, tempdecl.ident) && s)
         {
             if (!tempinst.aliasdecl || tempinst.aliasdecl != s)
             {
@@ -7531,14 +7769,14 @@ private extern(C++) class NewScopeVisitor : Visitor
 }
 
 
-extern(C++) Dsymbols* include(Dsymbol d, Scope* sc)
+Dsymbols* include(Dsymbol d, Scope* sc)
 {
-    scope icv = new IncludeVisitor(sc);
+    scope icv = new ConditionIncludeVisitor(sc);
     d.accept(icv);
     return icv.symbols;
 }
 
-extern(C++) class IncludeVisitor : Visitor
+extern(C++) class ConditionIncludeVisitor : Visitor
 {
     alias visit = typeof(super).visit;
     Scope* sc;
@@ -7570,7 +7808,7 @@ extern(C++) class IncludeVisitor : Visitor
             return;
         }
         assert(cdc.condition);
-        symbols = cdc.condition.include(cdc._scope ? cdc._scope : sc) ? cdc.decl : cdc.elsedecl;
+        symbols = dmd.expressionsem.include(cdc.condition, cdc._scope ? cdc._scope : sc) ? cdc.decl : cdc.elsedecl;
     }
 
     override void visit(StaticIfDeclaration sif)
@@ -7891,7 +8129,7 @@ Lfail:
     return false;
 }
 
-extern (C++) void addComment(Dsymbol d, const(char)* comment)
+void addComment(Dsymbol d, const(char)* comment)
 {
     scope v = new AddCommentVisitor(comment);
     d.accept(v);
@@ -8004,7 +8242,7 @@ private extern(C++) class OneMemberVisitor : Visitor
     override void visit(AttribDeclaration atb)
     {
         Dsymbols* d = atb.include(null);
-        result = Dsymbol.oneMembers(d, *ps, ident);
+        result = oneMembers(d, *ps, ident);
     }
 
     override void visit(StaticForeachDeclaration sfd)
@@ -8027,7 +8265,7 @@ private extern(C++) class OneMemberVisitor : Visitor
 
     override void visit(StorageClassDeclaration scd)
     {
-        bool t = Dsymbol.oneMembers(scd.decl, *ps, ident);
+        bool t = oneMembers(scd.decl, *ps, ident);
         if (t && *ps)
         {
             /* This is to deal with the following case:
@@ -8056,12 +8294,12 @@ private extern(C++) class OneMemberVisitor : Visitor
         //printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition.inc);
         if (cd.condition.inc != Include.notComputed)
         {
-            Dsymbols* d = cd.condition.include(null) ? cd.decl : cd.elsedecl;
-            result = Dsymbol.oneMembers(d, *ps, ident);
+            Dsymbols* d = dmd.expressionsem.include(cd.condition, null) ? cd.decl : cd.elsedecl;
+            result = oneMembers(d, *ps, ident);
         }
         else
         {
-            bool res = (Dsymbol.oneMembers(cd.decl, *ps, ident) && *ps is null && Dsymbol.oneMembers(cd.elsedecl, *ps, ident) && *ps is null);
+            bool res = (oneMembers(cd.decl, *ps, ident) && *ps is null && oneMembers(cd.elsedecl, *ps, ident) && *ps is null);
             *ps = null;
             result = res;
         }
@@ -8070,7 +8308,7 @@ private extern(C++) class OneMemberVisitor : Visitor
     override void visit(ScopeDsymbol sd)
     {
         if (sd.isAnonymous())
-            result = Dsymbol.oneMembers(sd.members, *ps, ident);
+            result = oneMembers(sd.members, *ps, ident);
         else {
             // visit(Dsymbol dsym)
             *ps = sd;
@@ -8108,7 +8346,7 @@ private extern(C++) class OneMemberVisitor : Visitor
 * Return true if any of the members are static ctors or static dtors, or if
 * any members have members that are.
 */
-extern(C++) bool hasStaticCtorOrDtor(Dsymbol d)
+bool hasStaticCtorOrDtor(Dsymbol d)
 {
     scope v = new HasStaticCtorOrDtor();
     d.accept(v);
@@ -8162,7 +8400,7 @@ private extern(C++) class HasStaticCtorOrDtor : Visitor
     }
 }
 
-extern(C++) bool isFuncHidden(ClassDeclaration cd, FuncDeclaration fd)
+bool isFuncHidden(ClassDeclaration cd, FuncDeclaration fd)
 {
     import dmd.funcsem : overloadApply;
     //printf("ClassDeclaration.isFuncHidden(class = %s, fd = %s)\n", toChars(), fd.toPrettyChars());
@@ -8210,3 +8448,618 @@ Dsymbol vtblSymbol(ClassDeclaration cd)
     }
     return cd.vtblsym;
 }
+
+bool isAbstract(ClassDeclaration cd)
+{
+    enum log = false;
+    if (cd.isabstract != ThreeState.none)
+        return cd.isabstract == ThreeState.yes;
+
+    if (log) printf("isAbstract(%s)\n", cd.toChars());
+
+    bool no()  { if (log) printf("no\n");  cd.isabstract = ThreeState.no;  return false; }
+    bool yes() { if (log) printf("yes\n"); cd.isabstract = ThreeState.yes; return true;  }
+
+    if (cd.storage_class & STC.abstract_ || cd._scope && cd._scope.stc & STC.abstract_)
+        return yes();
+
+    if (cd.errors)
+        return no();
+
+    /* https://issues.dlang.org/show_bug.cgi?id=11169
+        * Resolve forward references to all class member functions,
+        * and determine whether this class is abstract.
+        */
+    static int func(Dsymbol s, void*)
+    {
+        auto fd = s.isFuncDeclaration();
+        if (!fd)
+            return 0;
+        if (fd.storage_class & STC.static_)
+            return 0;
+
+        if (fd.isAbstract())
+            return 1;
+        return 0;
+    }
+
+    // opaque class is not abstract if it is not declared abstract
+    if (!(cd.members))
+        return no();
+
+    for (size_t i = 0; i < cd.members.length; i++)
+    {
+        auto s = (*(cd.members))[i];
+        if (s.apply(&func, null))
+        {
+            return yes();
+        }
+    }
+
+    /* If the base class is not abstract, then this class cannot
+        * be abstract.
+        */
+    if (!cd.isInterfaceDeclaration() && (!cd.baseClass || !cd.baseClass.isAbstract()))
+        return no();
+
+    /* If any abstract functions are inherited, but not overridden,
+        * then the class is abstract. Do this by checking the vtbl[].
+        * Need to do semantic() on class to fill the vtbl[].
+        */
+    cd.dsymbolSemantic(null);
+
+    /* The next line should work, but does not because when ClassDeclaration.dsymbolSemantic()
+        * is called recursively it can set PASS.semanticdone without finishing it.
+        */
+    //if (semanticRun < PASS.semanticdone)
+    {
+        /* Could not complete semantic(). Try running semantic() on
+            * each of the virtual functions,
+            * which will fill in the vtbl[] overrides.
+            */
+        static int virtualSemantic(Dsymbol s, void*)
+        {
+            auto fd = s.isFuncDeclaration();
+            if (fd && !(fd.storage_class & STC.static_) && !fd.isUnitTestDeclaration())
+                fd.dsymbolSemantic(null);
+            return 0;
+        }
+
+        for (size_t i = 0; i < cd.members.length; i++)
+        {
+            auto s = (*(cd.members))[i];
+            s.apply(&virtualSemantic,null);
+        }
+    }
+
+    /* Finally, check the vtbl[]
+        */
+    foreach (i; 1 .. cd.vtbl.length)
+    {
+        auto fd = cd.vtbl[i].isFuncDeclaration();
+        //if (fd) printf("\tvtbl[%d] = [%s] %s\n", i, fd.loc.toChars(), fd.toPrettyChars());
+        if (!fd || fd.isAbstract())
+        {
+            return yes();
+        }
+    }
+
+    return no();
+}
+
+void finalizeSize(AggregateDeclaration ad)
+{
+    scope v = new FinalizeSizeVisitor();
+    ad.accept(v);
+}
+
+/**********************************
+ * Determine if exp is all binary zeros.
+ * Params:
+ *      exp = expression to check
+ * Returns:
+ *      true if it's all binary 0
+ */
+bool _isZeroInit(Expression exp)
+{
+    switch (exp.op)
+    {
+        case EXP.int64:
+            return exp.toInteger() == 0;
+
+        case EXP.null_:
+            return true;
+
+        case EXP.structLiteral:
+        {
+            auto sle = exp.isStructLiteralExp();
+            if (sle.sd.isNested())
+                return false;
+            const isCstruct = sle.sd.isCsymbol();  // C structs are default initialized to all zeros
+            foreach (i; 0 .. sle.sd.fields.length)
+            {
+                auto field = sle.sd.fields[i];
+                if (field.type.size(field.loc))
+                {
+                    auto e = sle.elements && i < sle.elements.length ? (*sle.elements)[i] : null;
+                    if (e ? !_isZeroInit(e)
+                          : !isCstruct && !field.type.isZeroInit(field.loc))
+                        return false;
+                }
+            }
+            return true;
+        }
+
+        case EXP.arrayLiteral:
+        {
+            auto ale = cast(ArrayLiteralExp)exp;
+
+            const dim = ale.elements ? ale.elements.length : 0;
+
+            if (ale.type.toBasetype().ty == Tarray) // if initializing a dynamic array
+                return dim == 0;
+
+            foreach (i; 0 .. dim)
+            {
+                if (!_isZeroInit(ale[i]))
+                    return false;
+            }
+
+            /* Note that true is returned for all T[0]
+             */
+            return true;
+        }
+
+        case EXP.string_:
+        {
+            auto se = cast(StringExp)exp;
+
+            if (se.type.toBasetype().ty == Tarray) // if initializing a dynamic array
+                return se.len == 0;
+
+            foreach (i; 0 .. se.len)
+            {
+                if (se.getIndex(i) != 0)
+                    return false;
+            }
+            return true;
+        }
+
+        case EXP.vector:
+        {
+            auto ve = cast(VectorExp) exp;
+            return _isZeroInit(ve.e1);
+        }
+
+        case EXP.float64:
+        case EXP.complex80:
+        {
+            import dmd.root.ctfloat : CTFloat;
+            return (exp.toReal()      is CTFloat.zero) &&
+                   (exp.toImaginary() is CTFloat.zero);
+        }
+
+        default:
+            return false;
+    }
+}
+
+private extern(C++) class FinalizeSizeVisitor : Visitor
+{
+    alias visit = Visitor.visit;
+
+    override void visit(ClassDeclaration outerCd)
+    {
+        assert(outerCd.sizeok != Sizeok.done);
+
+        // Set the offsets of the fields and determine the size of the class
+        if (outerCd.baseClass)
+        {
+            assert(outerCd.baseClass.sizeok == Sizeok.done);
+
+            outerCd.alignsize = outerCd.baseClass.alignsize;
+            if (outerCd.classKind == ClassKind.cpp)
+                outerCd.structsize = target.cpp.derivedClassOffset(outerCd.baseClass);
+            else
+                outerCd.structsize = outerCd.baseClass.structsize;
+        }
+        else if (outerCd.classKind == ClassKind.objc)
+            outerCd.structsize = 0; // no hidden member for an Objective-C class
+        else if (outerCd.isInterfaceDeclaration())
+        {
+            if (outerCd.interfaces.length == 0)
+            {
+                outerCd.alignsize = target.ptrsize;
+                outerCd.structsize = target.ptrsize;      // allow room for __vptr
+            }
+        }
+        else
+        {
+            outerCd.alignsize = target.ptrsize;
+            outerCd.structsize = target.ptrsize;      // allow room for __vptr
+            if (outerCd.hasMonitor())
+                outerCd.structsize += target.ptrsize; // allow room for __monitor
+        }
+
+        //printf("finalizeSize() %s, sizeok = %d\n", toChars(), sizeok);
+        size_t bi = 0;                  // index into vtblInterfaces[]
+
+        /****
+            * Runs through the inheritance graph to set the BaseClass.offset fields.
+            * Recursive in order to account for the size of the interface classes, if they are
+            * more than just interfaces.
+            * Params:
+            *      cd = interface to look at
+            *      baseOffset = offset of where cd will be placed
+            * Returns:
+            *      subset of instantiated size used by cd for interfaces
+            */
+        uint membersPlace(ClassDeclaration cd, uint baseOffset)
+        {
+            //printf("    membersPlace(%s, %d)\n", cd.toChars(), baseOffset);
+            uint offset = baseOffset;
+
+            foreach (BaseClass* b; cd.interfaces)
+            {
+                if (b.sym.sizeok != Sizeok.done)
+                    b.sym.finalizeSize();
+                assert(b.sym.sizeok == Sizeok.done);
+
+                if (!b.sym.alignsize)
+                    b.sym.alignsize = target.ptrsize;
+                offset = alignmember(structalign_t(cast(ushort)b.sym.alignsize), b.sym.alignsize, offset);
+                assert(bi < outerCd.vtblInterfaces.length);
+
+                BaseClass* bv = (*(outerCd.vtblInterfaces))[bi];
+                if (b.sym.interfaces.length == 0)
+                {
+                    //printf("\tvtblInterfaces[%d] b=%p b.sym = %s, offset = %d\n", bi, bv, bv.sym.toChars(), offset);
+                    bv.offset = offset;
+                    ++bi;
+                    // All the base interfaces down the left side share the same offset
+                    for (BaseClass* b2 = bv; b2.baseInterfaces.length; )
+                    {
+                        b2 = &b2.baseInterfaces[0];
+                        b2.offset = offset;
+                        //printf("\tvtblInterfaces[%d] b=%p   sym = %s, offset = %d\n", bi, b2, b2.sym.toChars(), b2.offset);
+                    }
+                }
+                membersPlace(b.sym, offset);
+                //printf(" %s size = %d\n", b.sym.toChars(), b.sym.structsize);
+                offset += b.sym.structsize;
+                if (outerCd.alignsize < b.sym.alignsize)
+                    outerCd.alignsize = b.sym.alignsize;
+            }
+            return offset - baseOffset;
+        }
+
+        outerCd.structsize += membersPlace(outerCd, outerCd.structsize);
+
+        if (outerCd.isInterfaceDeclaration())
+        {
+            outerCd.sizeok = Sizeok.done;
+            return;
+        }
+
+        // FIXME: Currently setFieldOffset functions need to increase fields
+        // to calculate each variable offsets. It can be improved later.
+        outerCd.fields.setDim(0);
+
+        FieldState fieldState;
+        fieldState.offset = outerCd.structsize;
+        foreach (s; *(outerCd.members))
+        {
+            s.setFieldOffset(outerCd, &fieldState, false);
+        }
+
+        outerCd.sizeok = Sizeok.done;
+
+        // Calculate fields[i].overlapped
+        outerCd.checkOverlappedFields();
+    }
+
+    override void visit(StructDeclaration sd)
+    {
+        //printf("StructDeclaration::finalizeSize() %s, sizeok = %d\n", toChars(), sizeok);
+        assert(sd.sizeok != Sizeok.done);
+
+        if (sd.sizeok == Sizeok.inProcess)
+        {
+            return;
+        }
+        sd.sizeok = Sizeok.inProcess;
+
+        //printf("+StructDeclaration::finalizeSize() %s, fields.length = %d, sizeok = %d\n", toChars(), fields.length, sizeok);
+
+        sd.fields.setDim(0);   // workaround
+
+        // Set the offsets of the fields and determine the size of the struct
+        FieldState fieldState;
+        bool isunion = sd.isUnionDeclaration() !is null;
+        for (size_t i = 0; i < sd.members.length; i++)
+        {
+            Dsymbol s = (*sd.members)[i];
+            s.setFieldOffset(sd, &fieldState, isunion);
+            if (sd.type.ty == Terror)
+            {
+                errorSupplemental(s.loc, "error on member `%s`", s.toPrettyChars);
+                sd.errors = true;
+                return;
+            }
+        }
+
+        if (sd.structsize == 0)
+        {
+            sd.hasNoFields = true;
+            sd.alignsize = 1;
+
+            // A fine mess of what size a zero sized struct should be
+            final switch (sd.classKind)
+            {
+                case ClassKind.d:
+                case ClassKind.cpp:
+                    sd.structsize = 1;
+                    break;
+
+                case ClassKind.c:
+                case ClassKind.objc:
+                    if (target.c.bitFieldStyle == TargetC.BitFieldStyle.MS)
+                    {
+                        /* Undocumented MS behavior for:
+                         *   struct S { int :0; };
+                         */
+                        sd.structsize = 4;
+                    }
+                    else
+                        sd.structsize = 0;
+                    break;
+            }
+        }
+
+        // Round struct size up to next alignsize boundary.
+        // This will ensure that arrays of structs will get their internals
+        // aligned properly.
+        if (sd.alignment.isDefault() || sd.alignment.isPack())
+            sd.structsize = (sd.structsize + sd.alignsize - 1) & ~(sd.alignsize - 1);
+        else
+            sd.structsize = (sd.structsize + sd.alignment.get() - 1) & ~(sd.alignment.get() - 1);
+
+        sd.sizeok = Sizeok.done;
+
+        //printf("-StructDeclaration::finalizeSize() %s, fields.length = %d, structsize = %d\n", toChars(), cast(int)fields.length, cast(int)structsize);
+
+        if (sd.errors)
+            return;
+
+        // Calculate fields[i].overlapped
+        if (sd.checkOverlappedFields())
+        {
+            sd.errors = true;
+            return;
+        }
+
+        // Determine if struct is all zeros or not
+        sd.zeroInit = true;
+        auto lastOffset = -1;
+        foreach (vd; sd.fields)
+        {
+            // First skip zero sized fields
+            if (vd.type.size(vd.loc) == 0)
+                continue;
+
+            // only consider first sized member of an (anonymous) union
+            if (vd.overlapped && vd.offset == lastOffset)
+                continue;
+            lastOffset = vd.offset;
+
+            if (vd._init)
+            {
+                if (vd._init.isVoidInitializer())
+                    /* Treat as 0 for the purposes of putting the initializer
+                     * in the BSS segment, or doing a mass set to 0
+                     */
+                    continue;
+
+                // Examine init to see if it is all 0s.
+                auto exp = vd.getConstInitializer();
+                if (!exp || !_isZeroInit(exp))
+                {
+                    sd.zeroInit = false;
+                    break;
+                }
+            }
+            else if (!vd.type.isZeroInit(sd.loc))
+            {
+                sd.zeroInit = false;
+                break;
+            }
+        }
+
+
+        sd.argTypes = target.toArgTypes(sd.type);
+    }
+}
+
+/*****************************************
+* Is Dsymbol a variable that contains pointers?
+*/
+bool hasPointers(Dsymbol d)
+{
+    scope v = new HasPointersVisitor();
+    d.accept(v);
+    return v.result;
+}
+
+private extern(C++) class HasPointersVisitor : Visitor
+{
+    import dmd.mtype : Type;
+
+    alias visit = Visitor.visit;
+    bool result;
+
+    override void visit(AttribDeclaration ad)
+    {
+        result = ad.include(null).foreachDsymbol( (s) { return s.hasPointers(); } ) != 0;
+    }
+
+    override void visit(VarDeclaration vd)
+    {
+        import dmd.typesem : hasPointers;
+        result = (!vd.isDataseg() && vd.type.hasPointers());
+    }
+
+    override void visit(Dsymbol d)
+    {
+        //printf("Dsymbol::hasPointers() %s\n", toChars());
+        result = false;
+    }
+
+    override void visit(TemplateMixin tm)
+    {
+        //printf("TemplateMixin.hasPointers() %s\n", toChars());
+        result = tm.members.foreachDsymbol( (s) { return s.hasPointers(); } ) != 0;
+    }
+
+    override void visit(Nspace ns)
+    {
+        //printf("Nspace::hasPointers() %s\n", toChars());
+        result = ns.members.foreachDsymbol( (s) { return s.hasPointers(); } ) != 0;
+    }
+}
+
+/***************************************
+ * Expands attribute declarations in members in depth first
+ * order. Calls dg(size_t symidx, Dsymbol *sym) for each
+ * member.
+ * If dg returns !=0, stops and returns that value else returns 0.
+ * Use this function to avoid the O(N + N^2/2) complexity of
+ * calculating dim and calling N times getNth.
+ * Returns:
+ *  last value returned by dg()
+ */
+int _foreach(Scope* sc, Dsymbols* members, scope ForeachDg dg, size_t* pn = null)
+{
+    assert(dg);
+    if (!members)
+        return 0;
+    size_t n = pn ? *pn : 0; // take over index
+    int result = 0;
+    foreach (size_t i; 0 .. members.length)
+    {
+        import dmd.attrib : AttribDeclaration;
+        import dmd.dtemplate : TemplateMixin;
+
+        Dsymbol s = (*members)[i];
+        if (AttribDeclaration a = s.isAttribDeclaration())
+            result = _foreach(sc, a.include(sc), dg, &n);
+        else if (TemplateMixin tm = s.isTemplateMixin())
+            result = _foreach(sc, tm.members, dg, &n);
+        else if (s.isTemplateInstance())
+        {
+        }
+        else if (s.isUnitTestDeclaration())
+        {
+        }
+        else
+            result = dg(n++, s);
+        if (result)
+            break;
+    }
+    if (pn)
+        *pn = n; // update index
+    return result;
+}
+
+/****************************************
+ * Create array of the local classes in the Module, suitable
+ * for inclusion in ModuleInfo
+ * Params:
+ *      mod = the Module
+ *      aclasses = array to fill in
+ * Returns: array of local classes
+ */
+void getLocalClasses(Module mod, ref ClassDeclarations aclasses)
+{
+    //printf("members.length = %d\n", mod.members.length);
+    int pushAddClassDg(size_t n, Dsymbol sm)
+    {
+        if (!sm)
+            return 0;
+
+        if (auto cd = sm.isClassDeclaration())
+        {
+            // compatibility with previous algorithm
+            if (cd.parent && cd.parent.isTemplateMixin())
+                return 0;
+
+            if (cd.classKind != ClassKind.objc)
+                aclasses.push(cd);
+        }
+        return 0;
+    }
+
+    _foreach(null, mod.members, &pushAddClassDg);
+}
+
+/*****************************************
+* Same as Dsymbol::oneMember(), but look at an array of Dsymbols.
+*/
+extern (D) bool oneMembers(Dsymbols* members, out Dsymbol ps, Identifier ident)
+{
+    //printf("Dsymbol::oneMembers() %d\n", members ? members.length : 0);
+    Dsymbol s = null;
+    if (!members)
+    {
+        ps = null;
+        return true;
+    }
+
+    for (size_t i = 0; i < members.length; i++)
+    {
+        Dsymbol sx = (*members)[i];
+        bool x = sx.oneMember(ps, ident); //MYTODO: this temporarily creates a new dependency to dsymbolsem, will need to extract oneMembers() later
+        //printf("\t[%d] kind %s = %d, s = %p\n", i, sx.kind(), x, *ps);
+        if (!x)
+        {
+            //printf("\tfalse 1\n");
+            assert(ps is null);
+            return false;
+        }
+        if (ps)
+        {
+            assert(ident);
+            if (!ps.ident || !ps.ident.equals(ident))
+                continue;
+            if (!s)
+                s = ps;
+            else if (s.isOverloadable() && ps.isOverloadable())
+            {
+                // keep head of overload set
+                FuncDeclaration f1 = s.isFuncDeclaration();
+                FuncDeclaration f2 = ps.isFuncDeclaration();
+                if (f1 && f2)
+                {
+                    assert(!f1.isFuncAliasDeclaration());
+                    assert(!f2.isFuncAliasDeclaration());
+                    for (; f1 != f2; f1 = f1.overnext0)
+                    {
+                        if (f1.overnext0 is null)
+                        {
+                            f1.overnext0 = f2;
+                            break;
+                        }
+                    }
+                }
+            }
+            else // more than one symbol
+            {
+                ps = null;
+                //printf("\tfalse 2\n");
+                return false;
+            }
+        }
+    }
+    ps = s; // s is the one symbol, null if none
+    //printf("\ttrue\n");
+    return true;
+}
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index 215889574570..16e192da20ff 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -53,7 +53,7 @@ import dmd.dinterpret;
 import dmd.dmodule;
 import dmd.dscope;
 import dmd.dsymbol;
-import dmd.dsymbolsem : dsymbolSemantic, checkDeprecated, aliasSemantic, search, search_correct, setScope, importAll, include, hasStaticCtorOrDtor;
+import dmd.dsymbolsem : dsymbolSemantic, checkDeprecated, aliasSemantic, search, search_correct, setScope, importAll, include, hasStaticCtorOrDtor, oneMembers;
 import dmd.errors;
 import dmd.errorsink;
 import dmd.expression;
@@ -593,6 +593,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
     bool isTrivialAliasSeq; /// matches pattern `template AliasSeq(T...) { alias AliasSeq = T; }`
     bool isTrivialAlias;    /// matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
     bool deprecated_;       /// this template declaration is deprecated
+    bool isCmacro;          /// Whether this template is a translation of a C macro
     Visibility visibility;
 
     // threaded list of previous instantiation attempts on stack
@@ -639,7 +640,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
             return;
 
         Dsymbol s;
-        if (!Dsymbol.oneMembers(members, s, ident) || !s)
+        if (!oneMembers(members, s, ident) || !s)
             return;
 
         onemember = s;
@@ -3661,11 +3662,11 @@ extern (C++) class TemplateInstance : ScopeDsymbol
     ScopeDsymbol argsym;        // argument symbol table
     size_t hash;                // cached result of toHash()
 
-    /// For function template, these are the function names and arguments
+    /// For function template, these are the function fnames(name and loc of it) and arguments
     /// Relevant because different resolutions of `auto ref` parameters
     /// create different template instances even with the same template arguments
     Expressions* fargs;
-    Identifiers* fnames;
+    ArgumentLabels* fnames;
 
     TemplateInstances* deferred;
 
@@ -5273,7 +5274,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
                 if (members.length)
                 {
                     Dsymbol sa;
-                    if (Dsymbol.oneMembers(members, sa, tempdecl.ident) && sa)
+                    if (oneMembers(members, sa, tempdecl.ident) && sa)
                         aliasdecl = sa;
                 }
                 done = true;
@@ -5490,12 +5491,6 @@ extern (C++) final class TemplateMixin : TemplateInstance
         return "mixin";
     }
 
-    override bool hasPointers()
-    {
-        //printf("TemplateMixin.hasPointers() %s\n", toChars());
-        return members.foreachDsymbol( (s) { return s.hasPointers(); } ) != 0;
-    }
-
     extern (D) bool findTempDecl(Scope* sc)
     {
         // Follow qualifications to find the TemplateDeclaration
diff --git a/gcc/d/dmd/enumsem.d b/gcc/d/dmd/enumsem.d
index 4f0d4e5f53f2..6d325e44c964 100644
--- a/gcc/d/dmd/enumsem.d
+++ b/gcc/d/dmd/enumsem.d
@@ -81,7 +81,7 @@ import dmd.visitor;
 
 
 /*********************************
- * Perform semantic analysis on enum declaration `em`
+ * Perform semantic analysis on enum declaration `ed`
  */
 void enumSemantic(Scope* sc, EnumDeclaration ed)
 {
@@ -158,9 +158,10 @@ void enumSemantic(Scope* sc, EnumDeclaration ed)
                 ed.semanticRun = PASS.initial;
                 return;
             }
-            else
-                // Ensure that semantic is run to detect. e.g. invalid forward references
-                sym.dsymbolSemantic(sc);
+            // Ensure that semantic is run to detect. e.g. invalid forward references
+            sym.dsymbolSemantic(sc);
+            if (ed.errors)
+                ed.memtype = Type.terror; // avoid infinite recursion in toBaseType
         }
         if (ed.memtype.ty == Tvoid)
         {
@@ -175,6 +176,8 @@ void enumSemantic(Scope* sc, EnumDeclaration ed)
             ed.semanticRun = PASS.semanticdone;
             return;
         }
+        if (global.params.useTypeInfo && Type.dtypeinfo && !ed.inNonRoot())
+            semanticTypeInfo(sc, ed.memtype);
     }
 
     if (!ed.members) // enum ident : memtype;
@@ -229,122 +232,24 @@ void enumSemantic(Scope* sc, EnumDeclaration ed)
     addEnumMembersToSymtab(ed, sc, sc.getScopesym());
 
     if (sc.inCfile)
-    {
-        /* C11 6.7.2.2
-         */
-        Type commonType = ed.memtype;
-        if (!commonType)
-            commonType = Type.tint32;
-        ulong nextValue = 0;        // C11 6.7.2.2-3 first member value defaults to 0
-
-        // C11 6.7.2.2-2 value must be representable as an int.
-        // The sizemask represents all values that int will fit into,
-        // from 0..uint.max.  We want to cover int.min..uint.max.
-        IntRange ir = IntRange.fromType(commonType);
-
-        void emSemantic(EnumMember em, ref ulong nextValue)
-        {
-            static void errorReturn(EnumMember em)
-            {
-                em.value = ErrorExp.get();
-                em.errors = true;
-                em.semanticRun = PASS.semanticdone;
-            }
-
-            em.semanticRun = PASS.semantic;
-            em.type = commonType;
-            em._linkage = LINK.c;
-            em.storage_class |= STC.manifest;
-            if (em.value)
-            {
-                Expression e = em.value;
-                assert(e.dyncast() == DYNCAST.expression);
-
-                /* To merge the type of e with commonType, add 0 of type commonType
-                 */
-                if (!ed.memtype)
-                    e = new AddExp(em.loc, e, new IntegerExp(em.loc, 0, commonType));
-
-                e = e.expressionSemantic(sc);
-                e = resolveProperties(sc, e);
-                e = e.integralPromotions(sc);
-                e = e.ctfeInterpret();
-                if (e.op == EXP.error)
-                    return errorReturn(em);
-                auto ie = e.isIntegerExp();
-                if (!ie)
-                {
-                    // C11 6.7.2.2-2
-                    .error(em.loc, "%s `%s` enum member must be an integral constant expression, not `%s` of type `%s`", em.kind, em.toPrettyChars, e.toChars(), e.type.toChars());
-                    return errorReturn(em);
-                }
-                if (ed.memtype && !ir.contains(getIntRange(ie)))
-                {
-                    // C11 6.7.2.2-2
-                    .error(em.loc, "%s `%s` enum member value `%s` does not fit in `%s`", em.kind, em.toPrettyChars, e.toChars(), commonType.toChars());
-                    return errorReturn(em);
-                }
-                nextValue = ie.toInteger();
-                if (!ed.memtype)
-                    commonType = e.type;
-                em.value = new IntegerExp(em.loc, nextValue, commonType);
-            }
-            else
-            {
-                // C11 6.7.2.2-3 add 1 to value of previous enumeration constant
-                bool first = (em == (*em.ed.members)[0]);
-                if (!first)
-                {
-                    Expression max = getProperty(commonType, null, em.loc, Id.max, 0);
-                    if (nextValue == max.toInteger())
-                    {
-                        .error(em.loc, "%s `%s` initialization with `%s+1` causes overflow for type `%s`", em.kind, em.toPrettyChars, max.toChars(), commonType.toChars());
-                        return errorReturn(em);
-                    }
-                    nextValue += 1;
-                }
-                em.value = new IntegerExp(em.loc, nextValue, commonType);
-            }
-            em.type = commonType;
-            em.semanticRun = PASS.semanticdone;
-        }
-
-        ed.members.foreachDsymbol( (s)
-        {
-            if (EnumMember em = s.isEnumMember())
-                emSemantic(em, nextValue);
-        });
-
-        if (!ed.memtype)
-        {
-            // cast all members to commonType
-            ed.members.foreachDsymbol( (s)
-            {
-                if (EnumMember em = s.isEnumMember())
-                {
-                    em.type = commonType;
-                    // optimize out the cast so that other parts of the compiler can
-                    // assume that an integral enum's members are `IntegerExp`s.
-                    // https://issues.dlang.org/show_bug.cgi?id=24504
-                    em.value = em.value.castTo(sc, commonType).optimize(WANTvalue);
-                }
-            });
-        }
-
-        ed.memtype = commonType;
-        ed.semanticRun = PASS.semanticdone;
-        return;
-    }
+        return cEnumSemantic(sc, ed);
 
     ed.members.foreachDsymbol( (s)
     {
         if (EnumMember em = s.isEnumMember())
             em.dsymbolSemantic(em._scope);
     });
+
+    if (global.params.useTypeInfo && Type.dtypeinfo && !ed.inNonRoot())
+        semanticTypeInfo(sc, ed.memtype);
     //printf("ed.defaultval = %lld\n", ed.defaultval);
 
     //if (ed.defaultval) printf("ed.defaultval: %s %s\n", ed.defaultval.toChars(), ed.defaultval.type.toChars());
     //printf("members = %s\n", members.toChars());
+
+    // Set semantic2done here to indicate all members have been processed
+    // This prevents using the enum in a final switch while being defined
+    ed.semanticRun = PASS.semantic2done;
 }
 
 Expression getDefaultValue(EnumDeclaration ed, Loc loc)
@@ -625,6 +530,21 @@ void enumMemberSemantic(Scope* sc, EnumMember em)
         });
 
         assert(emprev);
+
+        // New check: if the base type is an enum, auto-increment is not supported,
+        // unless it is a special enum (for example, the C types like cpp_long/longlong).
+        if (auto te = em.ed.memtype ? em.ed.memtype.isTypeEnum() : null)
+        {
+            if (!te.sym.isSpecial())
+            {
+                error(em.loc,
+                      "cannot automatically assign value to enum member `%s` because base type `%s` is an enum; provide an explicit value",
+                      em.toPrettyChars(), em.ed.memtype.toChars());
+                return errorReturn();
+            }
+        }
+
+
         if (emprev.semanticRun < PASS.semanticdone) // if forward reference
             emprev.dsymbolSemantic(emprev._scope); // resolve it
         if (emprev.errors)
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index d65b163ee668..c29484d9e7bf 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -86,7 +86,7 @@ inout(Expression) lastComma(inout Expression e)
  *     exps  = array of Expressions
  *     names = optional array of names corresponding to Expressions
  */
-void expandTuples(Expressions* exps, Identifiers* names = null)
+void expandTuples(Expressions* exps, ArgumentLabels* names = null)
 {
     //printf("expandTuples()\n");
     if (exps is null)
@@ -116,7 +116,7 @@ void expandTuples(Expressions* exps, Identifiers* names = null)
             }
             foreach (i; 1 .. length)
             {
-                names.insert(index + i, cast(Identifier) null);
+                names.insert(index + i, ArgumentLabel(cast(Identifier) null, Loc.init));
             }
         }
     }
@@ -306,6 +306,7 @@ extern (C++) abstract class Expression : ASTNode
     {
     bool parens;    // if this is a parenthesized expression
     bool rvalue;    // true if this is considered to be an rvalue, even if it is an lvalue
+    bool gcPassDone; // `checkGC` has been run on this expression
     }
     import dmd.common.bitfields;
     mixin(generateBitFields!(BitFields, ubyte));
@@ -1405,6 +1406,8 @@ extern (C++) final class StringExp : Expression
 
     /// If the string is parsed from a hex string literal
     bool hexString = false;
+    /// If the string is from a collected C macro
+    bool cMacro = false;
 
     enum char NoPostfix = 0;
 
@@ -1416,13 +1419,14 @@ extern (C++) final class StringExp : Expression
         this.sz = 1;                    // work around LDC bug #1286
     }
 
-    extern (D) this(Loc loc, const(void)[] string, size_t len, ubyte sz, char postfix = NoPostfix) scope
+    extern (D) this(Loc loc, const(void)[] string, size_t len, ubyte sz, char postfix = NoPostfix, bool cMacro = false) scope
     {
         super(loc, EXP.string_);
         this.string = cast(char*)string.ptr; // note that this.string should be const
         this.len = len;
         this.sz = sz;
         this.postfix = postfix;
+        this.cMacro = cMacro;
     }
 
     static StringExp create(Loc loc, const(char)* s)
@@ -2445,7 +2449,7 @@ extern (C++) final class NewExp : Expression
     Expression thisexp;         // if !=null, 'this' for class being allocated
     Type newtype;
     Expressions* arguments;     // Array of Expression's
-    Identifiers* names;         // Array of names corresponding to expressions
+    ArgumentLabels* names;         // Array of names(name and location of name) corresponding to expressions
     Expression placement;       // if !=null, then PlacementExpression
 
     Expression argprefix;       // expression to be evaluated just before arguments[]
@@ -2457,9 +2461,10 @@ extern (C++) final class NewExp : Expression
 
     /// Puts the `arguments` and `names` into an `ArgumentList` for easily passing them around.
     /// The fields are still separate for backwards compatibility
+
     extern (D) ArgumentList argumentList() { return ArgumentList(arguments, names); }
 
-    extern (D) this(Loc loc, Expression placement, Expression thisexp, Type newtype, Expressions* arguments, Identifiers* names = null) @safe
+    extern (D) this(Loc loc, Expression placement, Expression thisexp, Type newtype, Expressions* arguments, ArgumentLabels* names = null) @safe
     {
         super(loc, EXP.new_);
         this.placement = placement;
@@ -3271,29 +3276,36 @@ extern (C++) final class DotTypeExp : UnaExp
 struct ArgumentList
 {
     Expressions* arguments; // function arguments
-    Identifiers* names;     // named argument identifiers
+    ArgumentLabels* names;  // named argument labels
 
     size_t length() const @nogc nothrow pure @safe { return arguments ? arguments.length : 0; }
 
     /// Returns: whether this argument list contains any named arguments
-    bool hasNames() const @nogc nothrow pure @safe
+    bool hasArgNames() const @nogc nothrow pure @safe
     {
         if (names is null)
             return false;
-        foreach (name; *names)
-            if (name !is null)
+        foreach (argLabel; *names)
+            if (argLabel.name !is null)
                 return true;
 
         return false;
     }
 }
 
+// Contains both `name` and `location of the name` for an expression.
+struct ArgumentLabel
+{
+    Identifier name;    // name of the argument
+    Loc loc;            // location of the name
+ }
+
 /***********************************************************
  */
 extern (C++) final class CallExp : UnaExp
 {
     Expressions* arguments; // function arguments
-    Identifiers* names;     // named argument identifiers
+    ArgumentLabels *names;  // named argument labels
     FuncDeclaration f;      // symbol to call
     bool directcall;        // true if a virtual call is devirtualized
     bool inDebugStatement;  /// true if this was in a debug statement
@@ -3305,7 +3317,7 @@ extern (C++) final class CallExp : UnaExp
     /// The fields are still separate for backwards compatibility
     extern (D) ArgumentList argumentList() { return ArgumentList(arguments, names); }
 
-    extern (D) this(Loc loc, Expression e, Expressions* exps, Identifiers* names = null) @safe
+    extern (D) this(Loc loc, Expression e, Expressions* exps, ArgumentLabels *names = null) @safe
     {
         super(loc, EXP.call, e);
         this.arguments = exps;
@@ -3851,6 +3863,9 @@ extern (C++) final class CommaExp : BinExp
     /// false will be passed will be from the parser.
     bool allowCommaExp;
 
+    /// The original expression before any rewriting occurs.
+    /// This is used in error messages.
+    Expression originalExp;
 
     extern (D) this(Loc loc, Expression e1, Expression e2, bool generated = true) @safe
     {
@@ -3858,6 +3873,12 @@ extern (C++) final class CommaExp : BinExp
         allowCommaExp = isGenerated = generated;
     }
 
+    extern (D) this(Loc loc, Expression e1, Expression e2, Expression oe) @safe
+    {
+        this(loc, e1, e2);
+        originalExp = oe;
+    }
+
     override bool isLvalue()
     {
         return !rvalue && e2.isLvalue();
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index 3c8d90dd7eb6..6b4298b3308b 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -51,14 +51,13 @@ namespace dmd
 {
     // in expressionsem.d
     Expression *expressionSemantic(Expression *e, Scope *sc);
-    void lowerNonArrayAggregate(StaticForeach *sfe, Scope *sc);
     // in typesem.d
     Expression *defaultInit(Type *mt, Loc loc, const bool isCfile = false);
 
     // Entry point for CTFE.
     // A compile-time result is required. Give an error if not possible
     Expression *ctfeInterpret(Expression *e);
-    void expandTuples(Expressions *exps, Identifiers *names = nullptr);
+    void expandTuples(Expressions *exps, ArgumentLabels *names = nullptr);
     Expression *optimize(Expression *exp, int result, bool keepLvalue = false);
 }
 
@@ -354,6 +353,7 @@ public:
     unsigned char sz;   // 1: char, 2: wchar, 4: dchar
     d_bool committed;   // if type is committed
     d_bool hexString;   // if string is parsed from a hex string literal
+    d_bool cMacro;      // If the string is from a collected C macro
 
     static StringExp *create(Loc loc, const char *s);
     static StringExp *create(Loc loc, const void *s, d_size_t len);
@@ -518,7 +518,7 @@ public:
     Expression *thisexp;        // if !NULL, 'this' for class being allocated
     Type *newtype;
     Expressions *arguments;     // Array of Expression's
-    Identifiers *names;         // Array of names corresponding to expressions
+    ArgumentLabels *names;      // Array of argument Labels (name and location of name) corresponding to expressions
     Expression *placement;      // if !NULL, placement expression
 
     Expression *argprefix;      // expression to be evaluated just before arguments[]
@@ -795,23 +795,38 @@ public:
 struct ArgumentList final
 {
     Expressions* arguments;
-    Identifiers* names;
+    ArgumentLabels* names;
     ArgumentList() :
         arguments(),
         names()
     {
     }
-    ArgumentList(Expressions* arguments, Identifiers* names = nullptr) :
+    ArgumentList(Expressions* arguments, ArgumentLabels* names = nullptr) :
         arguments(arguments),
         names(names)
         {}
 };
 
+struct ArgumentLabel final
+{
+    Identifier* name;
+    Loc loc;
+    ArgumentLabel() :
+        name(),
+        loc()
+    {
+    }
+    ArgumentLabel(Identifier* name, Loc loc = Loc()) :
+        name(name),
+        loc(loc)
+        {}
+};
+
 class CallExp final : public UnaExp
 {
 public:
     Expressions *arguments;     // function arguments
-    Identifiers *names;
+    ArgumentLabels* names;      // function argument Labels (name + location of name)
     FuncDeclaration *f;         // symbol to call
     d_bool directcall;            // true if a virtual call is devirtualized
     d_bool inDebugStatement;      // true if this was in a debug statement
@@ -935,6 +950,7 @@ public:
 class ArrayLengthExp final : public UnaExp
 {
 public:
+    Expression lowering;
     void accept(Visitor *v) override { v->visit(this); }
 };
 
@@ -990,6 +1006,7 @@ class CommaExp final : public BinExp
 public:
     d_bool isGenerated;
     d_bool allowCommaExp;
+    Expression* originalExp;
     bool isLvalue() override;
     Optional<bool> toBool() override;
     void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index b02f6ea64102..2576d7c0d056 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -1334,8 +1334,8 @@ private Expression resolveUFCS(Scope* sc, CallExp ce)
         ce.arguments = new Expressions();
     ce.arguments.shift(eleft);
     if (!ce.names)
-        ce.names = new Identifiers();
-    ce.names.shift(null);
+        ce.names = new ArgumentLabels();
+    ce.names.shift(ArgumentLabel(cast(Identifier) null, Loc.init));
     ce.isUfcsRewrite = true;
     return null;
 }
@@ -4115,16 +4115,28 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
 
         /* Look for what user might have meant
          */
-        if (const n = importHint(exp.ident.toString()))
-            error(exp.loc, "`%s` is not defined, perhaps `import %.*s;` is needed?", exp.ident.toChars(), cast(int)n.length, n.ptr);
-        else if (auto s2 = sc.search_correct(exp.ident))
-            error(exp.loc, "undefined identifier `%s`, did you mean %s `%s`?", exp.ident.toChars(), s2.kind(), s2.toChars());
-        else if (const p = Scope.search_correct_C(exp.ident))
-            error(exp.loc, "undefined identifier `%s`, did you mean `%s`?", exp.ident.toChars(), p);
-        else if (exp.ident == Id.dollar)
-            error(exp.loc, "undefined identifier `$`");
+        if (!(sc && sc.inCfile))
+        {
+            if (const n = importHint(exp.ident.toString()))
+                error(exp.loc, "`%s` is not defined, perhaps `import %.*s;` is needed?", exp.ident.toChars(), cast(int)n.length, n.ptr);
+            else if (auto s2 = sc.search_correct(exp.ident))
+                error(exp.loc, "undefined identifier `%s`, did you mean %s `%s`?", exp.ident.toChars(), s2.kind(), s2.toChars());
+            else if (const p = Scope.search_correct_C(exp.ident))
+                error(exp.loc, "undefined identifier `%s`, did you mean `%s`?", exp.ident.toChars(), p);
+            else if (exp.ident == Id.dollar)
+                error(exp.loc, "undefined identifier `$`");
+            else
+                error(exp.loc, "undefined identifier `%s`", exp.ident.toChars());
+        }
         else
-            error(exp.loc, "undefined identifier `%s`", exp.ident.toChars());
+        {
+            if (const n = cIncludeHint(exp.ident.toString()))
+                error(exp.loc, "`%s` is not defined, perhaps `#include %.*s` is needed?", exp.ident.toChars(), cast(int)n.length, n.ptr);
+            else if (auto s2 = sc.search_correct(exp.ident))
+                error(exp.loc, "undefined identifier `%s`, did you mean %s `%s`?", exp.ident.toChars(), s2.kind(), s2.toChars());
+            else
+                error(exp.loc, "undefined identifier `%s`", exp.ident.toChars());
+        }
 
         result = ErrorExp.get();
     }
@@ -4416,7 +4428,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             }
             buffer.write4(0);
             e.setData(buffer.extractData(), newlen, 4);
-            if (sc && sc.inCfile)
+            if (!e.cMacro && sc && sc.inCfile)
                 e.type = Type.tuns32.sarrayOf(e.len + 1);
             else
                 e.type = Type.tdchar.immutableOf().arrayOf();
@@ -4441,7 +4453,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             }
             buffer.writeUTF16(0);
             e.setData(buffer.extractData(), newlen, 2);
-            if (sc && sc.inCfile)
+            if (!e.cMacro && sc && sc.inCfile)
                 e.type = Type.tuns16.sarrayOf(e.len + 1);
             else
                 e.type = Type.twchar.immutableOf().arrayOf();
@@ -4453,7 +4465,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             goto default;
 
         default:
-            if (sc && sc.inCfile)
+            if (!e.cMacro && sc && sc.inCfile)
                 e.type = Type.tchar.sarrayOf(e.len + 1);
             else
                 e.type = Type.tchar.immutableOf().arrayOf();
@@ -4551,7 +4563,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
         {
             printf("AssocArrayLiteralExp::semantic('%s')\n", e.toChars());
         }
-
+        if (e.type)
+        {
+            // already done, but we might have missed generating type info
+            semanticTypeInfo(sc, e.type);
+            result = e;
+            return;
+        }
         // Run semantic() on each element
         bool err_keys = arrayExpressionSemantic(e.keys.peekSlice(), sc);
         bool err_vals = arrayExpressionSemantic(e.values.peekSlice(), sc);
@@ -4894,6 +4912,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 error(p.loc, "PlacementExpression `%s` of type `%s` be unshared and mutable", p.toChars(), toChars(p.type));
                 return setError();
             }
+            checkModifiable(exp.placement, sc);
         }
 
         //for error messages if the argument in [] is not convertible to size_t
@@ -5294,10 +5313,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             {
                 if (exp.names)
                 {
-                    exp.arguments = resolveStructLiteralNamedArgs(sd, exp.type, sc, exp.loc,
-                        exp.names ? (*exp.names)[] : null,
+                    exp.arguments = resolveStructLiteralNamedArgs(sd, exp.type, sc, exp.loc, exp.names.length,
+                        i => (*exp.names)[i].name,
                         (size_t i, Type t) => (*exp.arguments)[i],
-                        i => (*exp.arguments)[i].loc
+                        i => (*exp.arguments)[i].loc,
+                        i => (*exp.names)[i].loc
                     );
                     if (!exp.arguments)
                         return setError();
@@ -5361,9 +5381,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 }
 
                 Expression arg = (*exp.arguments)[i];
-                if (exp.names && (*exp.names)[i])
+                if (exp.names && (*exp.names)[i].name)
                 {
-                    error(exp.loc, "no named argument `%s` allowed for array dimension", (*exp.names)[i].toChars());
+                    error(exp.loc, "no named argument `%s` allowed for array dimension", (*exp.names)[i].name.toChars());
                     return setError();
                 }
 
@@ -5477,9 +5497,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             }
             else if (nargs == 1)
             {
-                if (exp.names && (*exp.names)[0])
+                if (exp.names && (*exp.names)[0].name)
                 {
-                    error(exp.loc, "no named argument `%s` allowed for scalar", (*exp.names)[0].toChars());
+                    error(exp.loc, "no named argument `%s` allowed for scalar", (*exp.names)[0].name.toChars());
                     return setError();
                 }
                 Expression e = (*exp.arguments)[0];
@@ -6269,10 +6289,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 Expressions* resolvedArgs = exp.arguments;
                 if (exp.names)
                 {
-                    resolvedArgs = resolveStructLiteralNamedArgs(sd, exp.e1.type, sc, exp.loc,
-                        (*exp.names)[],
+                    resolvedArgs = resolveStructLiteralNamedArgs(sd, exp.e1.type, sc, exp.loc, exp.names.length,
+                        i => (*exp.names)[i].name,
                         (size_t i, Type t) => (*exp.arguments)[i],
-                        i => (*exp.arguments)[i].loc
+                        i => (*exp.arguments)[i].loc,
+                        i => (*exp.names)[i].loc
                     );
                     if (!resolvedArgs)
                     {
@@ -7303,6 +7324,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             sc2.tinst = null;
             sc2.minst = null;
             sc2.fullinst = true;
+            sc2.traitsCompiles = true;
             Type t = dmd.typesem.trySemantic(e.targ, e.loc, sc2);
             sc2.pop();
             if (!t) // errors, so condition is false
@@ -8177,37 +8199,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             if (exp.arrow) // ImportC only
                 exp.e1 = exp.e1.expressionSemantic(sc).arrayFuncConv(sc);
 
-            if (exp.ident == Id.__xalignof && exp.e1.isTypeExp())
-            {
-                // C11 6.5.3 says _Alignof only applies to types
-                Expression e;
-                Type t;
-                Dsymbol s;
-                dmd.typesem.resolve(exp.e1.type, exp.e1.loc, sc, e, t, s, true);
-                if (e)
-                {
-                    error(exp.e1.loc, "argument to `_Alignof` must be a type");
-                    return setError();
-                }
-                else if (t)
-                {
-                    // Note similarity to getProperty() implementation of __xalignof
-                    const explicitAlignment = t.alignment();
-                    const naturalAlignment = t.alignsize();
-                    const actualAlignment = (explicitAlignment.isDefault() ? naturalAlignment : explicitAlignment.get());
-                    result = new IntegerExp(exp.loc, actualAlignment, Type.tsize_t);
-                }
-                else if (s)
-                {
-                    error(exp.e1.loc, "argument to `_Alignof` must be a type");
-                    return setError();
-                }
-                else
-                    assert(0);
-                return;
-            }
-
-            if (exp.ident != Id.__sizeof)
+            if (exp.ident != Id.__sizeof && exp.ident != Id.__xalignof)
             {
                 result = fieldLookup(exp.e1, sc, exp.ident, exp.arrow);
                 return;
@@ -10595,7 +10587,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             {
                 TupleDeclaration td = isAliasThisTuple(e2x);
                 if (!td)
-                    goto Lnomatch;
+                {
+                Lnomatch:
+                    error(exp.loc, "cannot assign `%s` to expression sequence `%s`",
+                        exp.e2.type.toChars(), exp.e1.type.toChars());
+                    return setError();
+                }
 
                 assert(exp.e1.type.ty == Ttuple);
                 TypeTuple tt = cast(TypeTuple)exp.e1.type;
@@ -10637,7 +10634,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 // Do not need to overwrite this.e2
                 goto Ltupleassign;
             }
-        Lnomatch:
         }
 
         /* Inside constructor, if this is the first assignment of object field,
@@ -11241,25 +11237,30 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
          */
         if (auto ale = exp.e1.isArrayLengthExp())
         {
-            // e1 is not an lvalue, but we let code generator handle it
 
+            // Ensure e1 is a modifiable lvalue
             auto ale1x = ale.e1.modifiableLvalueImpl(sc, exp.e1);
             if (ale1x.op == EXP.error)
                 return setResult(ale1x);
             ale.e1 = ale1x;
 
+            // Ensure the element type has a valid constructor
             Type tn = ale.e1.type.toBasetype().nextOf();
             checkDefCtor(ale.loc, tn);
 
+            // Choose correct GC hook
             Identifier hook = global.params.tracegc ? Id._d_arraysetlengthTTrace : Id._d_arraysetlengthT;
-            if (!verifyHookExist(exp.loc, *sc, Id._d_arraysetlengthTImpl, "resizing arrays"))
+
+            // Verify the correct hook exists
+            if (!verifyHookExist(exp.loc, *sc, hook, "resizing arrays"))
                 return setError();
 
             exp.e2 = exp.e2.expressionSemantic(sc);
             auto lc = lastComma(exp.e2);
             lc = lc.optimize(WANTvalue);
-            // use slice expression when arr.length = 0 to avoid runtime call
-            if(lc.op == EXP.int64 && lc.toInteger() == 0)
+
+            // Optimize case where arr.length = 0
+            if (lc.op == EXP.int64 && lc.toInteger() == 0)
             {
                 Expression se = new SliceExp(ale.loc, ale.e1, lc, lc);
                 Expression as = new AssignExp(ale.loc, ale.e1, se);
@@ -11269,30 +11270,27 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 return setResult(res);
             }
 
-            if (!sc.needsCodegen())      // if compile time creature only
+            if (!sc.needsCodegen()) // Compile-time only case
             {
                 exp.type = Type.tsize_t;
                 return setResult(exp);
             }
 
-            // Lower to object._d_arraysetlengthTImpl!(typeof(e1))._d_arraysetlengthT{,Trace}(e1, e2)
+            // Ensure correct reference for _d_arraysetlengthT
             Expression id = new IdentifierExp(ale.loc, Id.empty);
             id = new DotIdExp(ale.loc, id, Id.object);
-            auto tiargs = new Objects();
-            tiargs.push(ale.e1.type);
-            id = new DotTemplateInstanceExp(ale.loc, id, Id._d_arraysetlengthTImpl, tiargs);
             id = new DotIdExp(ale.loc, id, hook);
             id = id.expressionSemantic(sc);
 
+            // Generate call: _d_arraysetlengthT(e1, e2)
             auto arguments = new Expressions();
-            arguments.push(ale.e1);
-            arguments.push(exp.e2);
+            arguments.push(ale.e1);  // array
+            arguments.push(exp.e2);  // new length
 
             Expression ce = new CallExp(ale.loc, id, arguments).expressionSemantic(sc);
             auto res = new LoweredAssignExp(exp, ce);
-            // if (global.params.verbose)
-            //     message("lowered   %s =>\n          %s", exp.toChars(), res.toChars());
             res.type = Type.tsize_t;
+
             return setResult(res);
         }
         else if (auto se = exp.e1.isSliceExp())
@@ -11761,6 +11759,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
 
         res = new LoweredAssignExp(ae, res);
         res.type = ae.type;
+        res = res.checkGC(sc);
 
         return res;
     }
@@ -12795,6 +12794,57 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             return;
         }
 
+        // Inline the expression, if possible.
+        PowExp pe = cast(PowExp)e;
+        if (pe.e1.type.isScalar() && pe.e2.isIntegerExp())
+        {
+            Expression one;
+            if (pe.e1.type.isIntegral()) {
+                one = new IntegerExp(e.loc, 1, pe.e1.type);
+            } else {
+                one = new RealExp(e.loc, CTFloat.one, pe.e1.type);
+            }
+
+            const expo = cast(sinteger_t)pe.e2.toInteger();
+            // Replace e1 ^^ -1 with 1 / e1
+            if (expo == -1)
+            {
+                Expression ex = new DivExp(exp.loc, one, pe.e1);
+                ex = ex.expressionSemantic(sc);
+                result = ex;
+                return;
+            }
+            // Replace e1 ^^ 0 with (e1, 1)
+            else if (expo == 0)
+            {
+                Expression ex = new CommaExp(exp.loc, pe.e1, one, exp);
+                ex = ex.expressionSemantic(sc);
+                result = ex;
+                return;
+            }
+            // Replace e1 ^^ 1 with e1
+            else if (expo == 1)
+            {
+                Expression ex = pe.e1;
+                ex.loc = exp.loc;
+                ex = ex.expressionSemantic(sc);
+                result = ex;
+                return;
+            }
+            // Replace e1 ^^ 2 with e1 * e1
+            else if (expo == 2)
+            {
+                auto v = copyToTemp(STC.const_, "__powtmp", pe.e1);
+                auto ve = new VarExp(exp.loc, v);
+                auto de = new DeclarationExp(exp.e1.loc, v);
+                auto me = new MulExp(exp.e2.loc, ve, ve);
+                Expression ex = new CommaExp(exp.loc, de, me, exp);
+                ex = ex.expressionSemantic(sc);
+                result = ex;
+                return;
+            }
+        }
+
         Module mmath = Module.loadStdMath();
         if (!mmath)
         {
@@ -13874,6 +13924,7 @@ private bool expressionSemanticDone(Expression e)
         || e.isTypeExp() // stores its type in the Expression.type field
         || e.isCompoundLiteralExp() // stores its `(type) {}` in type field, gets rewritten to struct literal
         || e.isVarExp() // type sometimes gets set already before semantic
+        || (e.isAssocArrayLiteralExp() && !e.type.vtinfo) // semanticTypeInfo not run during initialization
     );
 }
 
@@ -15771,11 +15822,12 @@ private Expression toLvalueImpl(Expression _this, Scope* sc, const(char)* action
 }
 
 /***************************************
- * Parameters:
- *      sc:     scope
- *      flag:   1: do not issue error message for invalid modification
-                2: the exp is a DotVarExp and a subfield of the leftmost
-                   variable is modified
+ * Params:
+ *      exp  = expression to check if modifiable
+ *      sc   = scope
+ *      flag = noError - do not issue error message for invalid modification
+               fieldAssign - exp is a DotVarExp and a subfield of the leftmost
+               variable is modified
  * Returns:
  *      Whether the type is modifiable
  */
@@ -16728,11 +16780,12 @@ enum ModifyFlags
 }
 
 /*************************************
- * Check to see if declaration can be modified in this context (sc).
+ * Check to see if `d` can be modified in this context `sc`.
  * Issue error if not.
  * Params:
+ *  d    = declaration to check
  *  loc  = location for error messages
- *  e1   = `null` or `this` expression when this declaration is a field
+ *  e1   = `null` or `this` expression when `d` is a field
  *  sc   = context
  *  flag = if the first bit is set it means do not issue error message for
  *         invalid modification; if the second bit is set, it means that
@@ -16742,6 +16795,7 @@ enum ModifyFlags
  */
 private Modifiable checkModify(Declaration d, Loc loc, Scope* sc, Expression e1, ModifyFlags flag)
 {
+    //printf("checkModify() d: %s, e1: %s\n", d.toChars(), e1.toChars());
     VarDeclaration v = d.isVarDeclaration();
     if (v && v.canassign)
         return Modifiable.initialization;
@@ -16787,15 +16841,19 @@ private Modifiable checkModify(Declaration d, Loc loc, Scope* sc, Expression e1,
 }
 
 /***********************************************
- * Mark variable v as modified if it is inside a constructor that var
+ * Mark variable `var` as modified if it is inside a constructor that `var`
  * is a field in.
  * Also used to allow immutable globals to be initialized inside a static constructor.
+ * Params:
+ *    loc = location for error messages
+ *    sc = scope
+ *    var = field
  * Returns:
- *    true if it's an initialization of v
+ *    true if it's an initialization of `var`
  */
 private bool modifyFieldVar(Loc loc, Scope* sc, VarDeclaration var, Expression e1)
 {
-    //printf("modifyFieldVar(var = %s)\n", var.toChars());
+    //printf("modifyFieldVar(var: %s, e1: %s)\n", var.toChars(), e1.toChars());
     Dsymbol s = sc.func;
     while (1)
     {
@@ -16811,7 +16869,7 @@ private bool modifyFieldVar(Loc loc, Scope* sc, VarDeclaration var, Expression e
             bool result = true;
 
             var.ctorinit = true;
-            //printf("setting ctorinit\n");
+            //printf("setting ctorinit for %s\n", var.toChars());
 
             if (var.isField() && sc.ctorflow.fieldinit.length && !sc.intypeof)
             {
@@ -17457,7 +17515,7 @@ bool fill(StructDeclaration sd, Loc loc, ref Expressions elements, bool ctorinit
 *     sfe = The 'static foreach'.
 *     sc = The current scope.
 */
-extern (C++) void lowerNonArrayAggregate(StaticForeach sfe, Scope* sc)
+void lowerNonArrayAggregate(StaticForeach sfe, Scope* sc)
 {
     import dmd.statement;
 
@@ -17671,3 +17729,143 @@ extern(D) void lowerArrayAggregate(StaticForeach sfe, Scope* sc)
     sfe.aggrfe.aggr = sfe.aggrfe.aggr.optimize(WANTvalue);
     sfe.aggrfe.aggr = sfe.aggrfe.aggr.ctfeInterpret();
 }
+
+int include(Condition c, Scope* sc)
+{
+    scope v = new IncludeVisitor(sc);
+    c.accept(v);
+    return v.result;
+}
+
+private extern(C++) class IncludeVisitor : Visitor {
+    alias visit = Visitor.visit;
+
+    Scope *sc;
+    int result;
+
+    this(Scope* sc)
+    {
+        this.sc = sc;
+    }
+
+    override void visit(DebugCondition dc)
+    {
+        //printf("DebugCondition::include() level = %d, debuglevel = %d\n", level, global.params.debuglevel);
+        if (dc.inc != Include.notComputed)
+        {
+            result = dc.inc == Include.yes;
+            return;
+        }
+        dc.inc = Include.no;
+        bool definedInModule = false;
+        if (dc.ident)
+        {
+            if (dc.mod.debugids && findCondition(*dc.mod.debugids, dc.ident))
+            {
+                dc.inc = Include.yes;
+                definedInModule = true;
+            }
+            else if (findCondition(global.debugids, dc.ident))
+                dc.inc = Include.yes;
+            else
+            {
+                if (!dc.mod.debugidsNot)
+                    dc.mod.debugidsNot = new Identifiers();
+                dc.mod.debugidsNot.push(dc.ident);
+            }
+        }
+        else if (global.params.debugEnabled)
+            dc.inc = Include.yes;
+
+        if (!definedInModule)
+            printDepsConditional(sc, dc, "depsDebug ");
+        result = (dc.inc == Include.yes);
+    }
+
+    override void visit(VersionCondition vc)
+    {
+        //printf("VersionCondition::include() level = %d, versionlevel = %d\n", level, global.params.versionlevel);
+        //if (ident) printf("\tident = '%s'\n", ident.toChars());
+        if (vc.inc != Include.notComputed)
+        {
+            result = vc.inc == Include.yes;
+            return;
+        }
+
+        vc.inc = Include.no;
+        bool definedInModule = false;
+        if (vc.ident)
+        {
+            if (vc.mod.versionids && findCondition(*vc.mod.versionids, vc.ident))
+            {
+                vc.inc = Include.yes;
+                definedInModule = true;
+            }
+            else if (findCondition(global.versionids, vc.ident))
+                vc.inc = Include.yes;
+            else
+            {
+                if (!vc.mod.versionidsNot)
+                    vc.mod.versionidsNot = new Identifiers();
+                vc.mod.versionidsNot.push(vc.ident);
+            }
+        }
+        if (!definedInModule &&
+            (!vc.ident || (!vc.isReserved(vc.ident.toString()) && vc.ident != Id._unittest && vc.ident != Id._assert)))
+        {
+            printDepsConditional(sc, vc, "depsVersion ");
+        }
+        result = (vc.inc == Include.yes);
+    }
+
+    override void visit(StaticIfCondition sic)
+    {
+        // printf("StaticIfCondition::include(sc = %p) this=%p inc = %d\n", sc, this, inc);
+
+        int errorReturn()
+        {
+            if (!global.gag)
+                sic.inc = Include.no; // so we don't see the error message again
+            return 0;
+        }
+
+        if (sic.inc != Include.notComputed)
+        {
+            result = sic.inc == Include.yes;
+            return;
+        }
+
+        if (!sc)
+        {
+            error(sic.loc, "`static if` conditional cannot be at global scope");
+            sic.inc = Include.no;
+            result = 0;
+            return;
+        }
+
+        import dmd.staticcond;
+        bool errors;
+
+        bool local_result = evalStaticCondition(sc, sic.exp, sic.exp, errors);
+
+        // Prevent repeated condition evaluation.
+        // See: fail_compilation/fail7815.d
+        if (sic.inc != Include.notComputed)
+        {
+            result = (sic.inc == Include.yes);
+            return;
+        }
+
+        if (errors)
+        {
+            result = errorReturn();
+            return;
+        }
+
+        if (local_result)
+            sic.inc = Include.yes;
+        else
+            sic.inc = Include.no;
+        result = (sic.inc == Include.yes);
+    }
+}
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index 064b67f96060..6a573810a4b9 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -820,15 +820,13 @@ extern (C++) class FuncDeclaration : Declaration
     bool addPreInvariant()
     {
         auto ad = isThis();
-        ClassDeclaration cd = ad ? ad.isClassDeclaration() : null;
-        return (ad && !(cd && cd.isCPPclass()) && global.params.useInvariants == CHECKENABLE.on && (visibility.kind == Visibility.Kind.protected_ || visibility.kind == Visibility.Kind.public_ || visibility.kind == Visibility.Kind.export_) && !this.isNaked());
+        return (ad && global.params.useInvariants == CHECKENABLE.on && (visibility.kind == Visibility.Kind.protected_ || visibility.kind == Visibility.Kind.public_ || visibility.kind == Visibility.Kind.export_) && !this.isNaked());
     }
 
     bool addPostInvariant()
     {
         auto ad = isThis();
-        ClassDeclaration cd = ad ? ad.isClassDeclaration() : null;
-        return (ad && !(cd && cd.isCPPclass()) && ad.inv && global.params.useInvariants == CHECKENABLE.on && (visibility.kind == Visibility.Kind.protected_ || visibility.kind == Visibility.Kind.public_ || visibility.kind == Visibility.Kind.export_) && !this.isNaked());
+        return (ad && ad.inv && global.params.useInvariants == CHECKENABLE.on && (visibility.kind == Visibility.Kind.protected_ || visibility.kind == Visibility.Kind.public_ || visibility.kind == Visibility.Kind.export_) && !this.isNaked());
     }
 
     override const(char)* kind() const
diff --git a/gcc/d/dmd/funcsem.d b/gcc/d/dmd/funcsem.d
index 1231496e41ab..10f6f154b2ff 100644
--- a/gcc/d/dmd/funcsem.d
+++ b/gcc/d/dmd/funcsem.d
@@ -235,6 +235,17 @@ void funcDeclarationSemantic(Scope* sc, FuncDeclaration funcdecl)
     if ((funcdecl.storage_class & STC.TYPECTOR) && !(ad || funcdecl.isNested()))
         funcdecl.storage_class &= ~STC.TYPECTOR;
 
+    auto tf = funcdecl.type.isTypeFunction();
+    if ((funcdecl.storage_class & STC.auto_) && tf.isRef && !funcdecl.inferRetType)
+    {
+        if (!(funcdecl.storage_class & STC.autoref))
+        {
+            // @@@DEPRECATED_2.122@@@
+            // Deprecated in 2.112, turn into an error in 2.122
+            deprecation(funcdecl.loc, "`auto ref` return type must have `auto` and `ref` adjacent");
+            funcdecl.storage_class |= STC.autoref;
+        }
+    }
     //printf("function storage_class = x%llx, sc.stc = x%llx, %x\n", storage_class, sc.stc, Declaration.isFinal());
 
     if (sc.traitsCompiles)
@@ -272,20 +283,6 @@ void funcDeclarationSemantic(Scope* sc, FuncDeclaration funcdecl)
     if (!funcdecl.originalType)
         funcdecl.originalType = funcdecl.type.syntaxCopy();
 
-    static TypeFunction getFunctionType(FuncDeclaration fd)
-    {
-        if (auto tf = fd.type.isTypeFunction())
-            return tf;
-
-        if (!fd.type.isTypeError())
-        {
-            .error(fd.loc, "%s `%s` `%s` must be a function instead of `%s`", fd.kind, fd.toPrettyChars, fd.toChars(), fd.type.toChars());
-            fd.type = Type.terror;
-        }
-        fd.errors = true;
-        return null;
-    }
-
     if (sc.inCfile)
     {
         /* C11 allows a function to be declared with a typedef, D does not.
@@ -313,7 +310,6 @@ void funcDeclarationSemantic(Scope* sc, FuncDeclaration funcdecl)
         sc = sc.push();
         sc.stc |= funcdecl.storage_class & (STC.disable | STC.deprecated_); // forward to function type
 
-        TypeFunction tf = funcdecl.type.toTypeFunction();
         if (sc.func)
         {
             /* If the nesting parent is pure without inference,
@@ -563,587 +559,697 @@ void funcDeclarationSemantic(Scope* sc, FuncDeclaration funcdecl)
 
     if (ClassDeclaration cd = parent.isClassDeclaration())
     {
-        parent = cd = objc.getParent(funcdecl, cd);
+        switch (classFuncSemantic(cd, funcdecl, parent, sc, f))
+        {
+            case 0: break;
+            case 1: goto Ldone;
+            case 2: return;
+            default: assert(0);
+        }
+    }
+    else if (funcdecl.isOverride() && !parent.isTemplateInstance())
+        .error(funcdecl.loc, "%s `%s` `override` only applies to class member functions", funcdecl.kind, funcdecl.toPrettyChars);
+
+    if (auto ti = parent.isTemplateInstance)
+    {
+        objc.setSelector(funcdecl, sc);
+        objc.setAsOptional(funcdecl, sc);
+    }
 
-        if (funcdecl.isCtorDeclaration())
+    objc.validateSelector(funcdecl);
+    objc.validateOptional(funcdecl);
+    // Reflect this.type to f because it could be changed by findVtblIndex
+    f = funcdecl.type.toTypeFunction();
+
+Ldone:
+    if (!funcdecl.fbody && !funcdecl.allowsContractWithoutBody())
+        .error(funcdecl.loc, "%s `%s` `in` and `out` contracts can only appear without a body when they are virtual interface functions or abstract", funcdecl.kind, funcdecl.toPrettyChars);
+
+    /* Do not allow template instances to add virtual functions
+     * to a class.
+     */
+    if (funcdecl.isVirtual())
+    {
+        if (auto ti = parent.isTemplateInstance())
         {
-            goto Ldone;
+            // Take care of nested templates
+            while (1)
+            {
+                TemplateInstance ti2 = ti.tempdecl.parent.isTemplateInstance();
+                if (!ti2)
+                    break;
+                ti = ti2;
+            }
+
+            // If it's a member template
+            if (ClassDeclaration cd = ti.tempdecl.isClassMember())
+            {
+                .error(funcdecl.loc, "%s `%s` cannot use template to add virtual function to class `%s`", funcdecl.kind, funcdecl.toPrettyChars, cd.toChars());
+            }
         }
+    }
+
+    funcdecl.checkMain();       // Check main() parameters and return type
 
-        if (funcdecl.storage_class & STC.abstract_)
-            cd.isabstract = ThreeState.yes;
+    /* Purity and safety can be inferred for some functions by examining
+     * the function body.
+     */
+    if (funcdecl.canInferAttributes(sc))
+        funcdecl.initInferAttributes();
+
+    funcdecl.semanticRun = PASS.semanticdone;
 
-        // if static function, do not put in vtbl[]
-        if (!funcdecl.isVirtual())
+    /* Save scope for possible later use (if we need the
+     * function internals)
+     */
+    funcdecl._scope = sc.copy();
+    funcdecl._scope.setNoFree();
+
+    __gshared bool printedMain = false; // semantic might run more than once
+    if (global.params.v.verbose && !printedMain)
+    {
+        const(char)* type = funcdecl.isMain() ? "main" : funcdecl.isWinMain() ? "winmain" : funcdecl.isDllMain() ? "dllmain" : cast(const(char)*)null;
+        Module mod = sc._module;
+
+        if (type && mod)
         {
-            //printf("\tnot virtual\n");
-            goto Ldone;
+            printedMain = true;
+            auto name = mod.srcfile.toChars();
+            auto path = FileName.searchPath(global.importPaths, name, true);
+            message("entry     %-10s\t%s", type, path ? path : name);
         }
-        // Suppress further errors if the return type is an error
-        if (funcdecl.type.nextOf() == Type.terror)
-            goto Ldone;
+    }
 
-        bool may_override = false;
-        for (size_t i = 0; i < cd.baseclasses.length; i++)
+    if (funcdecl.fbody && sc._module.isRoot() &&
+        (funcdecl.isMain() || funcdecl.isWinMain() || funcdecl.isDllMain() || funcdecl.isCMain()))
+        global.hasMainFunction = true;
+
+    if (funcdecl.fbody && funcdecl.isMain() && sc._module.isRoot())
+    {
+        // check if `_d_cmain` is defined
+        bool cmainTemplateExists()
         {
-            BaseClass* b = (*cd.baseclasses)[i];
-            ClassDeclaration cbd = b.type.toBasetype().isClassHandle();
-            if (!cbd)
+            Dsymbol pscopesym;
+            auto rootSymbol = sc.search(funcdecl.loc, Id.empty, pscopesym);
+            if (auto moduleSymbol = rootSymbol.search(funcdecl.loc, Id.object))
+                if (moduleSymbol.search(funcdecl.loc, Id.CMain))
+                    return true;
+
+            return false;
+        }
+
+        // Only mixin `_d_cmain` if it is defined
+        if (cmainTemplateExists())
+        {
+            // add `mixin _d_cmain!();` to the declaring module
+            auto tqual = new TypeIdentifier(funcdecl.loc, Id.CMain);
+            auto tm = new TemplateMixin(funcdecl.loc, null, tqual, null);
+            sc._module.members.push(tm);
+        }
+    }
+
+    assert(funcdecl.type.ty != Terror || funcdecl.errors);
+
+    // semantic for parameters' UDAs
+    foreach (i, param; f.parameterList)
+    {
+        if (param && param.userAttribDecl)
+            param.userAttribDecl.dsymbolSemantic(sc);
+    }
+}
+
+/**
+ Returns:
+    0 if semantic analysis in `funcDeclarationSemantic` should continue as normal
+    1 if it should skip over some analysis and `goto Ldone;`
+    2 if `funcDeclarationSemantic` should return early because of forward refernce error or
+        the derived class cd doesn't have its vtbl[] allocated yet
+ */
+private int classFuncSemantic(ClassDeclaration cd, FuncDeclaration funcdecl,
+                              ref Dsymbol parent, Scope* sc, TypeFunction f)
+{
+    parent = cd = objc.getParent(funcdecl, cd);
+
+    if (funcdecl.isCtorDeclaration())
+    {
+        return 1;
+    }
+
+    if (funcdecl.storage_class & STC.abstract_)
+        cd.isabstract = ThreeState.yes;
+
+    // if static function, do not put in vtbl[]
+    if (!funcdecl.isVirtual())
+    {
+        //printf("\tnot virtual\n");
+        return 1;
+    }
+    // Suppress further errors if the return type is an error
+    if (funcdecl.type.nextOf() == Type.terror)
+        return 1;
+
+    bool may_override = false;
+    for (size_t i = 0; i < cd.baseclasses.length; i++)
+    {
+        BaseClass* b = (*cd.baseclasses)[i];
+        ClassDeclaration cbd = b.type.toBasetype().isClassHandle();
+        if (!cbd)
+            continue;
+        for (size_t j = 0; j < cbd.vtbl.length; j++)
+        {
+            FuncDeclaration f2 = cbd.vtbl[j].isFuncDeclaration();
+            if (!f2 || f2.ident != funcdecl.ident)
                 continue;
-            for (size_t j = 0; j < cbd.vtbl.length; j++)
+            if (cbd.parent && cbd.parent.isTemplateInstance())
             {
-                FuncDeclaration f2 = cbd.vtbl[j].isFuncDeclaration();
-                if (!f2 || f2.ident != funcdecl.ident)
-                    continue;
-                if (cbd.parent && cbd.parent.isTemplateInstance())
-                {
-                    if (!functionSemantic(f2))
-                        goto Ldone;
-                }
-                may_override = true;
+                if (!functionSemantic(f2))
+                    return 1;
             }
+            may_override = true;
         }
-        if (may_override && funcdecl.type.nextOf() is null)
+    }
+    if (may_override && funcdecl.type.nextOf() is null)
+    {
+        /* If same name function exists in base class but 'this' is auto return,
+         * cannot find index of base class's vtbl[] to override.
+         */
+        .error(funcdecl.loc, "%s `%s` return type inference is not supported if may override base class function", funcdecl.kind, funcdecl.toPrettyChars);
+    }
+
+    /* Find index of existing function in base class's vtbl[] to override
+     * (the index will be the same as in cd's current vtbl[])
+     */
+    int vi = cd.baseClass ? findVtblIndex(funcdecl, cd.baseClass.vtbl[]) : -1;
+
+    bool doesoverride = false;
+    switch (vi)
+    {
+    case -1:
+    Lintro:
+        /* Didn't find one, so
+         * This is an 'introducing' function which gets a new
+         * slot in the vtbl[].
+         */
+
+        // Verify this doesn't override previous final function
+        if (cd.baseClass)
         {
-            /* If same name function exists in base class but 'this' is auto return,
-             * cannot find index of base class's vtbl[] to override.
-             */
-            .error(funcdecl.loc, "%s `%s` return type inference is not supported if may override base class function", funcdecl.kind, funcdecl.toPrettyChars);
+            Dsymbol s = cd.baseClass.search(funcdecl.loc, funcdecl.ident);
+            if (s)
+            {
+                if (auto f2 = s.isFuncDeclaration())
+                {
+                    f2 = f2.overloadExactMatch(funcdecl.type);
+                    if (f2 && f2.isFinalFunc() && f2.visible().kind != Visibility.Kind.private_)
+                        .error(funcdecl.loc, "%s `%s` cannot override `final` function `%s`", funcdecl.kind, funcdecl.toPrettyChars, f2.toPrettyChars());
+                }
+            }
         }
 
-        /* Find index of existing function in base class's vtbl[] to override
-         * (the index will be the same as in cd's current vtbl[])
+        /* These quirky conditions mimic what happens when virtual
+           inheritance is implemented by producing a virtual base table
+           with offsets to each of the virtual bases.
          */
-        int vi = cd.baseClass ? findVtblIndex(funcdecl, cd.baseClass.vtbl[]) : -1;
-
-        bool doesoverride = false;
-        switch (vi)
+        if (target.cpp.splitVBasetable && cd.classKind == ClassKind.cpp &&
+            cd.baseClass && cd.baseClass.vtbl.length)
         {
-        case -1:
-        Lintro:
-            /* Didn't find one, so
-             * This is an 'introducing' function which gets a new
-             * slot in the vtbl[].
+            /* if overriding an interface function, then this is not
+             * introducing and don't put it in the class vtbl[]
              */
+            funcdecl.interfaceVirtual = overrideInterface(funcdecl);
+            if (funcdecl.interfaceVirtual)
+            {
+                //printf("\tinterface function %s\n", toChars());
+                cd.vtblFinal.push(funcdecl);
+                goto Linterfaces;
+            }
+        }
 
-            // Verify this doesn't override previous final function
-            if (cd.baseClass)
+        if (funcdecl.isFinalFunc())
+        {
+            // Don't check here, as it may override an interface function
+            //if (isOverride())
+            //    error("is marked as override, but does not override any function");
+            cd.vtblFinal.push(funcdecl);
+        }
+        else
+        {
+            //printf("\tintroducing function %s\n", funcdecl.toChars());
+            funcdecl.isIntroducing = true;
+            if (cd.classKind == ClassKind.cpp && target.cpp.reverseOverloads)
             {
-                Dsymbol s = cd.baseClass.search(funcdecl.loc, funcdecl.ident);
-                if (s)
+                /* Overloaded functions with same name are grouped and in reverse order.
+                 * Search for first function of overload group, and insert
+                 * funcdecl into vtbl[] immediately before it.
+                 */
+                funcdecl.vtblIndex = cast(int)cd.vtbl.length;
+                bool found;
+                foreach (const i, s; cd.vtbl)
                 {
-                    if (auto f2 = s.isFuncDeclaration())
+                    if (found)
+                        // the rest get shifted forward
+                        ++s.isFuncDeclaration().vtblIndex;
+                    else if (s.ident == funcdecl.ident && s.parent == parent)
                     {
-                        f2 = f2.overloadExactMatch(funcdecl.type);
-                        if (f2 && f2.isFinalFunc() && f2.visible().kind != Visibility.Kind.private_)
-                            .error(funcdecl.loc, "%s `%s` cannot override `final` function `%s`", funcdecl.kind, funcdecl.toPrettyChars, f2.toPrettyChars());
+                        // found first function of overload group
+                        funcdecl.vtblIndex = cast(int)i;
+                        found = true;
+                        ++s.isFuncDeclaration().vtblIndex;
                     }
                 }
+                cd.vtbl.insert(funcdecl.vtblIndex, funcdecl);
+
+                debug foreach (const i, s; cd.vtbl)
+                {
+                    // a C++ dtor gets its vtblIndex later (and might even be added twice to the vtbl),
+                    // e.g. when compiling druntime with a debug compiler, namely with core.stdcpp.exception.
+                    if (auto fd = s.isFuncDeclaration())
+                        assert(fd.vtblIndex == i ||
+                               (cd.classKind == ClassKind.cpp && fd.isDtorDeclaration) ||
+                               funcdecl.parent.isInterfaceDeclaration); // interface functions can be in multiple vtbls
+                }
+            }
+            else
+            {
+                // Append to end of vtbl[]
+                vi = cast(int)cd.vtbl.length;
+                cd.vtbl.push(funcdecl);
+                funcdecl.vtblIndex = vi;
             }
+        }
+        break;
 
-            /* These quirky conditions mimic what happens when virtual
-               inheritance is implemented by producing a virtual base table
-               with offsets to each of the virtual bases.
-             */
-            if (target.cpp.splitVBasetable && cd.classKind == ClassKind.cpp &&
-                cd.baseClass && cd.baseClass.vtbl.length)
+    case -2:
+        // can't determine because of forward references
+        funcdecl.errors = true;
+        return 2;
+
+    default:
+        {
+            if (vi >= cd.vtbl.length)
             {
-                /* if overriding an interface function, then this is not
-                 * introducing and don't put it in the class vtbl[]
+                /* the derived class cd doesn't have its vtbl[] allocated yet.
+                 * https://issues.dlang.org/show_bug.cgi?id=21008
                  */
-                funcdecl.interfaceVirtual = overrideInterface(funcdecl);
-                if (funcdecl.interfaceVirtual)
-                {
-                    //printf("\tinterface function %s\n", toChars());
-                    cd.vtblFinal.push(funcdecl);
-                    goto Linterfaces;
-                }
+                .error(funcdecl.loc, "%s `%s` circular reference to class `%s`", funcdecl.kind, funcdecl.toPrettyChars, cd.toChars());
+                funcdecl.errors = true;
+                return 2;
             }
+            FuncDeclaration fdv = cd.baseClass.vtbl[vi].isFuncDeclaration();
+            FuncDeclaration fdc = cd.vtbl[vi].isFuncDeclaration();
+            // This function is covariant with fdv
 
-            if (funcdecl.isFinalFunc())
+            if (fdc == funcdecl)
             {
-                // Don't check here, as it may override an interface function
-                //if (isOverride())
-                //    error("is marked as override, but does not override any function");
-                cd.vtblFinal.push(funcdecl);
+                doesoverride = true;
+                break;
             }
-            else
+
+            auto vtf = getFunctionType(fdv);
+            if (vtf.trust > TRUST.system && f.trust == TRUST.system)
+                .error(funcdecl.loc, "%s `%s` cannot override `@safe` method `%s` with a `@system` attribute", funcdecl.kind, funcdecl.toPrettyChars,
+                               fdv.toPrettyChars);
+
+            if (fdc.toParent() == parent)
             {
-                //printf("\tintroducing function %s\n", funcdecl.toChars());
-                funcdecl.isIntroducing = true;
-                if (cd.classKind == ClassKind.cpp && target.cpp.reverseOverloads)
-                {
-                    /* Overloaded functions with same name are grouped and in reverse order.
-                     * Search for first function of overload group, and insert
-                     * funcdecl into vtbl[] immediately before it.
-                     */
-                    funcdecl.vtblIndex = cast(int)cd.vtbl.length;
-                    bool found;
-                    foreach (const i, s; cd.vtbl)
-                    {
-                        if (found)
-                            // the rest get shifted forward
-                            ++s.isFuncDeclaration().vtblIndex;
-                        else if (s.ident == funcdecl.ident && s.parent == parent)
-                        {
-                            // found first function of overload group
-                            funcdecl.vtblIndex = cast(int)i;
-                            found = true;
-                            ++s.isFuncDeclaration().vtblIndex;
-                        }
-                    }
-                    cd.vtbl.insert(funcdecl.vtblIndex, funcdecl);
+                //printf("vi = %d,\tthis = %p %s %s @ [%s]\n\tfdc  = %p %s %s @ [%s]\n\tfdv  = %p %s %s @ [%s]\n",
+                //        vi, this, this.toChars(), this.type.toChars(), this.loc.toChars(),
+                //            fdc,  fdc .toChars(), fdc .type.toChars(), fdc .loc.toChars(),
+                //            fdv,  fdv .toChars(), fdv .type.toChars(), fdv .loc.toChars());
+
+                // fdc overrides fdv exactly, then this introduces new function.
+                if (fdc.type.mod == fdv.type.mod && funcdecl.type.mod != fdv.type.mod)
+                    goto Lintro;
+            }
 
-                    debug foreach (const i, s; cd.vtbl)
-                    {
-                        // a C++ dtor gets its vtblIndex later (and might even be added twice to the vtbl),
-                        // e.g. when compiling druntime with a debug compiler, namely with core.stdcpp.exception.
-                        if (auto fd = s.isFuncDeclaration())
-                            assert(fd.vtblIndex == i ||
-                                   (cd.classKind == ClassKind.cpp && fd.isDtorDeclaration) ||
-                                   funcdecl.parent.isInterfaceDeclaration); // interface functions can be in multiple vtbls
-                    }
+            if (fdv.isDeprecated && !funcdecl.isDeprecated)
+                deprecation(funcdecl.loc, "`%s` is overriding the deprecated method `%s`",
+                            funcdecl.toPrettyChars, fdv.toPrettyChars);
+
+            // This function overrides fdv
+            if (fdv.isFinalFunc())
+                .error(funcdecl.loc, "%s `%s` cannot override `final` function `%s`", funcdecl.kind, funcdecl.toPrettyChars, fdv.toPrettyChars());
+
+            if (!funcdecl.isOverride())
+            {
+                if (fdv.isFuture())
+                {
+                    deprecation(funcdecl.loc, "method `%s` implicitly overrides `@__future` base class method; rename the former",
+                        funcdecl.toPrettyChars());
+                    deprecationSupplemental(fdv.loc, "base method `%s` defined here",
+                        fdv.toPrettyChars());
+                    // Treat 'this' as an introducing function, giving it a separate hierarchy in the vtbl[]
+                    goto Lintro;
                 }
                 else
                 {
-                    // Append to end of vtbl[]
-                    vi = cast(int)cd.vtbl.length;
-                    cd.vtbl.push(funcdecl);
-                    funcdecl.vtblIndex = vi;
+                    // https://issues.dlang.org/show_bug.cgi?id=17349
+                    error(funcdecl.loc, "cannot implicitly override base class method `%s` with `%s`; add `override` attribute",
+                          fdv.toPrettyChars(), funcdecl.toPrettyChars());
                 }
             }
-            break;
-
-        case -2:
-            // can't determine because of forward references
-            funcdecl.errors = true;
-            return;
-
-        default:
+            doesoverride = true;
+            if (fdc.toParent() == parent)
             {
-                if (vi >= cd.vtbl.length)
+                // If both are mixins, or both are not, then error.
+                // If either is not, the one that is not overrides the other.
+                bool thismixin = funcdecl.parent.isClassDeclaration() !is null;
+                bool fdcmixin = fdc.parent.isClassDeclaration() !is null;
+                if (thismixin == fdcmixin)
+                {
+                    .error(funcdecl.loc, "%s `%s` multiple overrides of same function", funcdecl.kind, funcdecl.toPrettyChars);
+                }
+                /*
+                 * https://issues.dlang.org/show_bug.cgi?id=711
+                 *
+                 * If an overriding method is introduced through a mixin,
+                 * we need to update the vtbl so that both methods are
+                 * present.
+                 */
+                else if (thismixin)
                 {
-                    /* the derived class cd doesn't have its vtbl[] allocated yet.
-                     * https://issues.dlang.org/show_bug.cgi?id=21008
+                    /* if the mixin introduced the overriding method, then reintroduce it
+                     * in the vtbl. The initial entry for the mixined method
+                     * will be updated at the end of the enclosing `if` block
+                     * to point to the current (non-mixined) function.
                      */
-                    .error(funcdecl.loc, "%s `%s` circular reference to class `%s`", funcdecl.kind, funcdecl.toPrettyChars, cd.toChars());
-                    funcdecl.errors = true;
-                    return;
+                    auto vitmp = cast(int)cd.vtbl.length;
+                    cd.vtbl.push(fdc);
+                    fdc.vtblIndex = vitmp;
                 }
-                FuncDeclaration fdv = cd.baseClass.vtbl[vi].isFuncDeclaration();
-                FuncDeclaration fdc = cd.vtbl[vi].isFuncDeclaration();
-                // This function is covariant with fdv
-
-                if (fdc == funcdecl)
+                else if (fdcmixin)
                 {
-                    doesoverride = true;
+                    /* if the current overriding function is coming from a
+                     * mixined block, then push the current function in the
+                     * vtbl, but keep the previous (non-mixined) function as
+                     * the overriding one.
+                     */
+                    auto vitmp = cast(int)cd.vtbl.length;
+                    cd.vtbl.push(funcdecl);
+                    funcdecl.vtblIndex = vitmp;
                     break;
                 }
-
-                auto vtf = getFunctionType(fdv);
-                if (vtf.trust > TRUST.system && f.trust == TRUST.system)
-                    .error(funcdecl.loc, "%s `%s` cannot override `@safe` method `%s` with a `@system` attribute", funcdecl.kind, funcdecl.toPrettyChars,
-                                   fdv.toPrettyChars);
-
-                if (fdc.toParent() == parent)
+                else // fdc overrides fdv
                 {
-                    //printf("vi = %d,\tthis = %p %s %s @ [%s]\n\tfdc  = %p %s %s @ [%s]\n\tfdv  = %p %s %s @ [%s]\n",
-                    //        vi, this, this.toChars(), this.type.toChars(), this.loc.toChars(),
-                    //            fdc,  fdc .toChars(), fdc .type.toChars(), fdc .loc.toChars(),
-                    //            fdv,  fdv .toChars(), fdv .type.toChars(), fdv .loc.toChars());
-
-                    // fdc overrides fdv exactly, then this introduces new function.
-                    if (fdc.type.mod == fdv.type.mod && funcdecl.type.mod != fdv.type.mod)
-                        goto Lintro;
+                    // this doesn't override any function
+                    break;
                 }
+            }
+            cd.vtbl[vi] = funcdecl;
+            funcdecl.vtblIndex = vi;
 
-                if (fdv.isDeprecated && !funcdecl.isDeprecated)
-                    deprecation(funcdecl.loc, "`%s` is overriding the deprecated method `%s`",
-                                funcdecl.toPrettyChars, fdv.toPrettyChars);
-
-                // This function overrides fdv
-                if (fdv.isFinalFunc())
-                    .error(funcdecl.loc, "%s `%s` cannot override `final` function `%s`", funcdecl.kind, funcdecl.toPrettyChars, fdv.toPrettyChars());
+            /* Remember which functions this overrides
+             */
+            funcdecl.foverrides.push(fdv);
+
+            /* This works by whenever this function is called,
+             * it actually returns tintro, which gets dynamically
+             * cast to type. But we know that tintro is a base
+             * of type, so we could optimize it by not doing a
+             * dynamic cast, but just subtracting the isBaseOf()
+             * offset if the value is != null.
+             */
 
-                if (!funcdecl.isOverride())
-                {
-                    if (fdv.isFuture())
-                    {
-                        deprecation(funcdecl.loc, "method `%s` implicitly overrides `@__future` base class method; rename the former",
-                            funcdecl.toPrettyChars());
-                        deprecationSupplemental(fdv.loc, "base method `%s` defined here",
-                            fdv.toPrettyChars());
-                        // Treat 'this' as an introducing function, giving it a separate hierarchy in the vtbl[]
-                        goto Lintro;
-                    }
-                    else
-                    {
-                        // https://issues.dlang.org/show_bug.cgi?id=17349
-                        error(funcdecl.loc, "cannot implicitly override base class method `%s` with `%s`; add `override` attribute",
-                              fdv.toPrettyChars(), funcdecl.toPrettyChars());
-                    }
-                }
-                doesoverride = true;
-                if (fdc.toParent() == parent)
+            if (fdv.tintro)
+                funcdecl.tintro = fdv.tintro;
+            else if (!funcdecl.type.equals(fdv.type))
+            {
+                auto tnext = funcdecl.type.nextOf();
+                if (auto handle = tnext.isClassHandle())
                 {
-                    // If both are mixins, or both are not, then error.
-                    // If either is not, the one that is not overrides the other.
-                    bool thismixin = funcdecl.parent.isClassDeclaration() !is null;
-                    bool fdcmixin = fdc.parent.isClassDeclaration() !is null;
-                    if (thismixin == fdcmixin)
-                    {
-                        .error(funcdecl.loc, "%s `%s` multiple overrides of same function", funcdecl.kind, funcdecl.toPrettyChars);
-                    }
-                    /*
-                     * https://issues.dlang.org/show_bug.cgi?id=711
-                     *
-                     * If an overriding method is introduced through a mixin,
-                     * we need to update the vtbl so that both methods are
-                     * present.
-                     */
-                    else if (thismixin)
-                    {
-                        /* if the mixin introduced the overriding method, then reintroduce it
-                         * in the vtbl. The initial entry for the mixined method
-                         * will be updated at the end of the enclosing `if` block
-                         * to point to the current (non-mixined) function.
-                         */
-                        auto vitmp = cast(int)cd.vtbl.length;
-                        cd.vtbl.push(fdc);
-                        fdc.vtblIndex = vitmp;
-                    }
-                    else if (fdcmixin)
-                    {
-                        /* if the current overriding function is coming from a
-                         * mixined block, then push the current function in the
-                         * vtbl, but keep the previous (non-mixined) function as
-                         * the overriding one.
-                         */
-                        auto vitmp = cast(int)cd.vtbl.length;
-                        cd.vtbl.push(funcdecl);
-                        funcdecl.vtblIndex = vitmp;
-                        break;
-                    }
-                    else // fdc overrides fdv
-                    {
-                        // this doesn't override any function
-                        break;
-                    }
+                    if (handle.semanticRun < PASS.semanticdone && !handle.isBaseInfoComplete())
+                        handle.dsymbolSemantic(null);
                 }
-                cd.vtbl[vi] = funcdecl;
-                funcdecl.vtblIndex = vi;
-
-                /* Remember which functions this overrides
+                /* Only need to have a tintro if the vptr
+                 * offsets differ
                  */
-                funcdecl.foverrides.push(fdv);
-
-                /* This works by whenever this function is called,
-                 * it actually returns tintro, which gets dynamically
-                 * cast to type. But we know that tintro is a base
-                 * of type, so we could optimize it by not doing a
-                 * dynamic cast, but just subtracting the isBaseOf()
-                 * offset if the value is != null.
-                 */
-
-                if (fdv.tintro)
-                    funcdecl.tintro = fdv.tintro;
-                else if (!funcdecl.type.equals(fdv.type))
+                int offset;
+                if (fdv.type.nextOf().isBaseOf(tnext, &offset))
                 {
-                    auto tnext = funcdecl.type.nextOf();
-                    if (auto handle = tnext.isClassHandle())
-                    {
-                        if (handle.semanticRun < PASS.semanticdone && !handle.isBaseInfoComplete())
-                            handle.dsymbolSemantic(null);
-                    }
-                    /* Only need to have a tintro if the vptr
-                     * offsets differ
-                     */
-                    int offset;
-                    if (fdv.type.nextOf().isBaseOf(tnext, &offset))
-                    {
-                        funcdecl.tintro = fdv.type;
-                    }
+                    funcdecl.tintro = fdv.type;
                 }
-                break;
             }
+            break;
         }
+    }
 
-        /* Go through all the interface bases.
-         * If this function is covariant with any members of those interface
-         * functions, set the tintro.
-         */
-    Linterfaces:
-        bool foundVtblMatch = false;
+    /* Go through all the interface bases.
+     * If this function is covariant with any members of those interface
+     * functions, set the tintro.
+     */
+Linterfaces:
+    bool foundVtblMatch = false;
 
-        for (ClassDeclaration bcd = cd; !foundVtblMatch && bcd; bcd = bcd.baseClass)
+    for (ClassDeclaration bcd = cd; !foundVtblMatch && bcd; bcd = bcd.baseClass)
+    {
+        foreach (b; bcd.interfaces)
         {
-            foreach (b; bcd.interfaces)
+            vi = findVtblIndex(funcdecl, b.sym.vtbl[]);
+            switch (vi)
             {
-                vi = findVtblIndex(funcdecl, b.sym.vtbl[]);
-                switch (vi)
-                {
-                case -1:
-                    break;
+            case -1:
+                break;
 
-                case -2:
-                    // can't determine because of forward references
-                    funcdecl.errors = true;
-                    return;
+            case -2:
+                // can't determine because of forward references
+                funcdecl.errors = true;
+                return 2;
 
-                default:
-                    {
-                        auto fdv = cast(FuncDeclaration)b.sym.vtbl[vi];
-                        Type ti = null;
+            default:
+                {
+                    auto fdv = cast(FuncDeclaration)b.sym.vtbl[vi];
+                    Type ti = null;
 
-                        foundVtblMatch = true;
+                    foundVtblMatch = true;
 
-                        /* Remember which functions this overrides
-                         */
-                        funcdecl.foverrides.push(fdv);
+                    /* Remember which functions this overrides
+                     */
+                    funcdecl.foverrides.push(fdv);
 
-                        if (fdv.tintro)
-                            ti = fdv.tintro;
-                        else if (!funcdecl.type.equals(fdv.type))
+                    if (fdv.tintro)
+                        ti = fdv.tintro;
+                    else if (!funcdecl.type.equals(fdv.type))
+                    {
+                        /* Only need to have a tintro if the vptr
+                         * offsets differ
+                         */
+                        int offset;
+                        if (fdv.type.nextOf().isBaseOf(funcdecl.type.nextOf(), &offset))
                         {
-                            /* Only need to have a tintro if the vptr
-                             * offsets differ
-                             */
-                            int offset;
-                            if (fdv.type.nextOf().isBaseOf(funcdecl.type.nextOf(), &offset))
-                            {
-                                ti = fdv.type;
-                            }
+                            ti = fdv.type;
                         }
-                        if (ti)
+                    }
+                    if (ti)
+                    {
+                        if (funcdecl.tintro)
                         {
-                            if (funcdecl.tintro)
-                            {
-                                if (!funcdecl.tintro.nextOf().equals(ti.nextOf()) && !funcdecl.tintro.nextOf().isBaseOf(ti.nextOf(), null) && !ti.nextOf().isBaseOf(funcdecl.tintro.nextOf(), null))
-                                {
-                                    .error(funcdecl.loc, "%s `%s` incompatible covariant types `%s` and `%s`", funcdecl.kind, funcdecl.toPrettyChars, funcdecl.tintro.toChars(), ti.toChars());
-                                }
-                            }
-                            else
+                            if (!funcdecl.tintro.nextOf().equals(ti.nextOf()) && !funcdecl.tintro.nextOf().isBaseOf(ti.nextOf(), null) && !ti.nextOf().isBaseOf(funcdecl.tintro.nextOf(), null))
                             {
-                                funcdecl.tintro = ti;
+                                .error(funcdecl.loc, "%s `%s` incompatible covariant types `%s` and `%s`", funcdecl.kind, funcdecl.toPrettyChars, funcdecl.tintro.toChars(), ti.toChars());
                             }
                         }
+                        else
+                        {
+                            funcdecl.tintro = ti;
+                        }
                     }
                 }
             }
         }
-        if (foundVtblMatch)
+    }
+    if (foundVtblMatch)
+    {
+        goto L2;
+    }
+
+    if (!doesoverride && funcdecl.isOverride() && (funcdecl.type.nextOf() || !may_override))
+    {
+        BaseClass* bc = null;
+        Dsymbol s = null;
+        for (size_t i = 0; i < cd.baseclasses.length; i++)
         {
-            goto L2;
+            bc = (*cd.baseclasses)[i];
+            s = bc.sym.search_correct(funcdecl.ident);
+            if (s)
+                break;
         }
 
-        if (!doesoverride && funcdecl.isOverride() && (funcdecl.type.nextOf() || !may_override))
+        if (s)
         {
-            BaseClass* bc = null;
-            Dsymbol s = null;
-            for (size_t i = 0; i < cd.baseclasses.length; i++)
-            {
-                bc = (*cd.baseclasses)[i];
-                s = bc.sym.search_correct(funcdecl.ident);
-                if (s)
-                    break;
-            }
+            HdrGenState hgs;
+            OutBuffer buf;
 
-            if (s)
+            auto fd = s.isFuncDeclaration();
+            functionToBufferFull(cast(TypeFunction)(funcdecl.type), buf,
+                new Identifier(funcdecl.toPrettyChars()), hgs, null);
+            const(char)* funcdeclToChars = buf.peekChars();
+
+            if (fd)
             {
-                HdrGenState hgs;
-                OutBuffer buf;
+                OutBuffer buf1;
 
-                auto fd = s.isFuncDeclaration();
-                functionToBufferFull(cast(TypeFunction)(funcdecl.type), buf,
-                    new Identifier(funcdecl.toPrettyChars()), hgs, null);
-                const(char)* funcdeclToChars = buf.peekChars();
+                if (fd.ident == funcdecl.ident)
+                    hgs.fullQual = true;
 
-                if (fd)
+                // https://issues.dlang.org/show_bug.cgi?id=23745
+                // If the potentially overridden function contains errors,
+                // inform the user to fix that one first
+                if (fd.errors)
                 {
-                    OutBuffer buf1;
-
-                    if (fd.ident == funcdecl.ident)
-                        hgs.fullQual = true;
+                    error(funcdecl.loc, "function `%s` does not override any function, did you mean to override `%s`?",
+                        funcdecl.toChars(), fd.toPrettyChars());
+                    errorSupplemental(fd.loc, "Function `%s` contains errors in its declaration, therefore it cannot be correctly overridden",
+                        fd.toPrettyChars());
+                }
+                else if (fd.isFinalFunc())
+                {
+                    // When trying to override a final method, don't suggest it as a candidate(Issue #19613)
+                    .error(funcdecl.loc, "%s `%s` does not override any function", funcdecl.kind, funcdecl.toPrettyChars);
 
-                    // https://issues.dlang.org/show_bug.cgi?id=23745
-                    // If the potentially overridden function contains errors,
-                    // inform the user to fix that one first
-                    if (fd.errors)
-                    {
-                        error(funcdecl.loc, "function `%s` does not override any function, did you mean to override `%s`?",
-                            funcdecl.toChars(), fd.toPrettyChars());
-                        errorSupplemental(fd.loc, "Function `%s` contains errors in its declaration, therefore it cannot be correctly overridden",
-                            fd.toPrettyChars());
-                    }
-                    else
+                    // Look for a non-final method with the same name to suggest as an alternative
+                    auto cdparent = fd.parent ? fd.parent.isClassDeclaration() : null;
+                    if (cdparent)
                     {
-                        functionToBufferFull(cast(TypeFunction)(fd.type), buf1,
-                            new Identifier(fd.toPrettyChars()), hgs, null);
+                        Dsymbol nonFinalAlt = null;
 
-                        error(funcdecl.loc, "function `%s` does not override any function, did you mean to override `%s`?",
-                            funcdeclToChars, buf1.peekChars());
-                   }
+                        auto overloadableSyms = cdparent.symtab.lookup(fd.ident);
+                        if (overloadableSyms)
+                        {
+                            // Check each overload to find one that's not final
+                            overloadApply(overloadableSyms, (Dsymbol s)
+                            {
+                                if (auto funcAlt = s.isFuncDeclaration())
+                                {
+                                    if (funcAlt != fd && !funcAlt.isFinalFunc())
+                                    {
+                                        nonFinalAlt = funcAlt;
+                                        return 1;
+                                    }
+                                }
+                                return 0;
+                            });
+
+                            // Provide a helpful suggestion if we found a viable alternative
+                            if (nonFinalAlt)
+                            {
+                                auto funcAlt = nonFinalAlt.isFuncDeclaration();
+                                OutBuffer buf2;
+                                functionToBufferFull(cast(TypeFunction)(funcAlt.type), buf2,
+                                    new Identifier(funcAlt.toPrettyChars()), hgs, null);
+                                errorSupplemental(funcdecl.loc, "Did you mean to override `%s`?", buf2.peekChars());
+                            }
+                        }
+                    }
                 }
                 else
                 {
-                    error(funcdecl.loc, "function `%s` does not override any function, did you mean to override %s `%s`?",
-                        funcdeclToChars, s.kind, s.toPrettyChars());
-                    errorSupplemental(funcdecl.loc, "Functions are the only declarations that may be overridden");
-                }
-            }
-            else
-                .error(funcdecl.loc, "%s `%s` does not override any function", funcdecl.kind, funcdecl.toPrettyChars);
-        }
+                    functionToBufferFull(cast(TypeFunction)(fd.type), buf1,
+                        new Identifier(fd.toPrettyChars()), hgs, null);
 
-    L2:
-        objc.setSelector(funcdecl, sc);
-        objc.checkLinkage(funcdecl);
-        objc.addToClassMethodList(funcdecl, cd);
-        objc.setAsOptional(funcdecl, sc);
+                    error(funcdecl.loc, "function `%s` does not override any function, did you mean to override `%s`?",
+                        funcdeclToChars, buf1.peekChars());
 
-        /* Go through all the interface bases.
-         * Disallow overriding any final functions in the interface(s).
-         */
-        foreach (b; cd.interfaces)
-        {
-            if (b.sym)
-            {
-                if (auto s = search_function(b.sym, funcdecl.ident))
-                {
-                    if (auto f2 = s.isFuncDeclaration())
-                    {
-                        f2 = f2.overloadExactMatch(funcdecl.type);
-                        if (f2 && f2.isFinalFunc() && f2.visible().kind != Visibility.Kind.private_)
-                            .error(funcdecl.loc, "%s `%s` cannot override `final` function `%s.%s`", funcdecl.kind, funcdecl.toPrettyChars, b.sym.toChars(), f2.toPrettyChars());
-                    }
-                }
-            }
-        }
-
-        if (funcdecl.isOverride)
-        {
-            if (funcdecl.storage_class & STC.disable)
-                deprecation(funcdecl.loc,
-                            "`%s` cannot be annotated with `@disable` because it is overriding a function in the base class",
-                            funcdecl.toPrettyChars);
+                    // Supplemental error for parameter scope differences
+                    auto tf1 = cast(TypeFunction)funcdecl.type;
+                    auto tf2 = cast(TypeFunction)fd.type;
 
-            if (funcdecl.isDeprecated && !(funcdecl.foverrides.length && funcdecl.foverrides[0].isDeprecated))
-                deprecation(funcdecl.loc,
-                            "`%s` cannot be marked as `deprecated` because it is overriding a function in the base class",
-                            funcdecl.toPrettyChars);
-        }
+                    if (tf1 && tf2)
+                    {
+                        auto params1 = tf1.parameterList;
+                        auto params2 = tf2.parameterList;
 
-    }
-    else if (funcdecl.isOverride() && !parent.isTemplateInstance())
-        .error(funcdecl.loc, "%s `%s` `override` only applies to class member functions", funcdecl.kind, funcdecl.toPrettyChars);
+                        if (params1.length == params2.length)
+                        {
+                            bool hasScopeDifference = false;
 
-    if (auto ti = parent.isTemplateInstance)
-    {
-        objc.setSelector(funcdecl, sc);
-        objc.setAsOptional(funcdecl, sc);
-    }
+                            for (size_t i = 0; i < params1.length; i++)
+                            {
+                                auto p1 = params1[i];
+                                auto p2 = params2[i];
 
-    objc.validateSelector(funcdecl);
-    objc.validateOptional(funcdecl);
-    // Reflect this.type to f because it could be changed by findVtblIndex
-    f = funcdecl.type.toTypeFunction();
+                                if ((p1.storageClass & STC.scope_) == (p2.storageClass & STC.scope_))
+                                    continue;
 
-Ldone:
-    if (!funcdecl.fbody && !funcdecl.allowsContractWithoutBody())
-        .error(funcdecl.loc, "%s `%s` `in` and `out` contracts can only appear without a body when they are virtual interface functions or abstract", funcdecl.kind, funcdecl.toPrettyChars);
+                                if (!(p2.storageClass & STC.scope_))
+                                    continue;
 
-    /* Do not allow template instances to add virtual functions
-     * to a class.
-     */
-    if (funcdecl.isVirtual())
-    {
-        if (auto ti = parent.isTemplateInstance())
-        {
-            // Take care of nested templates
-            while (1)
-            {
-                TemplateInstance ti2 = ti.tempdecl.parent.isTemplateInstance();
-                if (!ti2)
-                    break;
-                ti = ti2;
+                                if (!hasScopeDifference)
+                                {
+                                    // Intended signature
+                                    errorSupplemental(funcdecl.loc, "Did you intend to override:");
+                                    errorSupplemental(funcdecl.loc, "`%s`", buf1.peekChars());
+                                    hasScopeDifference = true;
+                                }
+                                errorSupplemental(funcdecl.loc, "Parameter %d is missing `scope`",
+                                cast(int)(i + 1));
+                            }
+                        }
+                    }
+               }
             }
-
-            // If it's a member template
-            if (ClassDeclaration cd = ti.tempdecl.isClassMember())
+            else
             {
-                .error(funcdecl.loc, "%s `%s` cannot use template to add virtual function to class `%s`", funcdecl.kind, funcdecl.toPrettyChars, cd.toChars());
+                error(funcdecl.loc, "function `%s` does not override any function, did you mean to override %s `%s`?",
+                    funcdeclToChars, s.kind, s.toPrettyChars());
+                errorSupplemental(funcdecl.loc, "Functions are the only declarations that may be overridden");
             }
         }
+        else
+            .error(funcdecl.loc, "%s `%s` does not override any function", funcdecl.kind, funcdecl.toPrettyChars);
     }
 
-    funcdecl.checkMain();       // Check main() parameters and return type
+L2:
+    objc.setSelector(funcdecl, sc);
+    objc.checkLinkage(funcdecl);
+    objc.addToClassMethodList(funcdecl, cd);
+    objc.setAsOptional(funcdecl, sc);
 
-    /* Purity and safety can be inferred for some functions by examining
-     * the function body.
+    /* Go through all the interface bases.
+     * Disallow overriding any final functions in the interface(s).
      */
-    if (funcdecl.canInferAttributes(sc))
-        funcdecl.initInferAttributes();
-
-    funcdecl.semanticRun = PASS.semanticdone;
-
-    /* Save scope for possible later use (if we need the
-     * function internals)
-     */
-    funcdecl._scope = sc.copy();
-    funcdecl._scope.setNoFree();
-
-    __gshared bool printedMain = false; // semantic might run more than once
-    if (global.params.v.verbose && !printedMain)
+    foreach (b; cd.interfaces)
     {
-        const(char)* type = funcdecl.isMain() ? "main" : funcdecl.isWinMain() ? "winmain" : funcdecl.isDllMain() ? "dllmain" : cast(const(char)*)null;
-        Module mod = sc._module;
-
-        if (type && mod)
+        if (b.sym)
         {
-            printedMain = true;
-            auto name = mod.srcfile.toChars();
-            auto path = FileName.searchPath(global.importPaths, name, true);
-            message("entry     %-10s\t%s", type, path ? path : name);
+            if (auto s = search_function(b.sym, funcdecl.ident))
+            {
+                if (auto f2 = s.isFuncDeclaration())
+                {
+                    f2 = f2.overloadExactMatch(funcdecl.type);
+                    if (f2 && f2.isFinalFunc() && f2.visible().kind != Visibility.Kind.private_)
+                        .error(funcdecl.loc, "%s `%s` cannot override `final` function `%s.%s`", funcdecl.kind, funcdecl.toPrettyChars, b.sym.toChars(), f2.toPrettyChars());
+                }
+            }
         }
     }
 
-    if (funcdecl.fbody && sc._module.isRoot() &&
-        (funcdecl.isMain() || funcdecl.isWinMain() || funcdecl.isDllMain() || funcdecl.isCMain()))
-        global.hasMainFunction = true;
-
-    if (funcdecl.fbody && funcdecl.isMain() && sc._module.isRoot())
+    if (funcdecl.isOverride)
     {
-        // check if `_d_cmain` is defined
-        bool cmainTemplateExists()
-        {
-            Dsymbol pscopesym;
-            auto rootSymbol = sc.search(funcdecl.loc, Id.empty, pscopesym);
-            if (auto moduleSymbol = rootSymbol.search(funcdecl.loc, Id.object))
-                if (moduleSymbol.search(funcdecl.loc, Id.CMain))
-                    return true;
-
-            return false;
-        }
+        if (funcdecl.storage_class & STC.disable)
+            deprecation(funcdecl.loc,
+                        "`%s` cannot be annotated with `@disable` because it is overriding a function in the base class",
+                        funcdecl.toPrettyChars);
 
-        // Only mixin `_d_cmain` if it is defined
-        if (cmainTemplateExists())
-        {
-            // add `mixin _d_cmain!();` to the declaring module
-            auto tqual = new TypeIdentifier(funcdecl.loc, Id.CMain);
-            auto tm = new TemplateMixin(funcdecl.loc, null, tqual, null);
-            sc._module.members.push(tm);
-        }
+        if (funcdecl.isDeprecated && !(funcdecl.foverrides.length && funcdecl.foverrides[0].isDeprecated))
+            deprecation(funcdecl.loc,
+                        "`%s` cannot be marked as `deprecated` because it is overriding a function in the base class",
+                        funcdecl.toPrettyChars);
     }
+    return 0;
+}
 
-    assert(funcdecl.type.ty != Terror || funcdecl.errors);
+private TypeFunction getFunctionType(FuncDeclaration fd)
+{
+    if (auto tf = fd.type.isTypeFunction())
+        return tf;
 
-    // semantic for parameters' UDAs
-    foreach (i, param; f.parameterList)
+    if (!fd.type.isTypeError())
     {
-        if (param && param.userAttribDecl)
-            param.userAttribDecl.dsymbolSemantic(sc);
+        .error(fd.loc, "%s `%s` `%s` must be a function instead of `%s`", fd.kind, fd.toPrettyChars, fd.toChars(), fd.type.toChars());
+        fd.type = Type.terror;
     }
+    fd.errors = true;
+    return null;
 }
 
 /*****************************************
@@ -1657,13 +1763,17 @@ FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,
             if (!od && !td.overnext)
             {
                 .error(loc, "%s `%s` is not callable using argument types `!(%s)%s`",
-                   td.kind(), td.ident.toChars(), tiargsBuf.peekChars(), fargsBuf.peekChars());
+                    td.kind(), td.ident.toChars(), tiargsBuf.peekChars(), fargsBuf.peekChars());
+
+                checkNamedArgErrorAndReport(td, argumentList, loc);
             }
             else
             {
                 .error(loc, "none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`",
-                   td.kind(), td.parent.toPrettyChars(), td.ident.toChars(),
-                   tiargsBuf.peekChars(), fargsBuf.peekChars());
+                    td.kind(), td.parent.toPrettyChars(), td.ident.toChars(),
+                    tiargsBuf.peekChars(), fargsBuf.peekChars());
+
+                checkNamedArgErrorAndReport(td, argumentList, loc);
             }
 
 
@@ -1683,7 +1793,9 @@ FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,
     if (od)
     {
         .error(loc, "none of the overloads of `%s` are callable using argument types `!(%s)%s`",
-               od.ident.toChars(), tiargsBuf.peekChars(), fargsBuf.peekChars());
+            od.ident.toChars(), tiargsBuf.peekChars(), fargsBuf.peekChars());
+
+        checkNamedArgErrorAndReportOverload(od, argumentList, loc);
         if (!global.gag || global.params.v.showGaggedErrors)
             printCandidates(loc, od, sc.isDeprecated());
         return null;
@@ -1713,8 +1825,14 @@ FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,
             OutBuffer buf;
             buf.argExpTypesToCBuffer(fargs);
             if (fd.isCtorDeclaration())
-                .error(loc, "none of the overloads of `%s` can construct a %sobject with argument types `(%s)`",
-                    fd.toChars(), thisBuf.peekChars(), buf.peekChars());
+            {
+                if (tthis.mod & MODFlags.immutable_)
+                    .error(loc, "none of the overloads of `%s` can construct an immutable object with argument types `(%s)`. Expected `immutable(%s)`",
+                        fd.toChars(), buf.peekChars(), buf.peekChars());
+                else
+                    .error(loc, "none of the overloads of `%s` can construct a %sobject with argument types `(%s)`",
+                        fd.toChars(), thisBuf.peekChars(), buf.peekChars());
+            }
             else
                 .error(loc, "none of the overloads of `%s` are callable using a %sobject with argument types `(%s)`",
                     fd.toChars(), thisBuf.peekChars(), buf.peekChars());
@@ -1782,10 +1900,15 @@ FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,
                     functionResolve(mErr, baseFunction, loc, sc, tiargs, baseClass.type, argumentList);
                     if (mErr.last > MATCH.nomatch && mErr.lastf)
                     {
-                        errorSupplemental(loc, "%s `%s` hides base class function `%s`",
-                                fd.kind, fd.toPrettyChars(), mErr.lastf.toPrettyChars());
-                        errorSupplemental(loc, "add `alias %s = %s` to `%s`'s body to merge the overload sets",
-                                fd.toChars(), mErr.lastf.toPrettyChars(), tthis.toChars());
+                        errorSupplemental(loc, "Note: %s `%s` hides base class %s `%s`",
+                            fd.kind, fd.toPrettyChars(),
+                            mErr.lastf.kind, mErr.lastf.toPrettyChars());
+
+                        if (!fd.isCtorDeclaration)
+                        {
+                            errorSupplemental(loc, "Add `alias %s = %s;` to `%s`'s body to merge the overload sets",
+                                    fd.toChars(), mErr.lastf.toPrettyChars(), tthis.toChars());
+                        }
                         return null;
                     }
                 }
@@ -1803,6 +1926,62 @@ FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,
     return null;
 }
 
+/********************************************************
+ * Check for named argument errors in template declarations and report them.
+ * Params:
+ *      td = template declaration to check
+ *      argumentList = arguments to check
+ *      loc = location for error reporting
+ */
+private void checkNamedArgErrorAndReport(TemplateDeclaration td, ArgumentList argumentList, Loc loc)
+{
+    if (!argumentList.hasArgNames())
+        return;
+
+    auto tf = td.onemember ? td.onemember.isFuncDeclaration() : null;
+    if (tf && tf.type && tf.type.ty == Tfunction)
+    {
+        OutBuffer buf;
+        auto resolvedArgs = tf.type.isTypeFunction().resolveNamedArgs(argumentList, &buf);
+        if (!resolvedArgs && buf.length)
+            .errorSupplemental(loc, "%s", buf.peekChars());
+    }
+}
+
+/******************************************
+ * Check for named argument errors in overload sets and report them.
+ * Params:
+ *      od = overload declaration to check
+ *      argumentList = arguments to check
+ *      loc = location for error report
+ */
+private void checkNamedArgErrorAndReportOverload(Dsymbol od, ArgumentList argumentList, Loc loc)
+{
+    if (!argumentList.hasArgNames())
+        return;
+
+    FuncDeclaration tf = null;
+    overloadApply(od, (Dsymbol s) {
+        if (!tf)
+        {
+            if (auto fd = s.isFuncDeclaration())
+                tf = fd;
+            else if (auto td = s.isTemplateDeclaration())
+                if (td.onemember)
+                    tf = td.onemember.isFuncDeclaration();
+        }
+        return 0;
+    });
+
+    if (tf && tf.type && tf.type.ty == Tfunction)
+    {
+        OutBuffer buf;
+        auto resolvedArgs = tf.type.isTypeFunction().resolveNamedArgs(argumentList, &buf);
+        if (!resolvedArgs && buf.length)
+            .errorSupplemental(loc, "%s", buf.peekChars());
+    }
+}
+
 /*******************************************
  * Prints template and function overload candidates as supplemental errors.
  * Params:
@@ -2050,16 +2229,17 @@ int overrides(FuncDeclaration fd1, FuncDeclaration fd2)
  * Params:
  *  f = first function
  *  g = second function
- *  names = names of parameters
+ *  names = argument Labels of parameters(name and location of the name)
  * Returns:
  *      match   'this' is at least as specialized as g
  *      0       g is more specialized than 'this'
  */
-MATCH leastAsSpecialized(FuncDeclaration f, FuncDeclaration g, Identifiers* names)
+MATCH leastAsSpecialized(FuncDeclaration f, FuncDeclaration g, ArgumentLabels* names)
 {
     enum LOG_LEASTAS = 0;
     static if (LOG_LEASTAS)
     {
+        Identifiers *names = extractNames(names);
         import core.stdc.stdio : printf;
         printf("leastAsSpecialized(%s, %s, %s)\n", f.toChars(), g.toChars(), names ? names.toChars() : "null");
         printf("%s, %s\n", f.type.toChars(), g.type.toChars());
@@ -3566,3 +3746,99 @@ extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg, Sco
     }
     return overloadApplyRecurse(fstart, dg, sc);
 }
+
+Dsymbol isUnique(OverDeclaration od)
+{
+    Dsymbol result = null;
+    overloadApply(od.aliassym, (Dsymbol s)
+    {
+        if (result)
+        {
+            result = null;
+            return 1; // ambiguous, done
+        }
+        else
+        {
+            result = s;
+            return 0;
+        }
+    });
+    return result;
+}
+
+/************************************
+* Check to see if this variable is actually in an enclosing function
+* rather than the current one.
+* Update nestedrefs[], closureVars[] and outerVars[].
+* Returns: true if error occurs.
+*/
+extern (D) bool checkNestedReference(VarDeclaration vd, Scope* sc, Loc loc)
+{
+    //printf("VarDeclaration::checkNestedReference() %s\n", toChars());
+    if (sc.intypeof == 1 || sc.ctfe)
+        return false;
+    if (!vd.parent || vd.parent == sc.parent)
+        return false;
+    if (vd.isDataseg() || (vd.storage_class & STC.manifest))
+        return false;
+
+    // The current function
+    FuncDeclaration fdthis = sc.parent.isFuncDeclaration();
+    if (!fdthis)
+        return false; // out of function scope
+
+    Dsymbol p = vd.toParent2();
+
+    // Function literals from fdthis to p must be delegates
+    ensureStaticLinkTo(fdthis, p);
+
+    // The function that this variable is in
+    FuncDeclaration fdv = p.isFuncDeclaration();
+    if (!fdv || fdv == fdthis)
+        return false;
+
+    // Add fdthis to nestedrefs[] if not already there
+    if (!vd.nestedrefs.contains(fdthis))
+        vd.nestedrefs.push(fdthis);
+
+    //printf("\tfdv = %s\n", fdv.toChars());
+    //printf("\tfdthis = %s\n", fdthis.toChars());
+    if (loc.isValid())
+    {
+        if (fdthis.getLevelAndCheck(loc, sc, fdv, vd) == fdthis.LevelError)
+            return true;
+    }
+
+    // Add this VarDeclaration to fdv.closureVars[] if not already there
+    if (!sc.intypeof && !sc.traitsCompiles &&
+        // https://issues.dlang.org/show_bug.cgi?id=17605
+        (fdv.skipCodegen || !fdthis.skipCodegen))
+    {
+        if (!fdv.closureVars.contains(vd))
+            fdv.closureVars.push(vd);
+    }
+
+    if (!fdthis.outerVars.contains(vd))
+        fdthis.outerVars.push(vd);
+
+    //printf("fdthis is %s\n", fdthis.toChars());
+    //printf("var %s in function %s is nested ref\n", toChars(), fdv.toChars());
+    // __dollar creates problems because it isn't a real variable
+    // https://issues.dlang.org/show_bug.cgi?id=3326
+    if (vd.ident == Id.dollar)
+    {
+        .error(loc, "cannnot use `$` inside a function literal");
+        return true;
+    }
+    if (vd.ident == Id.withSym) // https://issues.dlang.org/show_bug.cgi?id=1759
+    {
+        ExpInitializer ez = vd._init.isExpInitializer();
+        assert(ez);
+        Expression e = ez.exp;
+        if (e.op == EXP.construct || e.op == EXP.blit)
+            e = (cast(AssignExp)e).e2;
+        return lambdaCheckForNestedRef(e, sc);
+    }
+
+    return false;
+}
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index 61ff273c6b79..0f8c8c67b927 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -2724,6 +2724,12 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt
 
     void visitComma(CommaExp e)
     {
+        if (e.originalExp !is null)
+        {
+            e.originalExp.expressionPrettyPrint(buf, hgs);
+            return;
+        }
+
         // CommaExp is generated by the compiler so it shouldn't
         // appear in error messages or header files.
         // For now, this treats the case where the compiler
@@ -3695,9 +3701,9 @@ private void parameterToBuffer(Parameter p, ref OutBuffer buf, ref HdrGenState h
  *     buf = buffer to write to
  *     hgs = context
  *     basis = replace `null`s in argument list with this expression (for sparse array literals)
- *     names = if non-null, use these as the names for the arguments
+ *     names = if non-null, use these as the argument Labels for the arguments
  */
-private void argsToBuffer(Expressions* expressions, ref OutBuffer buf, ref HdrGenState hgs, Expression basis = null, Identifiers* names = null)
+private void argsToBuffer(Expressions* expressions, ref OutBuffer buf, ref HdrGenState hgs, Expression basis = null, ArgumentLabels* names = null)
 {
     if (!expressions || !expressions.length)
         return;
@@ -3708,9 +3714,9 @@ private void argsToBuffer(Expressions* expressions, ref OutBuffer buf, ref HdrGe
             if (i)
                 buf.writestring(", ");
 
-            if (names && i < names.length && (*names)[i])
+            if (names && i < names.length && (*names)[i].name)
             {
-                buf.writestring((*names)[i].toString());
+                buf.writestring((*names)[i].name.toString());
                 buf.writestring(": ");
             }
             if (!el)
diff --git a/gcc/d/dmd/iasmgcc.d b/gcc/d/dmd/iasmgcc.d
index 3d6e6ab5b511..4d9a758bb471 100644
--- a/gcc/d/dmd/iasmgcc.d
+++ b/gcc/d/dmd/iasmgcc.d
@@ -69,7 +69,7 @@ public Statement gccAsmSemantic(GccAsmStatement s, Scope* sc)
     s.insn = semanticString(sc, s.insn, "asm instruction template");
 
     if (s.labels && s.outputargs)
-        error(s.loc, "extended asm statements with labels cannot have output constraints");
+        p.eSink.error(s.loc, "extended asm statements with labels cannot have output constraints");
 
     // Analyse all input and output operands.
     if (s.args)
@@ -143,6 +143,35 @@ public void gccAsmSemantic(CAsmDeclaration ad, Scope* sc)
 
 private:
 
+/***********************************
+ * Parse an expression that evaluates to a string.
+ * Grammar:
+ *      | AsmStringExpr:
+ *      |     StringLiteral
+ *      |     ( AssignExpression )
+ * Params:
+ *      p = parser state
+ * Returns:
+ *      the parsed string expression
+ */
+Expression parseAsmString(Parser)(Parser p)
+{
+    if (p.token.value == TOK.leftParenthesis)
+    {
+        p.nextToken();
+        Expression insn = p.parseAssignExp();
+        p.check(TOK.rightParenthesis);
+        return insn;
+    }
+    else if (p.token.value != TOK.string_)
+    {
+        p.eSink.error(p.token.loc, "expected string literal or expression in parentheses");
+        return ErrorExp.get();
+    }
+
+    return p.parsePrimaryExp();
+}
+
 /***********************************
  * Parse list of extended asm input or output operands.
  * Grammar:
@@ -202,7 +231,7 @@ int parseExtAsmOperands(Parser)(Parser p, GccAsmStatement s)
                 if (p.token.value != TOK.leftParenthesis)
                 {
                     arg = p.parseAssignExp();
-                    error(arg.loc, "`%s` must be surrounded by parentheses", arg.toChars());
+                    p.eSink.error(arg.loc, "`%s` must be surrounded by parentheses", arg.toChars());
                 }
                 else
                 {
@@ -352,13 +381,13 @@ Lerror:
  *      |     GotoAsmInstruction
  *      |
  *      | BasicAsmInstruction:
- *      |     AssignExpression
+ *      |     AsmStringExpr
  *      |
  *      | ExtAsmInstruction:
- *      |     AssignExpression : Operands(opt) : Operands(opt) : Clobbers(opt)
+ *      |     AsmStringExpr : Operands(opt) : Operands(opt) : Clobbers(opt)
  *      |
  *      | GotoAsmInstruction:
- *      |     AssignExpression : : Operands(opt) : Clobbers(opt) : GotoLabels(opt)
+ *      |     AsmStringExpr : : Operands(opt) : Clobbers(opt) : GotoLabels(opt)
  * Params:
  *      p = parser state
  *      s = asm statement to parse
@@ -367,7 +396,10 @@ Lerror:
  */
 GccAsmStatement parseGccAsm(Parser)(Parser p, GccAsmStatement s)
 {
-    s.insn = p.parseAssignExp();
+    s.insn = p.parseAsmString();
+    if (s.insn.isErrorExp())
+        return s;
+
     if (p.token.value == TOK.semicolon || p.token.value == TOK.endOfFile)
         goto Ldone;
 
@@ -519,11 +551,11 @@ unittest
         } },
 
         // Any CTFE-able string allowed as instruction template.
-        q{ asm { generateAsm();
+        q{ asm { (generateAsm);
         } },
 
         // Likewise mixins, permissible so long as the result is a string.
-        q{ asm { mixin(`"repne"`, `~ "scasb"`);
+        q{ asm { (mixin(`"repne"`, `~ "scasb"`));
         } },
 
         // :: token tests
@@ -557,6 +589,11 @@ unittest
 
         // https://issues.dlang.org/show_bug.cgi?id=20593
         q{ asm { "instruction" : : "operand" 123; } },
+
+        // https://github.com/dlang/dmd/issues/21298
+        q{ asm { 1; }   },
+        q{ asm { int; } },
+        q{ asm { : "=r" (i); } },
     ];
 
     foreach (test; passAsmTests)
diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d
index e1c22f2f04ca..2d10e6f991af 100644
--- a/gcc/d/dmd/id.d
+++ b/gcc/d/dmd/id.d
@@ -324,7 +324,6 @@ immutable Msgtable[] msgtable =
     { "__switch_error"},
     { "__ArrayCast"},
     { "_d_HookTraceImpl" },
-    { "_d_arraysetlengthTImpl"},
     { "_d_arraysetlengthT"},
     { "_d_arraysetlengthTTrace"},
     { "_d_arrayappendT" },
diff --git a/gcc/d/dmd/imphint.d b/gcc/d/dmd/imphint.d
index 382a0f378633..e22bcc8b123f 100644
--- a/gcc/d/dmd/imphint.d
+++ b/gcc/d/dmd/imphint.d
@@ -26,8 +26,15 @@ const(char)[] importHint(const(char)[] s) @safe
         return *entry;
     return null;
 }
+const(char)[] cIncludeHint(const(char)[] s) @safe
+{
+    if (auto entry = s in cHints)
+        return *entry;
+    return null;
+}
 
 private immutable string[string] hints;
+private immutable string[string] cHints;
 
 shared static this()
 {
@@ -83,6 +90,23 @@ shared static this()
         "InterpolationHeader": "core.interpolation",
         "InterpolationFooter": "core.interpolation",
     ];
+    cHints = [
+        "NULL": "<stddef.h>",
+        "calloc": "<stdlib.h>",
+        "fopen": "<stdio.h>",
+        "fprintf": "<stdio.h>",
+        "free": "<stdlib.h>",
+        "malloc": "<stdlib.h>",
+        "memcpy": "<string.h>",
+        "memmove": "<string.h>",
+        "memset": "<string.h>",
+        "printf": "<stdio.h>",
+        "ptrdiff_t": "<stddef.h>",
+        "size_t": "<stddef.h>",
+        "stderr": "<stdio.h>",
+        "stdin": "<stdio.h>",
+        "stdout": "<stdio.h>",
+    ];
 }
 
 unittest
diff --git a/gcc/d/dmd/importc.d b/gcc/d/dmd/importc.d
index 2f88a21c049f..059de62b1f9c 100644
--- a/gcc/d/dmd/importc.d
+++ b/gcc/d/dmd/importc.d
@@ -17,16 +17,22 @@ import core.stdc.stdio;
 
 import dmd.astenums;
 import dmd.dcast;
+import dmd.denum;
 import dmd.declaration;
 import dmd.dscope;
 import dmd.dsymbol;
 import dmd.dsymbolsem;
+import dmd.dinterpret : ctfeInterpret;
 import dmd.errors;
 import dmd.expression;
 import dmd.expressionsem;
 import dmd.identifier;
+import dmd.id : Id;
 import dmd.init;
+import dmd.intrange : IntRange;
 import dmd.mtype;
+import dmd.optimize : optimize;
+import dmd.rootobject : DYNCAST;
 import dmd.tokens;
 import dmd.typesem;
 
@@ -120,6 +126,12 @@ Expression fieldLookup(Expression e, Scope* sc, Identifier id, bool arrow)
     e = e.expressionSemantic(sc);
     if (e.isErrorExp())
         return e;
+    if (arrow)
+    {
+        e = arrayFuncConv(e, sc);
+        if (e.isErrorExp())
+            return e;
+    }
 
     auto t = e.type;
     if (t.isTypePointer())
@@ -532,11 +544,17 @@ Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsy
         }
     }
 
+    // Don't let macros shadow real symbols
+    if (auto td = s.isTemplateDeclaration())
+    {
+        if (td.isCmacro) return s2;
+    }
+
     auto vd = s.isVarDeclaration(); // new declaration
     auto vd2 = s2.isVarDeclaration(); // existing declaration
 
     if (vd && vd.isCmacro())
-        return vd2;
+        return s2;
 
     assert(!(vd2 && vd2.isCmacro()));
 
@@ -638,3 +656,115 @@ Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsy
 
     return collision();
 }
+
+/*********************************
+ * ImportC-specific semantic analysis on enum declaration `ed`
+ */
+void cEnumSemantic(Scope* sc, EnumDeclaration ed)
+{
+    // C11 6.7.2.2
+    Type commonType = ed.memtype;
+    if (!commonType)
+        commonType = Type.tint32;
+    ulong nextValue = 0;        // C11 6.7.2.2-3 first member value defaults to 0
+
+    // C11 6.7.2.2-2 value must be representable as an int.
+    // The sizemask represents all values that int will fit into,
+    // from 0..uint.max.  We want to cover int.min..uint.max.
+    IntRange ir = IntRange.fromType(commonType);
+
+    void emSemantic(EnumMember em, ref ulong nextValue)
+    {
+        static void errorReturn(EnumMember em)
+        {
+            em.value = ErrorExp.get();
+            em.errors = true;
+            em.semanticRun = PASS.semanticdone;
+        }
+
+        em.semanticRun = PASS.semantic;
+        em.type = commonType;
+        em._linkage = LINK.c;
+        em.storage_class |= STC.manifest;
+        if (em.value)
+        {
+            Expression e = em.value;
+            assert(e.dyncast() == DYNCAST.expression);
+
+            /* To merge the type of e with commonType, add 0 of type commonType
+                */
+            if (!ed.memtype)
+                e = new AddExp(em.loc, e, new IntegerExp(em.loc, 0, commonType));
+
+            e = e.expressionSemantic(sc);
+            e = resolveProperties(sc, e);
+            e = e.integralPromotions(sc);
+            e = e.ctfeInterpret();
+            if (e.op == EXP.error)
+                return errorReturn(em);
+            auto ie = e.isIntegerExp();
+            if (!ie)
+            {
+                // C11 6.7.2.2-2
+                .error(em.loc, "%s `%s` enum member must be an integral constant expression, not `%s` of type `%s`", em.kind, em.toPrettyChars, e.toChars(), e.type.toChars());
+                return errorReturn(em);
+            }
+            if (ed.memtype && !ir.contains(getIntRange(ie)))
+            {
+                // C11 6.7.2.2-2
+                .error(em.loc, "%s `%s` enum member value `%s` does not fit in `%s`", em.kind, em.toPrettyChars, e.toChars(), commonType.toChars());
+                return errorReturn(em);
+            }
+            nextValue = ie.toInteger();
+            if (!ed.memtype)
+                commonType = e.type;
+            em.value = new IntegerExp(em.loc, nextValue, commonType);
+        }
+        else
+        {
+            // C11 6.7.2.2-3 add 1 to value of previous enumeration constant
+            bool first = (em == (*em.ed.members)[0]);
+            if (!first)
+            {
+                Expression max = getProperty(commonType, null, em.loc, Id.max, 0);
+                if (nextValue == max.toInteger())
+                {
+                    .error(em.loc, "%s `%s` initialization with `%s+1` causes overflow for type `%s`", em.kind, em.toPrettyChars, max.toChars(), commonType.toChars());
+                    return errorReturn(em);
+                }
+                nextValue += 1;
+            }
+            em.value = new IntegerExp(em.loc, nextValue, commonType);
+        }
+        em.type = commonType;
+        em.semanticRun = PASS.semanticdone;
+    }
+
+    ed.members.foreachDsymbol( (s)
+    {
+        if (EnumMember em = s.isEnumMember())
+            emSemantic(em, nextValue);
+    });
+
+    if (!ed.memtype)
+    {
+        // cast all members to commonType
+        ed.members.foreachDsymbol( (s)
+        {
+            if (EnumMember em = s.isEnumMember())
+            {
+                em.type = commonType;
+                // optimize out the cast so that other parts of the compiler can
+                // assume that an integral enum's members are `IntegerExp`s.
+                // https://issues.dlang.org/show_bug.cgi?id=24504
+                em.value = em.value.castTo(sc, commonType).optimize(WANTvalue);
+            }
+        });
+    }
+
+    ed.memtype = commonType;
+    // Set semantic2done to mark C enums as fully processed
+    // Prevents issues with final switch statements that reference C enums
+    ed.semanticRun = PASS.semantic2done;
+    return;
+}
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index 1ebccf77ee32..7247d7479746 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -153,7 +153,10 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn
             // that is not disabled.
             if (sd.hasRegularCtor(true))
             {
-                error(i.loc, "%s `%s` has constructors, cannot use `{ initializers }`, use `%s( initializers )` instead", sd.kind(), sd.toChars(), sd.toChars());
+                error(i.loc, "Cannot use %s initializer syntax for %s `%s` because it has a constructor",
+                    sd.kind(), sd.kind(), sd.toChars());
+                errorSupplemental(i.loc, "Use `%s( arguments )` instead of `{ initializers }`",
+                    sd.toChars());
                 return err();
             }
             sd.size(i.loc);
@@ -171,7 +174,8 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn
                 return ex;
             }
 
-            auto elements = resolveStructLiteralNamedArgs(sd, t, sc, i.loc, i.field[], &getExp, (size_t j) => i.value[j].loc);
+            auto elements = resolveStructLiteralNamedArgs(sd, t, sc, i.loc, i.field.length, (size_t j) => i.field[j], &getExp, (size_t j) => i.value[j].loc, (size_t j) => i.value[j].loc);
+            //Keeping both the getArgLoc and getNameLoc same as i.field doesn't have a .loc value here.
             if (!elements)
                 return err();
 
@@ -240,6 +244,9 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn
                 goto default;
             break;
 
+        case Terror:
+            return err();
+
         default:
             error(i.loc, "cannot use array to initialize `%s`", t.toChars());
             return err();
@@ -394,7 +401,10 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn
             if (needInterpret)
                 i.exp = i.exp.ctfeInterpret();
             if (i.exp.op == EXP.voidExpression)
-                error(i.loc, "variables cannot be initialized with an expression of type `void`. Use `void` initialization instead.");
+            {
+                error(i.loc, "variables cannot be initialized with an expression of type `void`");
+                errorSupplemental(i.loc, "only `= void;` is allowed, which prevents default initialization");
+            }
         }
         else
         {
@@ -755,9 +765,13 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn
                 // C11 6.2.5-20 "element type shall be complete whenever the array type is specified"
                 assert(0); // should have been detected by parser
             }
+            auto bt = tsa.nextOf().toBasetype();
 
-            auto tnsa = tsa.nextOf().toBasetype().isTypeSArray();
-
+            if (auto tnss = bt.isTypeStruct())
+            {
+                return subStruct(tnss, index);
+            }
+            auto tnsa = bt.isTypeSArray();
             auto ai = new ArrayInitializer(ci.loc);
             ai.isCarray = true;
 
@@ -1505,15 +1519,18 @@ Params:
     t = type of struct (potentially including qualifiers such as `const` or `immutable`)
     sc = scope of the expression initializing the struct
     iloc = location of expression initializing the struct
-    names = identifiers passed in argument list, `null` entries for positional arguments
-    getExp = function that, given an index into `names` and destination type, returns the initializing expression
-    getLoc = function that, given an index into `names`, returns a location for error messages
+    argCount = count of argumnet present
+    getExp = function that, given an index into `argNames` and destination type, returns the initializing expression
+    getArgName = function that, given an index into `argNames`, returns the name of argument for error messages
+    getArgLoc = function that, given an index into `argNames`, returns a location of argument for error messages
+    getNameLoc = function that, given an index into `argNames`, returns a location of that `name` for error messages
 
 Returns: list of expressions ordered to the struct's fields, or `null` on error
 */
 Expressions* resolveStructLiteralNamedArgs(StructDeclaration sd, Type t, Scope* sc,
-    Loc iloc, Identifier[] names, scope Expression delegate(size_t i, Type fieldType) getExp,
-    scope Loc delegate(size_t i) getLoc
+    Loc iloc, size_t argCount, scope Identifier delegate(size_t i) getArgName, scope Expression delegate(size_t i, Type fieldType) getExp,
+    scope Loc delegate(size_t i) getArgLoc,
+    scope Loc delegate(size_t i) getNameLoc
 )
 {
     //expandTuples for non-identity arguments?
@@ -1527,9 +1544,11 @@ Expressions* resolveStructLiteralNamedArgs(StructDeclaration sd, Type t, Scope*
     // TODO: this part is slightly different from StructLiteralExp::semantic.
     bool errors = false;
     size_t fieldi = 0;
-    foreach (j, id; names)
+    foreach (j; 0 .. argCount)
     {
-        const argLoc = getLoc(j);
+        const argLoc = getArgLoc(j);
+        const nameLoc = getNameLoc(j);
+        Identifier id = getArgName(j);
         if (id)
         {
             // Determine `fieldi` that `id` matches
@@ -1538,9 +1557,9 @@ Expressions* resolveStructLiteralNamedArgs(StructDeclaration sd, Type t, Scope*
             {
                 s = sd.search_correct(id);
                 if (s)
-                    error(argLoc, "`%s` is not a member of `%s`, did you mean %s `%s`?", id.toChars(), sd.toChars(), s.kind(), s.toChars());
+                    error(nameLoc, "`%s` is not a member of `%s`, did you mean %s `%s`?", id.toChars(), sd.toChars(), s.kind(), s.toChars());
                 else
-                    error(argLoc, "`%s` is not a member of `%s`", id.toChars(), sd.toChars());
+                    error(nameLoc, "`%s` is not a member of `%s`", id.toChars(), sd.toChars());
                 return null;
             }
             s.checkDeprecated(iloc, sc);
diff --git a/gcc/d/dmd/location.d b/gcc/d/dmd/location.d
index 393ffb8a92d4..daff06f3d2c6 100644
--- a/gcc/d/dmd/location.d
+++ b/gcc/d/dmd/location.d
@@ -48,6 +48,15 @@ struct Loc
 
 nothrow:
 
+    /// Reset global (Base)Loc tables, invalidating every existing `Loc` out there
+    /// and giving room to create new `Loc`s
+    static void _init()
+    {
+        locIndex = 1;
+        locFileTable = null;
+        lastFileTableIndex = 0;
+    }
+
     /*******************************
      * Configure how display is done
      * Params:
@@ -282,9 +291,7 @@ private size_t fileTableIndex(uint index) nothrow @nogc
     // To speed up linear find, we cache the last hit and compare that first,
     // since usually we stay in the same file for some time when resolving source locations.
     // If it's a different file now, either scan forwards / backwards
-    __gshared size_t lastI = 0; // index of last found hit
-
-    size_t i = lastI;
+    size_t i = lastFileTableIndex;
     if (index >= locFileTable[i].startIndex)
     {
         while (i + 1 < locFileTable.length && index >= locFileTable[i+1].startIndex)
@@ -296,7 +303,7 @@ private size_t fileTableIndex(uint index) nothrow @nogc
             i--;
     }
 
-    lastI = i;
+    lastFileTableIndex = i;
     return i;
 }
 
@@ -364,6 +371,11 @@ struct BaseLoc
     uint[] lines; /// For each line, the file offset at which it starts. At index 0 there's always a 0 entry.
     BaseLoc[] substitutions; /// Substitutions from #line / #file directives
 
+    /// Cache for the last line lookup
+    private size_t lastLineIndex = 0;
+    /// Cache for the last substitution lookup
+    private size_t lastSubstIndex = 0;
+
     /// Register that a new line starts at `offset` bytes from the start of the source file
     void newLine(uint offset)
     {
@@ -419,8 +431,61 @@ struct BaseLoc
 
     private size_t getSubstitutionIndex(uint offset) @nogc
     {
+        if (substitutions.length <= 1)
+            return 0;
+
+        // Check if the offset falls within the current cached substitution or the next one
+        if (lastSubstIndex < substitutions.length - 1)
+        {
+            // For the current substitution's range
+            if (substitutions[lastSubstIndex].startIndex <= offset &&
+                (lastSubstIndex == substitutions.length - 1 ||
+                 substitutions[lastSubstIndex + 1].startIndex > offset))
+                return lastSubstIndex;
+
+            // For the next substitution's range
+            if (lastSubstIndex + 1 < substitutions.length - 1 &&
+                substitutions[lastSubstIndex + 1].startIndex <= offset &&
+                substitutions[lastSubstIndex + 2].startIndex > offset)
+            {
+                lastSubstIndex++;
+                return lastSubstIndex;
+            }
+
+            // For the previous substitution's range
+            if (lastSubstIndex > 0 &&
+                substitutions[lastSubstIndex - 1].startIndex <= offset &&
+                substitutions[lastSubstIndex].startIndex > offset)
+            {
+                lastSubstIndex--;
+                return lastSubstIndex;
+            }
+        }
+        else if (lastSubstIndex == substitutions.length - 1 &&
+                 substitutions[lastSubstIndex].startIndex <= offset)
+        {
+            // Last substitution case
+            return lastSubstIndex;
+        }
+
+        // Fall back to binary search, but start near
         size_t lo = 0;
-        size_t hi = substitutions.length + -1;
+        size_t hi = substitutions.length - 1;
+
+        // Adjust the range based on the offset relative to lastSubstIndex
+        if (offset < substitutions[lastSubstIndex].startIndex)
+        {
+            // Search backward
+            lo = 0;
+            hi = lastSubstIndex;
+        }
+        else
+        {
+            // Search forward
+            lo = lastSubstIndex;
+            hi = substitutions.length - 1;
+        }
+
         size_t mid = 0;
         while (lo <= hi)
         {
@@ -428,7 +493,10 @@ struct BaseLoc
             if (substitutions[mid].startIndex <= offset)
             {
                 if (mid == substitutions.length - 1 || substitutions[mid + 1].startIndex > offset)
+                {
+                    lastSubstIndex = mid; // Update cache
                     return mid;
+                }
 
                 lo = mid + 1;
             }
@@ -441,10 +509,51 @@ struct BaseLoc
     }
 
     /// Binary search the index in `this.lines` corresponding to `offset`
+    /// lastLineIndex cache to avoid full binary search when possible
     private size_t getLineIndex(uint offset) @nogc
     {
+        if (lines.length <= 1)
+            return 0;
+
+        if (lastLineIndex < lines.length - 1)
+        {
+            if (lines[lastLineIndex] <= offset && offset < lines[lastLineIndex + 1])
+                return lastLineIndex;
+
+            if (lastLineIndex + 1 < lines.length - 1 &&
+                lines[lastLineIndex + 1] <= offset && offset < lines[lastLineIndex + 2])
+            {
+                lastLineIndex++;
+                return lastLineIndex;
+            }
+
+            if (lastLineIndex > 0 &&
+                lines[lastLineIndex - 1] <= offset && offset < lines[lastLineIndex])
+            {
+                lastLineIndex--;
+                return lastLineIndex;
+            }
+        }
+        else if (lastLineIndex == lines.length - 1 && lines[lastLineIndex] <= offset)
+        {
+            return lastLineIndex;
+        }
+
+        // Fall back to binary search
         size_t lo = 0;
-        size_t hi = lines.length + -1;
+        size_t hi = lines.length - 1;
+
+        if (offset < lines[lastLineIndex])
+        {
+            lo = 0;
+            hi = lastLineIndex;
+        }
+        else
+        {
+            lo = lastLineIndex;
+            hi = lines.length - 1;
+        }
+
         size_t mid = 0;
         while (lo <= hi)
         {
@@ -452,7 +561,10 @@ struct BaseLoc
             if (lines[mid] <= offset)
             {
                 if (mid == lines.length - 1 || lines[mid + 1] > offset)
+                {
+                    lastLineIndex = mid; // Update cache
                     return mid;
+                }
 
                 lo = mid + 1;
             }
@@ -470,3 +582,6 @@ private __gshared uint locIndex = 1;
 
 // Global mapping of Loc indices to source file offset/line/column, see `BaseLoc`
 private __gshared BaseLoc*[] locFileTable;
+
+// Index of last found hit in locFileTable, for optimization
+private __gshared size_t lastFileTableIndex = 0;
diff --git a/gcc/d/dmd/mangle/package.d b/gcc/d/dmd/mangle/package.d
index 3ad2c7d57941..cc797614ed0b 100644
--- a/gcc/d/dmd/mangle/package.d
+++ b/gcc/d/dmd/mangle/package.d
@@ -1339,7 +1339,11 @@ extern (D) const(char)[] externallyMangledIdentifier(Declaration d)
     const par = d.toParent(); //toParent() skips over mixin templates
     if (!par || par.isModule() || linkage == LINK.cpp ||
         (linkage == LINK.c && d.isCsymbol() &&
-         (d.isFuncDeclaration() ||
+         // https://github.com/dlang/dmd/issues/21241
+         // Static check is so C static functions get a unique mangle so the linker
+         // won't merge them if compiling all-at-once.
+         // Non-static functions can use their ident as their mangle.
+         ((d.isFuncDeclaration() && !d.isStatic()) ||
           (d.isVarDeclaration() && d.isDataseg() && d.storage_class & STC.extern_))))
     {
         if (linkage != LINK.d && d.localNum)
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index a3e1a8ca858b..c9b57449658a 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -2234,7 +2234,7 @@ extern (C++) final class TypeSArray : TypeArray
         auto elements = new Expressions(d);
         foreach (ref e; *elements)
             e = null;
-        auto ae = new ArrayLiteralExp(Loc.initial, this, elementinit, elements);
+        auto ae = new ArrayLiteralExp(loc, this, elementinit, elements);
         return ae;
     }
 
@@ -2631,7 +2631,7 @@ extern (C++) final class TypeFunction : TypeNext
     extern(D) Expressions* resolveNamedArgs(ArgumentList argumentList, OutBuffer* buf)
     {
         Expression[] args = argumentList.arguments ? (*argumentList.arguments)[] : null;
-        Identifier[] names = argumentList.names ? (*argumentList.names)[] : null;
+        ArgumentLabel[] names = argumentList.names ? (*argumentList.names)[] : null;
         const nParams = parameterList.length(); // cached because O(n)
         auto newArgs = new Expressions(nParams);
         newArgs.zero();
@@ -2645,7 +2645,7 @@ extern (C++) final class TypeFunction : TypeNext
                 ci++;
                 continue;
             }
-            auto name = i < names.length ? names[i] : null;
+            auto name = i < names.length ? names[i].name : null;
             if (name)
             {
                 hasNamedArgs = true;
@@ -3761,6 +3761,7 @@ extern (C++) final class TypeTag : Type
     Loc loc;                /// location of declaration
     TOK tok;                /// TOK.struct_, TOK.union_, TOK.enum_
     structalign_t packalign; /// alignment of struct/union fields
+    Expressions* alignExps; /// alignment of struct itself
     Identifier id;          /// tag name identifier
     Type base;              /// base type for enums otherwise null
     Dsymbols* members;      /// members of struct, null if none
@@ -3770,7 +3771,7 @@ extern (C++) final class TypeTag : Type
                             ///   struct S { int a; } s1, *s2;
     MOD mod;                /// modifiers to apply after type is resolved (only MODFlags.const_ at the moment)
 
-    extern (D) this(Loc loc, TOK tok, Identifier id, structalign_t packalign, Type base, Dsymbols* members) @safe
+    extern (D) this(Loc loc, TOK tok, Identifier id, structalign_t packalign, Expressions* alignExps, Type base, Dsymbols* members) @safe
     {
         //printf("TypeTag ctor %s %p\n", id ? id.toChars() : "null".ptr, this);
         super(Ttag);
@@ -3778,6 +3779,7 @@ extern (C++) final class TypeTag : Type
         this.tok = tok;
         this.id = id;
         this.packalign = packalign;
+        this.alignExps = alignExps;
         this.base = base;
         this.members = members;
         this.mod = 0;
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index 4d1938f4a723..4d303acf3c3c 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -554,6 +554,8 @@ public:
     void isReturn(bool v);
     bool isReturnScope() const;
     void isReturnScope(bool v);
+    bool isRvalue() const;
+    void isRvalue(bool v);
     bool isScopeQual() const;
     void isScopeQual(bool v);
     bool isReturnInferred() const;
diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d
index f1494a409f6e..5e3c164acbb4 100644
--- a/gcc/d/dmd/nogc.d
+++ b/gcc/d/dmd/nogc.d
@@ -24,6 +24,7 @@ import dmd.dscope;
 import dmd.dtemplate : isDsymbol;
 import dmd.dsymbol : PASS;
 import dmd.errors;
+import dmd.escape;
 import dmd.expression;
 import dmd.func;
 import dmd.globals;
@@ -45,13 +46,15 @@ extern (C++) final class NOGCVisitor : StoppableVisitor
     alias visit = typeof(super).visit;
 public:
     FuncDeclaration f;
+    Scope* sc;
     bool checkOnly;     // don't print errors
     bool err;
     bool nogcExceptions; // -preview=dip1008 enabled
 
-    extern (D) this(FuncDeclaration f) scope @safe
+    extern (D) this(FuncDeclaration f, Scope* sc) scope @safe
     {
         this.f = f;
+        this.sc = sc;
     }
 
     void doCond(Expression exp)
@@ -86,6 +89,8 @@ public:
      */
     private bool setGC(Expression e, const(char)* msg)
     {
+        if (sc.debug_)
+            return false;
         if (checkOnly)
         {
             err = true;
@@ -119,10 +124,17 @@ public:
 
     override void visit(ArrayLiteralExp e)
     {
-        if (e.type.ty != Tarray || !e.elements || !e.elements.length || e.onstack)
+        if (e.type.toBasetype().isTypeSArray() || !e.elements || !e.elements.length || e.onstack)
             return;
         if (setGC(e, "this array literal"))
             return;
+
+        if (checkArrayLiteralEscape(*sc, e, false))
+        {
+            err = true;
+            return;
+        }
+
         f.printGCUsage(e.loc, "array literal may cause a GC allocation");
     }
 
@@ -208,9 +220,10 @@ public:
     }
 }
 
-Expression checkGC(Scope* sc, Expression e)
+Expression checkGC(Expression e, Scope* sc)
 {
-    if (sc.ctfeBlock)     // ignore GC in ctfe blocks
+    // printf("%s checkGC(%s)\n", e.loc.toChars, e.toChars);
+    if (e.gcPassDone || sc.ctfeBlock || sc.ctfe || sc.intypeof == 1 || !sc.func)
         return e;
 
     /* If betterC, allow GC to happen in non-CTFE code.
@@ -219,28 +232,20 @@ Expression checkGC(Scope* sc, Expression e)
      */
     const betterC = !global.params.useGC;
     FuncDeclaration f = sc.func;
-    if (e && e.op != EXP.error && f && sc.intypeof != 1 &&
-           (!sc.ctfe || betterC) &&
-           (f.type.ty == Tfunction &&
-            (cast(TypeFunction)f.type).isNogc || f.nogcInprocess || global.params.v.gc) &&
-           !sc.debug_)
-    {
-        scope NOGCVisitor gcv = new NOGCVisitor(f);
-        gcv.checkOnly = betterC;
-        gcv.nogcExceptions = sc.previews.dip1008;
-        walkPostorder(e, gcv);
-        if (gcv.err)
-        {
-            if (betterC)
-            {
-                /* Allow ctfe to use the gc code, but don't let it into the runtime
-                 */
-                f.skipCodegen = true;
-            }
-            else
-                return ErrorExp.get();
-        }
-    }
+    scope NOGCVisitor gcv = new NOGCVisitor(f, sc);
+    gcv.checkOnly = betterC && (f.type.isTypeFunction().isNogc || f.nogcInprocess);
+    gcv.nogcExceptions = sc.previews.dip1008;
+    walkPostorder(e, gcv);
+    e.gcPassDone = true;
+
+    if (!gcv.err)
+        return e;
+
+    if (!betterC)
+        return ErrorExp.get();
+
+    // Allow ctfe to use the gc code, but don't let it into the runtime
+    f.skipCodegen = true;
     return e;
 }
 
diff --git a/gcc/d/dmd/nspace.d b/gcc/d/dmd/nspace.d
index 0c93f0e7994a..b8116343d6fe 100644
--- a/gcc/d/dmd/nspace.d
+++ b/gcc/d/dmd/nspace.d
@@ -78,12 +78,6 @@ extern (C++) final class Nspace : ScopeDsymbol
         return ns;
     }
 
-    override bool hasPointers()
-    {
-        //printf("Nspace::hasPointers() %s\n", toChars());
-        return members.foreachDsymbol( (s) { return s.hasPointers(); } ) != 0;
-    }
-
     override const(char)* kind() const
     {
         return "namespace";
diff --git a/gcc/d/dmd/nspace.h b/gcc/d/dmd/nspace.h
index 7b4c302303da..782688b9de1c 100644
--- a/gcc/d/dmd/nspace.h
+++ b/gcc/d/dmd/nspace.h
@@ -21,7 +21,6 @@ class Nspace final : public ScopeDsymbol
   public:
     Expression *identExp;
     Nspace *syntaxCopy(Dsymbol *s) override;
-    bool hasPointers() override;
     const char *kind() const override;
     void accept(Visitor *v) override { v->visit(this); }
 };
diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d
index 66b8c6a4953c..b13f8c64584f 100644
--- a/gcc/d/dmd/optimize.d
+++ b/gcc/d/dmd/optimize.d
@@ -1072,7 +1072,8 @@ Expression optimize(Expression e, int result, bool keepLvalue = false)
         // All negative integral powers are illegal.
         if (e.e1.type.isIntegral() && (e.e2.op == EXP.int64) && cast(sinteger_t)e.e2.toInteger() < 0)
         {
-            error(e.loc, "cannot raise `%s` to a negative integer power. Did you mean `(cast(real)%s)^^%s` ?", e.e1.type.toBasetype().toChars(), e.e1.toChars(), e.e2.toChars());
+            error(e.loc, "cannot raise `%s` to a negative integer power.", e.e1.type.toBasetype().toChars());
+            errorSupplemental(e.loc, "did you mean `(cast(real)%s)^^%s` ?", e.e1.toChars(), e.e2.toChars());
             return errorReturn();
         }
         // If e2 *could* have been an integer, make it one.
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index e68017c87e55..c57f1d3f7f74 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -28,6 +28,7 @@ import dmd.root.rmem;
 import dmd.rootobject;
 import dmd.root.string;
 import dmd.tokens;
+import dmd.expression;
 
 alias CompileEnv = dmd.lexer.CompileEnv;
 
@@ -1319,12 +1320,26 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
             // Allow identifier, template instantiation, or function call
             // for `@Argument` (single UDA) form.
-            AST.Expression exp = parsePrimaryExp();
+            AST.Expression exp;
+
+            {
+                const loc = token.loc;
+                Identifier id = token.ident;
+                nextToken();
+                if (token.value == TOK.not)
+                {
+                    auto tempinst = new AST.TemplateInstance(loc, id, parseTemplateArguments());
+                    exp = new AST.ScopeExp(loc, tempinst);
+                }
+                else
+                    exp = new AST.IdentifierExp(loc, id);
+            }
+
             if (token.value == TOK.leftParenthesis)
             {
                 const loc = token.loc;
                 AST.Expressions* args = new AST.Expressions();
-                AST.Identifiers* names = new AST.Identifiers();
+                AST.ArgumentLabels* names = new AST.ArgumentLabels();
                 parseNamedArguments(args, names);
                 exp = new AST.CallExp(loc, exp, args, names);
             }
@@ -2758,7 +2773,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
             if (len > 0)
             {
                 docline = cast(char*)mem.xmalloc_noscan(len + 2);
-                memcpy(docline, begPtr, len);
+                docline[0 .. len] = begPtr[0 .. len];
                 docline[len] = '\n'; // Terminate all lines by LF
                 docline[len + 1] = '\0';
             }
@@ -4067,7 +4082,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                  */
                 if (isParameters(&peekt))
                 {
-                    error("function declaration without return type. (Note that constructors are always named `this`)");
+                    error("function declaration without return type");
+                    errorSupplemental("Note that constructors are always named `this`");
                 }
                 else
                     error("unexpected `(` in declarator");
@@ -7090,12 +7106,12 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
             case TOK.colonColon:  // treat as two separate : tokens for iasmgcc
                 *ptoklist = allocateToken();
-                memcpy(*ptoklist, &token, Token.sizeof);
+                **ptoklist = this.token;
                 (*ptoklist).value = TOK.colon;
                 ptoklist = &(*ptoklist).next;
 
                 *ptoklist = allocateToken();
-                memcpy(*ptoklist, &token, Token.sizeof);
+                **ptoklist = this.token;
                 (*ptoklist).value = TOK.colon;
                 ptoklist = &(*ptoklist).next;
 
@@ -7105,7 +7121,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
             default:
                 *ptoklist = allocateToken();
-                memcpy(*ptoklist, &token, Token.sizeof);
+                **ptoklist = this.token;
                 ptoklist = &(*ptoklist).next;
                 *ptoklist = null;
                 nextToken();
@@ -8249,9 +8265,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                         const len2 = token.len;
                         len = len1 + len2;
                         auto s2 = cast(char*)mem.xmalloc_noscan(len * char.sizeof);
-                        memcpy(s2, s, len1 * char.sizeof);
-                        memcpy(s2 + len1, token.ustring, len2 * char.sizeof);
-                        s = s2;
+                        s2[0 .. len1] = s[0 .. len1];
+                        s2[len1 .. len1 + len2] = token.ustring[0 .. len2];
                     }
                     else
                         break;
@@ -8454,10 +8469,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                     nextToken();
                     if (token.value == TOK.identifier && peekNext() == TOK.leftParenthesis)
                     {
-                        error(loc, "unexpected `(` after `%s`, inside `is` expression. Try enclosing the contents of `is` with a `typeof` expression", token.toChars());
+                        error(loc, "unexpected `(` after `%s`, inside `is` expression", token.toChars());
+                        errorSupplemental("try enclosing the contents of `is` with a `typeof` expression");
                         nextToken();
                         Token* tempTok = peekPastParen(&token);
-                        memcpy(&token, tempTok, Token.sizeof);
+                        token = *tempTok;
                         goto Lerr;
                     }
                     targ = parseType(&ident);
@@ -9006,7 +9022,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
             case TOK.leftParenthesis:
                 AST.Expressions* args = new AST.Expressions();
-                AST.Identifiers* names = new AST.Identifiers();
+                AST.ArgumentLabels* names = new AST.ArgumentLabels();
                 parseNamedArguments(args, names);
                 e = new AST.CallExp(loc, e, args, names);
                 continue;
@@ -9053,11 +9069,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
     private AST.Expression parseMulExp()
     {
-        const loc = token.loc;
         auto e = parseUnaryExp();
 
         while (1)
         {
+            const loc = token.loc;
             switch (token.value)
             {
             case TOK.mul:
@@ -9088,11 +9104,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
     private AST.Expression parseAddExp()
     {
-        const loc = token.loc;
         auto e = parseMulExp();
 
         while (1)
         {
+            const loc = token.loc;
             switch (token.value)
             {
             case TOK.add:
@@ -9123,11 +9139,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
     private AST.Expression parseShiftExp()
     {
-        const loc = token.loc;
         auto e = parseAddExp();
 
         while (1)
         {
+            const loc = token.loc;
             switch (token.value)
             {
             case TOK.leftShift:
@@ -9158,10 +9174,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
     private AST.Expression parseCmpExp()
     {
-        const loc = token.loc;
-
         auto e = parseShiftExp();
         EXP op = EXP.reserved;
+        const loc = token.loc;
 
         switch (token.value)
         {
@@ -9223,28 +9238,26 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
     private AST.Expression parseAndExp()
     {
-        Loc loc = token.loc;
         auto e = parseCmpExp();
         while (token.value == TOK.and)
         {
             checkParens(TOK.and, e);
+            const loc = token.loc;
             nextToken();
             auto e2 = parseCmpExp();
             checkParens(TOK.and, e2);
             e = new AST.AndExp(loc, e, e2);
-            loc = token.loc;
         }
         return e;
     }
 
     private AST.Expression parseXorExp()
     {
-        const loc = token.loc;
-
         auto e = parseAndExp();
         while (token.value == TOK.xor)
         {
             checkParens(TOK.xor, e);
+            const loc = token.loc;
             nextToken();
             auto e2 = parseAndExp();
             checkParens(TOK.xor, e2);
@@ -9255,12 +9268,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
     private AST.Expression parseOrExp()
     {
-        const loc = token.loc;
-
         auto e = parseXorExp();
         while (token.value == TOK.or)
         {
             checkParens(TOK.or, e);
+            const loc = token.loc;
             nextToken();
             auto e2 = parseXorExp();
             checkParens(TOK.or, e2);
@@ -9271,11 +9283,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
     private AST.Expression parseAndAndExp()
     {
-        const loc = token.loc;
-
         auto e = parseOrExp();
         while (token.value == TOK.andAnd)
         {
+            const loc = token.loc;
             nextToken();
             auto e2 = parseOrExp();
             e = new AST.LogicalExp(loc, EXP.andAnd, e, e2);
@@ -9285,11 +9296,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
     private AST.Expression parseOrOrExp()
     {
-        const loc = token.loc;
-
         auto e = parseAndAndExp();
         while (token.value == TOK.orOr)
         {
+            const loc = token.loc;
             nextToken();
             auto e2 = parseAndAndExp();
             e = new AST.LogicalExp(loc, EXP.orOr, e, e2);
@@ -9299,11 +9309,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
     private AST.Expression parseCondExp()
     {
-        const loc = token.loc;
-
         auto e = parseOrOrExp();
         if (token.value == TOK.question)
         {
+            const loc = token.loc;
             nextToken();
             auto e1 = parseExpression();
             check(TOK.colon);
@@ -9452,7 +9461,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
      * Collect argument list.
      * Assume current token is ',', '$(LPAREN)' or '['.
      */
-    private void parseNamedArguments(AST.Expressions* arguments, AST.Identifiers* names)
+    private void parseNamedArguments(AST.Expressions* arguments, AST.ArgumentLabels* names)
     {
         assert(arguments);
 
@@ -9470,14 +9479,14 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
                 check(TOK.identifier);
                 check(TOK.colon);
                 if (names)
-                    names.push(ident);
+                    names.push(ArgumentLabel(ident, loc));
                 else
                     error(loc, "named arguments not allowed here");
             }
             else
             {
                 if (names)
-                    names.push(null);
+                    names.push(ArgumentLabel(null, Loc.init));
             }
 
             auto arg = parseAssignExp();
@@ -9518,7 +9527,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
         }
 
         AST.Expressions* arguments = null;
-        AST.Identifiers* names = null;
+        AST.ArgumentLabels* names = null;
 
         // An anonymous nested class starts with "class"
         if (token.value == TOK.class_)
@@ -9527,7 +9536,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
             if (token.value == TOK.leftParenthesis)
             {
                 arguments = new AST.Expressions();
-                names = new AST.Identifiers();
+                names = new AST.ArgumentLabels();
                 parseNamedArguments(arguments, names);
             }
 
@@ -9572,7 +9581,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
         else if (token.value == TOK.leftParenthesis && t.ty != Tsarray)
         {
             arguments = new AST.Expressions();
-            names = new AST.Identifiers();
+            names = new AST.ArgumentLabels();
             parseNamedArguments(arguments, names);
         }
 
diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d
index 1c58e63936d7..26f0fa8a254f 100644
--- a/gcc/d/dmd/semantic2.d
+++ b/gcc/d/dmd/semantic2.d
@@ -287,7 +287,10 @@ private extern(C++) final class Semantic2Visitor : Visitor
                 }
 
                 if (hasInvalidEnumInitializer(ei.exp))
-                    .error(vd.loc, "%s `%s` : Unable to initialize enum with class or pointer to struct. Use static const variable instead.", vd.kind, vd.toPrettyChars);
+                {
+                    .error(vd.loc, "%s `%s` : Unable to initialize enum with class or pointer to struct", vd.kind, vd.toPrettyChars);
+                    .errorSupplemental(vd.loc, "use static const variable instead");
+                }
             }
         }
         else if (vd._init && vd.isThreadlocal())
@@ -298,13 +301,20 @@ private extern(C++) final class Semantic2Visitor : Visitor
             {
                 ExpInitializer ei = vd._init.isExpInitializer();
                 if (ei && ei.exp.op == EXP.classReference)
-                    .error(vd.loc, "%s `%s` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead.", vd.kind, vd.toPrettyChars);
+                {
+                    .error(vd.loc, "%s `%s` is a thread-local class and cannot have a static initializer", vd.kind, vd.toPrettyChars);
+                    .errorSupplemental(vd.loc, "use `static this()` to initialize instead");
+                }
             }
             else if (vd.type.ty == Tpointer && vd.type.nextOf().ty == Tstruct && vd.type.nextOf().isMutable() && !vd.type.nextOf().isShared())
             {
                 ExpInitializer ei = vd._init.isExpInitializer();
                 if (ei && ei.exp.op == EXP.address && (cast(AddrExp)ei.exp).e1.op == EXP.structLiteral)
-                    .error(vd.loc, "%s `%s` is a thread-local pointer to struct and cannot have a static initializer. Use `static this()` to initialize instead.", vd.kind, vd.toPrettyChars);
+                {
+                    .error(vd.loc, "%s `%s` is a thread-local pointer to struct and cannot have a static initializer", vd.kind, vd.toPrettyChars);
+                    .errorSupplemental(vd.loc, "use `static this()` to initialize instead");
+                }
+
             }
         }
         vd.semanticRun = PASS.semantic2done;
diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d
index a24af7bbbfcf..bafb2e7d8719 100644
--- a/gcc/d/dmd/semantic3.d
+++ b/gcc/d/dmd/semantic3.d
@@ -855,7 +855,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
                         if (tret.ty == Terror)
                         {
                             // https://issues.dlang.org/show_bug.cgi?id=13702
-                            exp = checkGC(sc2, exp);
+                            exp = exp.checkGC(sc2);
                             continue;
                         }
 
@@ -977,7 +977,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
                                 checkReturnEscape(*sc2, exp, false);
                         }
 
-                        exp = checkGC(sc2, exp);
+                        exp = exp.checkGC(sc2);
 
                         if (funcdecl.vresult)
                         {
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index 0c9b6becb700..523ed7b39781 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -219,7 +219,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
             s.exp = ErrorExp.get();
 
         s.exp = s.exp.optimize(WANTvalue);
-        s.exp = checkGC(sc, s.exp);
+        s.exp = s.exp.checkGC(sc);
         if (s.exp.op == EXP.error)
             return setError();
         result = s;
@@ -585,7 +585,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
         if (checkNonAssignmentArrayOp(ds.condition))
             ds.condition = ErrorExp.get();
         ds.condition = ds.condition.optimize(WANTvalue);
-        ds.condition = checkGC(sc, ds.condition);
+        ds.condition = ds.condition.checkGC(sc);
 
         ds.condition = ds.condition.toBoolean(sc);
 
@@ -658,7 +658,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
             if (checkNonAssignmentArrayOp(fs.condition))
                 fs.condition = ErrorExp.get();
             fs.condition = fs.condition.optimize(WANTvalue);
-            fs.condition = checkGC(sc, fs.condition);
+            fs.condition = fs.condition.checkGC(sc);
 
             fs.condition = fs.condition.toBoolean(sc);
         }
@@ -677,7 +677,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
             if (checkNonAssignmentArrayOp(fs.increment))
                 fs.increment = ErrorExp.get();
             fs.increment = fs.increment.optimize(WANTvalue);
-            fs.increment = checkGC(sc, fs.increment);
+            fs.increment = fs.increment.checkGC(sc);
         }
 
         sc.sbreak = fs;
@@ -1709,7 +1709,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
 
         // checkGC after optimizing the condition so that
         // compile time constants are reduced.
-        ifs.condition = checkGC(scd, ifs.condition);
+        ifs.condition = ifs.condition.checkGC(scd);
 
         // Save 'root' of two branches (then and else) at the point where it forks
         CtorFlow ctorflow_root = scd.ctorflow.clone();
@@ -1897,7 +1897,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
         if (checkNonAssignmentArrayOp(ss.condition))
             ss.condition = ErrorExp.get();
         ss.condition = ss.condition.optimize(WANTvalue);
-        ss.condition = checkGC(sc, ss.condition);
+        ss.condition = ss.condition.checkGC(sc);
         if (ss.condition.op == EXP.error)
             conditionError = true;
 
@@ -1959,6 +1959,16 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
                 ed = ds.isEnumDeclaration(); // typedef'ed enum
             if (!ed && te && ((ds = te.toDsymbol(sc)) !is null))
                 ed = ds.isEnumDeclaration();
+
+            // Circular references
+            // Check if enum semantic analysis is not yet complete
+            if (ed && ed.semanticRun < PASS.semantic2done)
+            {
+                error(ss.loc, "cannot use `final switch` on enum `%s` while it is being defined", ed.toChars());
+                sc.pop();
+                return setError();
+            }
+
             if (ed && ss.cases.length < ed.members.length)
             {
                 int missingMembers = 0;
@@ -2593,7 +2603,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
 
             if (tbret && tbret.ty == Tvoid || convToVoid)
             {
-                if (!convToVoid)
+                if (!convToVoid && !texp.isTypeError())
                 {
                     error(rs.loc, "cannot return non-void from `void` function");
                     errors = true;
@@ -2626,7 +2636,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
             if (e0)
             {
                 e0 = e0.optimize(WANTvalue);
-                e0 = checkGC(sc, e0);
+                e0 = e0.checkGC(sc);
             }
         }
 
@@ -3044,7 +3054,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
             ss.exp = ss.exp.expressionSemantic(sc);
             ss.exp = resolveProperties(sc, ss.exp);
             ss.exp = ss.exp.optimize(WANTvalue);
-            ss.exp = checkGC(sc, ss.exp);
+            ss.exp = ss.exp.checkGC(sc);
             if (ss.exp.op == EXP.error)
             {
                 if (ss._body)
@@ -3168,7 +3178,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
         ws.exp = ws.exp.expressionSemantic(sc);
         ws.exp = resolveProperties(sc, ws.exp);
         ws.exp = ws.exp.optimize(WANTvalue);
-        ws.exp = checkGC(sc, ws.exp);
+        ws.exp = ws.exp.checkGC(sc);
         if (ws.exp.op == EXP.error)
             return setError();
         if (ws.exp.op == EXP.scope_)
@@ -3730,7 +3740,7 @@ public bool throwSemantic(Loc loc, ref Expression exp, Scope* sc)
 
     exp = exp.expressionSemantic(sc);
     exp = resolveProperties(sc, exp);
-    exp = checkGC(sc, exp);
+    exp = exp.checkGC(sc);
     if (exp.isErrorExp())
         return false;
     if (!exp.type.isNaked())
diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h
index 5576965ce4b2..bfc415148043 100644
--- a/gcc/d/dmd/template.h
+++ b/gcc/d/dmd/template.h
@@ -71,6 +71,7 @@ public:
     d_bool isTrivialAliasSeq;     // matches `template AliasSeq(T...) { alias AliasSeq = T; }
     d_bool isTrivialAlias;        // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
     d_bool deprecated_;           // this template declaration is deprecated
+    d_bool isCmacro;              // Whether this template is a translation of a C macro
     Visibility visibility;
 
     TemplatePrevious *previous;         // threaded list of previous instantiation attempts on stack
@@ -284,7 +285,6 @@ public:
 
     TemplateMixin *syntaxCopy(Dsymbol *s) override;
     const char *kind() const override;
-    bool hasPointers() override;
 
     void accept(Visitor *v) override { v->visit(this); }
 };
diff --git a/gcc/d/dmd/templatesem.d b/gcc/d/dmd/templatesem.d
index e5efce4a8bcc..a9cf867f1147 100644
--- a/gcc/d/dmd/templatesem.d
+++ b/gcc/d/dmd/templatesem.d
@@ -188,7 +188,7 @@ void templateDeclarationSemantic(Scope* sc, TemplateDeclaration tempdecl)
     if (tempdecl.members)
     {
         Dsymbol s;
-        if (Dsymbol.oneMembers(tempdecl.members, s, tempdecl.ident) && s)
+        if (oneMembers(tempdecl.members, s, tempdecl.ident) && s)
         {
             tempdecl.onemember = s;
             s.parent = tempdecl;
@@ -948,7 +948,7 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat
         size_t nfargs2 = argumentList.length; // total number of arguments including applied defaultArgs
         uint inoutMatch = 0; // for debugging only
         Expression[] fargs = argumentList.arguments ? (*argumentList.arguments)[] : null;
-        Identifier[] fnames = argumentList.names ? (*argumentList.names)[] : null;
+        ArgumentLabel[] fnames = argumentList.names ? (*argumentList.names)[] : null;
 
         for (size_t parami = 0; parami < nfparams; parami++)
         {
@@ -958,16 +958,17 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat
             Type prmtype = fparam.type.addStorageClass(fparam.storageClass);
 
             Expression farg;
-            Identifier fname = argi < fnames.length ? fnames[argi] : null;
+            Identifier fname = argi < fnames.length ? fnames[argi].name : null;
             bool foundName = false;
             if (fparam.ident)
             {
                 foreach (i; 0 .. fnames.length)
                 {
-                    if (fparam.ident == fnames[i])
+                    if (fparam.ident == fnames[i].name)
                     {
                         argi = i;
                         foundName = true;
+                        break;  //Exits the loop after a match
                     }
                 }
             }
@@ -1002,9 +1003,9 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat
                         {
                             break;
                         }
-                        foreach(name; fnames)
+                        foreach(argLabel; fnames)
                         {
-                            if (p.ident == name)
+                            if (p.ident == argLabel.name)
                                 break;
                         }
                         if (!reliesOnTemplateParameters(p.type, (*td.parameters)[inferStart .. td.parameters.length]))
diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d
index 127a89d19842..8cce1732e87e 100644
--- a/gcc/d/dmd/traits.d
+++ b/gcc/d/dmd/traits.d
@@ -1847,7 +1847,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
                     const tf = sc2.func.type.isTypeFunction();
                     err |= tf.isNothrow && canThrow(ex, sc2.func, null);
                 }
-                ex = checkGC(sc2, ex);
+                ex = ex.checkGC(sc2);
                 if (ex.op == EXP.error)
                     err = true;
             }
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index d4c7a5865d25..ffbdfed6eb37 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -169,17 +169,28 @@ private void resolveHelper(TypeQualified mt, Loc loc, Scope* sc, Dsymbol s, Dsym
          */
         const p = mt.mutableOf().unSharedOf().toChars();
         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))
-            error(loc, "undefined identifier `%s`, did you mean %s `%s`?", p, s2.kind(), s2.toChars());
-        else if (const q = Scope.search_correct_C(id))
-            error(loc, "undefined identifier `%s`, did you mean `%s`?", p, q);
-        else if ((id == Id.This   && sc.getStructClassScope()) ||
-                 (id == Id._super && sc.getClassScope()))
-            error(loc, "undefined identifier `%s`, did you mean `typeof(%s)`?", p, p);
-        else
-            error(loc, "undefined identifier `%s`", p);
+        if (!(sc && sc.inCfile))
+        {
+            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))
+                error(loc, "undefined identifier `%s`, did you mean %s `%s`?", p, s2.kind(), s2.toChars());
+            else if (const q = Scope.search_correct_C(id))
+                error(loc, "undefined identifier `%s`, did you mean `%s`?", p, q);
+            else if ((id == Id.This   && sc.getStructClassScope()) ||
+                     (id == Id._super && sc.getClassScope()))
+                error(loc, "undefined identifier `%s`, did you mean `typeof(%s)`?", p, p);
+            else
+                error(mt.loc, "undefined identifier `%s`", p);
+        }
+        else {
+            if (const n = cIncludeHint(id.toString()))
+                error(loc, "`%s` is not defined, perhaps `#include %.*s` ?", p, cast(int)n.length, n.ptr);
+            else if (auto s2 = sc.search_correct(id))
+                error(loc, "undefined identifier `%s`, did you mean %s `%s`?", p, s2.kind(), s2.toChars());
+            else
+                error(loc, "undefined identifier `%s`", p);
+        }
 
         pt = Type.terror;
         return;
@@ -1934,7 +1945,19 @@ Type typeSemantic(Type type, Loc loc, Scope* sc)
             Expression e;
             Type t;
             Dsymbol s;
-            mtype.index.resolve(loc, sc, e, t, s);
+            Loc indexLoc;
+
+            switch (mtype.index.ty)
+            {
+                case Tident:    indexLoc = mtype.index.isTypeIdentifier().loc;  break;
+                case Tinstance: indexLoc = mtype.index.isTypeInstance().loc;    break;
+                case Ttypeof:   indexLoc = mtype.index.isTypeTypeof().loc;      break;
+                case Treturn:   indexLoc = mtype.index.isTypeReturn().loc;      break;
+                case Tmixin:    indexLoc = mtype.index.isTypeMixin().loc;       break;
+                default: indexLoc = mtype.loc;
+            }
+
+            mtype.index.resolve(indexLoc, sc, e, t, s);
 
             // https://issues.dlang.org/show_bug.cgi?id=15478
             if (s)
@@ -2737,7 +2760,11 @@ Type typeSemantic(Type type, Loc loc, Scope* sc)
         Expression e;
         Dsymbol s;
         //printf("TypeIdentifier::semantic(%s)\n", mtype.toChars());
-        mtype.resolve(loc, sc, e, t, s);
+        if (mtype.loc != Loc.initial)
+            mtype.resolve(mtype.loc, sc, e, t, s);
+        else
+            mtype.resolve(loc, sc, e, t, s);
+
         if (t)
         {
             //printf("\tit's a type %d, %s, %s\n", t.ty, t.toChars(), t.deco);
@@ -3428,8 +3455,10 @@ Expression getProperty(Type t, Scope* scope_, Loc loc, Identifier ident, int fla
         }
 
         Dsymbol s = null;
-        if (mt.ty == Tstruct || mt.ty == Tclass || mt.ty == Tenum)
-            s = mt.toDsymbol(null);
+        auto derefType = mt.isTypePointer() ? mt.nextOf() : mt;
+
+        if (derefType.isTypeStruct() || derefType.isTypeClass() || derefType.isTypeEnum())
+            s = derefType.toDsymbol(null);
         if (s)
             s = s.search_correct(ident);
         if (s && !symbolIsVisible(scope_, s))
@@ -3439,18 +3468,21 @@ Expression getProperty(Type t, Scope* scope_, Loc loc, Identifier ident, int fla
             return ErrorExp.get();
 
         if (s)
-            error(loc, "no property `%s` for type `%s`, did you mean `%s`?", ident.toChars(), mt.toChars(), s.toPrettyChars());
+        {
+            error(loc, "no property `%s` for type `%s`", ident.toErrMsg(), mt.toErrMsg());
+            errorSupplemental(s.loc, "did you mean `%s`?", ident == s.ident ? s.toPrettyChars() : s.toErrMsg());
+        }
         else if (ident == Id.opCall && mt.ty == Tclass)
-            error(loc, "no property `%s` for type `%s`, did you mean `new %s`?", ident.toChars(), mt.toChars(), mt.toPrettyChars());
+            error(loc, "no property `%s` for type `%s`, did you mean `new %s`?", ident.toErrMsg(), mt.toErrMsg(), mt.toPrettyChars());
 
         else if (const n = importHint(ident.toString()))
-                error(loc, "no property `%s` for type `%s`, perhaps `import %.*s;` is needed?", ident.toChars(), mt.toChars(), cast(int)n.length, n.ptr);
+                error(loc, "no property `%s` for type `%s`, perhaps `import %.*s;` is needed?", ident.toErrMsg(), mt.toErrMsg(), cast(int)n.length, n.ptr);
         else
         {
             if (src)
             {
                 error(loc, "no property `%s` for `%s` of type `%s`",
-                    ident.toChars(), src.toChars(), mt.toPrettyChars(true));
+                    ident.toErrMsg(), src.toErrMsg(), mt.toPrettyChars(true));
                 auto s2 = scope_.search_correct(ident);
                 // UFCS
                 if (s2 && s2.isFuncDeclaration)
@@ -3458,30 +3490,17 @@ Expression getProperty(Type t, Scope* scope_, Loc loc, Identifier ident, int fla
                     if (s2.ident == ident)
                     {
                         errorSupplemental(s2.loc, "cannot call %s `%s` with UFCS because it is not declared at module scope",
-                            s2.kind(), s2.toChars());
+                            s2.kind(), s2.toErrMsg());
                     }
                     else
                         errorSupplemental(s2.loc, "did you mean %s `%s`?",
-                            s2.kind(), s2.toChars());
-                }
-                else if (src.type.ty == Tpointer)
-                {
-                    // structPtr.field
-                    auto tn = (cast(TypeNext) src.type).nextOf();
-                    if (auto as = tn.isAggregate())
-                    {
-                        if (auto s3 = as.search_correct(ident))
-                        {
-                            errorSupplemental(s3.loc, "did you mean %s `%s`?",
-                                s3.kind(), s3.toChars());
-                        }
-                    }
+                            s2.kind(), s2.toErrMsg());
                 }
             }
             else
-                error(loc, "no property `%s` for type `%s`", ident.toChars(), mt.toPrettyChars(true));
+                error(loc, "no property `%s` for type `%s`", ident.toErrMsg(), mt.toPrettyChars(true));
 
-            if (auto dsym = mt.toDsymbol(scope_))
+            if (auto dsym = derefType.toDsymbol(scope_))
             {
                 if (auto sym = dsym.isAggregateDeclaration())
                 {
@@ -3507,7 +3526,7 @@ Expression getProperty(Type t, Scope* scope_, Loc loc, Identifier ident, int fla
                     }
                 }
                 errorSupplemental(dsym.loc, "%s `%s` defined here",
-                    dsym.kind, dsym.toChars());
+                    dsym.kind, dsym.toErrMsg());
             }
         }
 
@@ -6704,6 +6723,7 @@ STC parameterStorageClass(TypeFunction tf, Type tthis, Parameter p, VarDeclarati
         // Check escaping through `this`
         if (tthis && tthis.isMutable())
         {
+            import dmd.dsymbolsem : hasPointers;
             foreach (VarDeclaration v; isAggregate(tthis).fields)
             {
                 if (v.hasPointers())
@@ -6714,6 +6734,7 @@ STC parameterStorageClass(TypeFunction tf, Type tthis, Parameter p, VarDeclarati
         // Check escaping through nested context
         if (outerVars && tf.isMutable())
         {
+            import dmd.dsymbolsem : hasPointers;
             foreach (VarDeclaration v; *outerVars)
             {
                 if (v.hasPointers())
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index 026b12fb93e1..160d37846f29 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -908,7 +908,7 @@ public:
 	      }
 	  }
 
-	if (cd->isAbstract ())
+	if (dmd::isAbstract (cd))
 	  flags |= ClassFlags::isAbstract;
 
 	for (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass)
@@ -919,7 +919,7 @@ public:
 	    for (size_t i = 0; i < bcd->members->length; i++)
 	      {
 		Dsymbol *sm = (*bcd->members)[i];
-		if (sm->hasPointers ())
+		if (dmd::hasPointers (sm))
 		  goto Lhaspointers;
 	      }
 	  }
diff --git a/gcc/testsuite/gdc.dg/asm1.d b/gcc/testsuite/gdc.dg/asm1.d
index 1593eb6acd34..e2f36b01c94a 100644
--- a/gcc/testsuite/gdc.dg/asm1.d
+++ b/gcc/testsuite/gdc.dg/asm1.d
@@ -11,7 +11,7 @@ void parse1()
 
 void parse2()
 {
-    asm 
+    asm
     {
         "" : : "g" (1 ? 2 : 3);
         "" : : "g" (1 ? 2 : :) 3;
@@ -22,11 +22,7 @@ void parse2()
 
 void parse3()
 {
-    asm { "" [; }
-    // { dg-error "expression expected, not ';'" "" { target *-*-* } .-1 }
-    // { dg-error "found 'End of File' when expecting ','" "" { target *-*-* } .-2 }
-    // { dg-error "found 'End of File' when expecting ']'" "" { target *-*-* } .-3 }
-    // { dg-error "found 'End of File' when expecting ';'" "" { target *-*-* } .-4 }
+    asm { "" [; } // { dg-error "found '\\\[' when expecting ':'" }
 }
 
 void parse4()
@@ -68,9 +64,9 @@ void semantic2()
 
 void semantic3()
 {
-    asm 
+    asm
     {
-        unknown;        // { dg-error "undefined identifier 'unknown'" }
+        unknown;        // { dg-error "expected string literal or expression in parentheses" }
     }
 }
 
diff --git a/gcc/testsuite/gdc.test/compilable/imports/cstuff3.c b/gcc/testsuite/gdc.test/compilable/imports/cstuff3.c
index f6aaf3b2a4ae..fb78ec76bca7 100644
--- a/gcc/testsuite/gdc.test/compilable/imports/cstuff3.c
+++ b/gcc/testsuite/gdc.test/compilable/imports/cstuff3.c
@@ -4,3 +4,16 @@ int squared(int a)
 {
     return a * a;
 }
+
+/* test case for issue #21094 */
+typedef enum upng_error {
+    UPNG_EOK            = 0, /* success (no error) */
+    UPNG_ENOMEM         = 1, /* memory allocation failed */
+    UPNG_ENOTFOUND      = 2, /* resource not found (file missing) */
+    UPNG_ENOTPNG        = 3, /* image data does not have a PNG header */
+    UPNG_EMALFORMED     = 4, /* image data is not a valid PNG image */
+    UPNG_EUNSUPPORTED   = 5, /* critical PNG chunk type is not supported */
+    UPNG_EUNINTERLACED  = 6, /* image interlacing is not supported */
+    UPNG_EUNFORMAT      = 7, /* image color format is not supported */
+    UPNG_EPARAM         = 8  /* invalid parameter to method call */
+} upng_error;
diff --git a/gcc/testsuite/gdc.test/compilable/imports/imp18127a.c b/gcc/testsuite/gdc.test/compilable/imports/imp18127a.c
new file mode 100644
index 000000000000..cd173151dbff
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/imp18127a.c
@@ -0,0 +1,74 @@
+// https://github.com/dlang/dmd/issues/18127
+union struct_or_union {
+    int x;
+};
+
+struct S_n_fields {
+    int x, y;
+};
+
+struct S_types {
+    float x;
+};
+
+struct S_names {
+    float x;
+};
+
+struct B {
+    int x;
+};
+
+struct S_b {
+    struct B b;
+};
+
+struct S_contains_anon_named {
+    struct {
+        int x;
+    } a;
+};
+
+struct S_contains_anon_unnamed {
+    struct {
+        int x;
+    };
+};
+
+struct S_bitfields_mismatch1 {
+    unsigned x: 3;
+    unsigned y: 1;
+};
+struct S_bitfields_mismatch2 {
+    unsigned x;
+    unsigned y: 1;
+};
+
+struct S_bitfields_widths {
+    unsigned x: 3;
+    unsigned y: 1;
+};
+
+struct S_bitfields_anon {
+    unsigned x: 3;
+    unsigned : 1;
+};
+
+struct S_alignas {
+    _Alignas(8) float x;
+};
+struct S_aligned {
+    float x;
+}__attribute__((aligned(8)));
+
+struct __attribute__((packed)) S_pack_1 {
+    float x;
+    char c;
+};
+#pragma pack(push)
+#pragma pack(1)
+struct S_pack_2 {
+    float x;
+    char c;
+};
+#pragma pack(pop)
diff --git a/gcc/testsuite/gdc.test/compilable/imports/imp18127b.c b/gcc/testsuite/gdc.test/compilable/imports/imp18127b.c
new file mode 100644
index 000000000000..cd173151dbff
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/imp18127b.c
@@ -0,0 +1,74 @@
+// https://github.com/dlang/dmd/issues/18127
+union struct_or_union {
+    int x;
+};
+
+struct S_n_fields {
+    int x, y;
+};
+
+struct S_types {
+    float x;
+};
+
+struct S_names {
+    float x;
+};
+
+struct B {
+    int x;
+};
+
+struct S_b {
+    struct B b;
+};
+
+struct S_contains_anon_named {
+    struct {
+        int x;
+    } a;
+};
+
+struct S_contains_anon_unnamed {
+    struct {
+        int x;
+    };
+};
+
+struct S_bitfields_mismatch1 {
+    unsigned x: 3;
+    unsigned y: 1;
+};
+struct S_bitfields_mismatch2 {
+    unsigned x;
+    unsigned y: 1;
+};
+
+struct S_bitfields_widths {
+    unsigned x: 3;
+    unsigned y: 1;
+};
+
+struct S_bitfields_anon {
+    unsigned x: 3;
+    unsigned : 1;
+};
+
+struct S_alignas {
+    _Alignas(8) float x;
+};
+struct S_aligned {
+    float x;
+}__attribute__((aligned(8)));
+
+struct __attribute__((packed)) S_pack_1 {
+    float x;
+    char c;
+};
+#pragma pack(push)
+#pragma pack(1)
+struct S_pack_2 {
+    float x;
+    char c;
+};
+#pragma pack(pop)
diff --git a/gcc/testsuite/gdc.test/compilable/imports/imp20344.c b/gcc/testsuite/gdc.test/compilable/imports/imp20344.c
new file mode 100644
index 000000000000..56ac79c930c3
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/imp20344.c
@@ -0,0 +1,2 @@
+// https://github.com/dlang/dmd/issues/20334
+#define X "X"
diff --git a/gcc/testsuite/gdc.test/compilable/imports/imp20499.c b/gcc/testsuite/gdc.test/compilable/imports/imp20499.c
new file mode 100644
index 000000000000..7ae74906f73c
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/imp20499.c
@@ -0,0 +1,8 @@
+// https://github.com/dlang/dmd/issues/20499
+typedef struct Foo {
+    int x;
+} *pFoo;
+
+struct Bar {
+    struct Foo foo;
+};
diff --git a/gcc/testsuite/gdc.test/compilable/test18127.d b/gcc/testsuite/gdc.test/compilable/test18127.d
new file mode 100644
index 000000000000..3d6b454a2be1
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test18127.d
@@ -0,0 +1,5 @@
+// https://github.com/dlang/dmd/issues/18127
+// EXTRA_FILES: imports/imp18127a.c imports/imp18127b.c
+
+import imports.imp18127a;
+import imports.imp18127b;
diff --git a/gcc/testsuite/gdc.test/compilable/test20344.d b/gcc/testsuite/gdc.test/compilable/test20344.d
new file mode 100644
index 000000000000..26ee9a3269e5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test20344.d
@@ -0,0 +1,14 @@
+// https://github.com/dlang/dmd/issues/20334
+// EXTRA_FILES: imports/imp20344.c
+import imports.imp20344;
+string s = X;
+const(char)* p = X;
+
+void takes_string(string){ }
+void takes_char_star(const(char)*){ }
+
+
+void test20344(){
+    takes_string(X);
+    takes_char_star(X);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test20499.d b/gcc/testsuite/gdc.test/compilable/test20499.d
new file mode 100644
index 000000000000..3263aed66b62
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test20499.d
@@ -0,0 +1,3 @@
+// https://github.com/dlang/dmd/issues/20499
+// EXTRA_FILES: imports/imp20499.c
+import imports.imp20499;
diff --git a/gcc/testsuite/gdc.test/compilable/test3004.d b/gcc/testsuite/gdc.test/compilable/test3004.d
index 23ec46f29055..664452ef4e68 100644
--- a/gcc/testsuite/gdc.test/compilable/test3004.d
+++ b/gcc/testsuite/gdc.test/compilable/test3004.d
@@ -1,7 +1,7 @@
 // https://issues.dlang.org/show_bug.cgi?id=3004
 /*
 REQUIRED_ARGS: -ignore -v
-TRANSFORM_OUTPUT: remove_lines("^(predefs|binary|version|config|DFLAG|parse|import|semantic|entry|library|function  object|function  core|\s*$)")
+TRANSFORM_OUTPUT: remove_lines("^(predefs|binary|version|config|DFLAG|parse|import|\(imported|semantic|entry|library|function  object|function  core|\s*$)")
 TEST_OUTPUT:
 ---
 pragma    GNU_attribute (__error)
diff --git a/gcc/testsuite/gdc.test/compilable/testcstuff3.d b/gcc/testsuite/gdc.test/compilable/testcstuff3.d
index 89228a9bc4ab..08aa3b03d11d 100644
--- a/gcc/testsuite/gdc.test/compilable/testcstuff3.d
+++ b/gcc/testsuite/gdc.test/compilable/testcstuff3.d
@@ -2,3 +2,22 @@
 import imports.cstuff3;
 
 static assert(squared(4) == 16);
+
+/* test case for issue #21094 */
+string enum_to_str(E)(E v) if (is(E == enum))
+{
+    final switch (v) with(E)
+    {
+        static foreach (m; __traits(allMembers, E))
+        {
+    case mixin(m):
+            return m;
+        }
+    }
+}
+
+void testEnumSwitch()
+{
+    auto str = enum_to_str(UPNG_EOK);
+    assert(str == "UPNG_EOK");
+}
diff --git a/gcc/testsuite/gdc.test/compilable/uda_lambda.d b/gcc/testsuite/gdc.test/compilable/uda_lambda.d
new file mode 100644
index 000000000000..df331747a7f1
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/uda_lambda.d
@@ -0,0 +1,3 @@
+enum UDA;
+int fun() @UDA => 7;
+static assert(fun() == 7);
diff --git a/gcc/testsuite/gdc.test/compilable/vcg-ast.d b/gcc/testsuite/gdc.test/compilable/vcg-ast.d
index 9197441affea..bcb7256723c6 100644
--- a/gcc/testsuite/gdc.test/compilable/vcg-ast.d
+++ b/gcc/testsuite/gdc.test/compilable/vcg-ast.d
@@ -75,3 +75,14 @@ template imported()
 }
 
 alias myImport = imported!();
+
+// https://github.com/dlang/dmd/issues/21105
+
+enum compiles = __traits(compiles,{
+    int[] arr;
+    arr ~= 1;
+});
+enum isexp = is(typeof({
+    int[] arr;
+    arr ~= 1;
+}));
diff --git a/gcc/testsuite/gdc.test/fail_compilation/b23686.d b/gcc/testsuite/gdc.test/fail_compilation/b23686.d
index 4c2a5bd026d2..5838f5c8e10c 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/b23686.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/b23686.d
@@ -4,7 +4,7 @@ TEST_OUTPUT:
 fail_compilation/b23686.d(107): Error: undefined identifier `eFN1`, did you mean template `eFN0()()`?
 fail_compilation/b23686.d(107): Error: `mixin(_error_)` does not give a valid type
 fail_compilation/b23686.d(115):        while looking for match for `eload!(int, 1)`
-fail_compilation/b23686.d(121): Error: undefined identifier `FNwtf`
+fail_compilation/b23686.d-mixin-121(121): Error: undefined identifier `FNwtf`
 fail_compilation/b23686.d(121): Error: `mixin(_error_)` does not give a valid type
 fail_compilation/b23686.d(126):        while looking for match for `load!"wtf"`
 ---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/checkimports2.d b/gcc/testsuite/gdc.test/fail_compilation/checkimports2.d
index 44c237f144f8..56e28e1ce7bb 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/checkimports2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/checkimports2.d
@@ -2,10 +2,12 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/checkimports2.d(25): Error: no property `X` for type `checkimports2.B`, did you mean `imports.imp2.X`?
-fail_compilation/checkimports2.d(25):        while evaluating: `static assert((B).X == 0)`
-fail_compilation/checkimports2.d(26): Error: no property `Y` for type `checkimports2.B`, did you mean `imports.imp2.Y`?
-fail_compilation/checkimports2.d(26):        while evaluating: `static assert((B).Y == 2)`
+fail_compilation/checkimports2.d(27): Error: no property `X` for type `checkimports2.B`
+fail_compilation/imports/imp2.d(3):        did you mean `imports.imp2.X`?
+fail_compilation/checkimports2.d(27):        while evaluating: `static assert((B).X == 0)`
+fail_compilation/checkimports2.d(28): Error: no property `Y` for type `checkimports2.B`
+fail_compilation/imports/imp2.d(4):        did you mean `imports.imp2.Y`?
+fail_compilation/checkimports2.d(28):        while evaluating: `static assert((B).Y == 2)`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag10405.d b/gcc/testsuite/gdc.test/fail_compilation/diag10405.d
deleted file mode 100644
index 28da8af93ad1..000000000000
--- a/gcc/testsuite/gdc.test/fail_compilation/diag10405.d
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
-TEST_OUTPUT:
----
-fail_compilation/diag10405.d(10): Error: cannot return non-void from `void` function
----
-*/
-
-void main()
-{
-    return 10;
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag20888.d b/gcc/testsuite/gdc.test/fail_compilation/diag20888.d
index 84af42533fcc..d030a98ec2c2 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag20888.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag20888.d
@@ -13,12 +13,12 @@ fail_compilation/diag20888.d(49): Error: return value `callback` of type `int de
 fail_compilation/diag20888.d(54): Error: return value `() => 3755` of type `int function() pure nothrow @nogc @safe` does not match return type `int`, and cannot be implicitly converted
 fail_compilation/diag20888.d(54):        Did you intend to call the function pointer?
 fail_compilation/diag20888.d(59): Error: `return` expression expected
-fail_compilation/diag20888.d(64): Error: cannot return non-void from `void` function
 fail_compilation/diag20888.d(70): Error: return value `() => i` of type `int delegate() pure nothrow @nogc @safe` does not match return type `int`, and cannot be implicitly converted
 fail_compilation/diag20888.d(70):        Did you intend to call the delegate?
 ---
 */
 
+
 int alpha(int function() callback)
 {
 	return callback;
@@ -59,10 +59,10 @@ int theta()
 	return;
 }
 
-void iota()
-{
-	return 0xEAB;
-}
+
+
+
+
 
 int kappa()
 {
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag23384.d b/gcc/testsuite/gdc.test/fail_compilation/diag23384.d
index 1fa4da5ffb9e..9cb17c00d74f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag23384.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag23384.d
@@ -4,8 +4,8 @@
 TEST_OUTPUT:
 ---
 fail_compilation/diag23384.d(28): Error: function `diag23384.Derived.fun(B b)` is not callable using argument types `(A)`
-fail_compilation/diag23384.d(28):        function `diag23384.Derived.fun` hides base class function `diag23384.Base.fun`
-fail_compilation/diag23384.d(28):        add `alias fun = diag23384.Base.fun` to `diag23384.Derived`'s body to merge the overload sets
+fail_compilation/diag23384.d(28):        Note: function `diag23384.Derived.fun` hides base class function `diag23384.Base.fun`
+fail_compilation/diag23384.d(28):        Add `alias fun = diag23384.Base.fun;` to `diag23384.Derived`'s body to merge the overload sets
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag9679.d b/gcc/testsuite/gdc.test/fail_compilation/diag9679.d
index 22e94e575969..50b8717adf31 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag9679.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag9679.d
@@ -3,13 +3,14 @@ TEST_OUTPUT:
 ---
 fail_compilation/diag9679.d(93): Deprecation: `auto` and `ref` storage classes should be adjacent
 fail_compilation/diag9679.d(93): Deprecation: `auto` and `ref` storage classes should be adjacent
-fail_compilation/diag9679.d(15): Error: rvalue `1` cannot be assigned to `ref n`
-fail_compilation/diag9679.d(16): Error: variable `diag9679.main.n` - storage class `auto` has no effect if type is not inferred, did you mean `scope`?
-fail_compilation/diag9679.d(17): Error: variable `diag9679.main.S.a` - field declarations cannot be `ref`
-fail_compilation/diag9679.d(24): Error: returning `r` escapes a reference to local variable `i`
+fail_compilation/diag9679.d(94): Deprecation: `auto ref` return type must have `auto` and `ref` adjacent
+fail_compilation/diag9679.d(100): Deprecation: `auto ref` return type must have `auto` and `ref` adjacent
+fail_compilation/diag9679.d(16): Error: rvalue `1` cannot be assigned to `ref n`
+fail_compilation/diag9679.d(17): Error: variable `diag9679.main.n` - storage class `auto` has no effect if type is not inferred, did you mean `scope`?
+fail_compilation/diag9679.d(18): Error: variable `diag9679.main.S.a` - field declarations cannot be `ref`
+fail_compilation/diag9679.d(25): Error: returning `r` escapes a reference to local variable `i`
 ---
 */
-
 void main()
 {
     if (ref n = 1) {}
@@ -60,7 +61,6 @@ fail_compilation/diag9679.d(96): Error: variable `x` - `auto ref` variable must
 ---
 */
 
-
 void test5()
 {
     ref int r5;
@@ -90,8 +90,11 @@ void test9()
     auto ref int y = void;
 }
 
-void testKeywordOrder()(ref auto int x, auto const ref float y) {}
-void testKeywordOrder()
+void testKeywordOrder()(ref auto int x, auto const ref float y) {};
+ref auto int testKeywordOrder()
 {
     ref auto int x = 3;
+    return 3;
 }
+
+auto { ref int autoFromScope() => 3; }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag_ptr_conversion.d b/gcc/testsuite/gdc.test/fail_compilation/diag_ptr_conversion.d
new file mode 100644
index 000000000000..ea144b2c9db2
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag_ptr_conversion.d
@@ -0,0 +1,17 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/diag_ptr_conversion.d(15): Error: cannot implicitly convert `const(int)*` to `int*`
+fail_compilation/diag_ptr_conversion.d(15):        Note: Converting const to mutable requires an explicit cast (`cast(int*)`).
+fail_compilation/diag_ptr_conversion.d(16): Error: cannot implicitly convert `int*` to `float*`
+fail_compilation/diag_ptr_conversion.d(16):        Note: Pointer types point to different base types (`int` vs `float`)
+---
+*/
+
+void testPointerConversions()
+{
+    int* p;
+    const(int)* cp = p;
+    p = cp;
+    float* f = p;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/enum_auto_increment.d b/gcc/testsuite/gdc.test/fail_compilation/enum_auto_increment.d
new file mode 100644
index 000000000000..9c04e9a324f6
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/enum_auto_increment.d
@@ -0,0 +1,18 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation\enum_auto_increment.d(17): Error: cannot automatically assign value to enum member `enum_auto_increment.A2.d` because base type `A1` is an enum; provide an explicit value
+---
+*/
+
+enum A1 : int
+{
+    a,
+    b,
+}
+
+enum A2 : A1
+{
+    c,
+    d,
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail109.d b/gcc/testsuite/gdc.test/fail_compilation/fail109.d
index 003e65f9b807..94f951f9f953 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail109.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail109.d
@@ -34,9 +34,7 @@ enum E1 : short
 /* https://issues.dlang.org/show_bug.cgi?id=14950
 TEST_OUTPUT:
 ---
-fail_compilation/fail109.d(50): Error: cannot check `fail109.B.end` value for overflow
-fail_compilation/fail109.d(50): Error: comparison between different enumeration types `B` and `C`; If this behavior is intended consider using `std.conv.asOriginalType`
-fail_compilation/fail109.d(50): Error: enum member `fail109.B.end` initialization with `B.start+1` causes overflow for type `C`
+fail_compilation\fail109.d(48): Error: cannot automatically assign value to enum member `fail109.B.end` because base type `C` is an enum; provide an explicit value
 ---
 */
 enum C
@@ -53,10 +51,10 @@ enum B
 /* https://issues.dlang.org/show_bug.cgi?id=11849
 TEST_OUTPUT:
 ---
-fail_compilation/fail109.d(72): Error: enum member `fail109.RegValueType1a.Unknown` is forward referenced looking for `.max`
-fail_compilation/fail109.d(79): Error: enum member `fail109.RegValueType1b.Unknown` is forward referenced looking for `.max`
-fail_compilation/fail109.d(84): Error: enum member `fail109.RegValueType2a.Unknown` is forward referenced looking for `.min`
-fail_compilation/fail109.d(91): Error: enum member `fail109.RegValueType2b.Unknown` is forward referenced looking for `.min`
+fail_compilation/fail109.d(70): Error: enum member `fail109.RegValueType1a.Unknown` is forward referenced looking for `.max`
+fail_compilation/fail109.d(77): Error: enum member `fail109.RegValueType1b.Unknown` is forward referenced looking for `.max`
+fail_compilation/fail109.d(82): Error: enum member `fail109.RegValueType2a.Unknown` is forward referenced looking for `.min`
+fail_compilation/fail109.d(89): Error: enum member `fail109.RegValueType2b.Unknown` is forward referenced looking for `.min`
 ---
 */
 
@@ -94,7 +92,7 @@ enum RegValueType2b : DWORD
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail109.d(107): Error: enum member `fail109.d` initialization with `__anonymous.c+1` causes overflow for type `Q`
+fail_compilation/fail109.d(105): Error: enum member `fail109.d` initialization with `__anonymous.c+1` causes overflow for type `Q`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail11714.d b/gcc/testsuite/gdc.test/fail_compilation/fail11714.d
index abc47087ffaa..f36f3e5831e9 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail11714.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail11714.d
@@ -1,8 +1,10 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail11714.d(14): Error: variable `fail11714.c` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead.
-fail_compilation/fail11714.d(21): Error: variable `fail11714.s` is a thread-local pointer to struct and cannot have a static initializer. Use `static this()` to initialize instead.
+fail_compilation/fail11714.d(16): Error: variable `fail11714.c` is a thread-local class and cannot have a static initializer
+fail_compilation/fail11714.d(16):        use `static this()` to initialize instead
+fail_compilation/fail11714.d(23): Error: variable `fail11714.s` is a thread-local pointer to struct and cannot have a static initializer
+fail_compilation/fail11714.d(23):        use `static this()` to initialize instead
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail15361.d b/gcc/testsuite/gdc.test/fail_compilation/fail15361.d
index 8e5f9800a816..aec716556a4f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail15361.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail15361.d
@@ -1,7 +1,8 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail15361.d(8): Error: unexpected `(` after `errorize`, inside `is` expression. Try enclosing the contents of `is` with a `typeof` expression
+fail_compilation/fail15361.d(9): Error: unexpected `(` after `errorize`, inside `is` expression
+fail_compilation/fail15361.d(9):        try enclosing the contents of `is` with a `typeof` expression
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail15616b.d b/gcc/testsuite/gdc.test/fail_compilation/fail15616b.d
index 4b209685ca44..4cbd591cbf82 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail15616b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail15616b.d
@@ -1,6 +1,6 @@
 /*
 REQUIRED_ARGS: -v
-TRANSFORM_OUTPUT: remove_lines("^(predefs|binary|version|config|DFLAG|parse|import|semantic|entry|\s*$)")
+TRANSFORM_OUTPUT: remove_lines("^(predefs|binary|version|config|DFLAG|parse|import|\(imported|semantic|entry|\s*$)")
 TEST_OUTPUT:
 ---
 fail_compilation/fail15616b.d(44): Error: none of the overloads of `foo` are callable using argument types `(double)`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail16.d b/gcc/testsuite/gdc.test/fail_compilation/fail16.d
index 4602d3de3bd6..ce021a95b859 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail16.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail16.d
@@ -2,8 +2,9 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail16.d(19): Error: function declaration without return type. (Note that constructors are always named `this`)
-fail_compilation/fail16.d(19): Error: variable name expected after type `bar!(typeof(X))(X)`, not `;`
+fail_compilation/fail16.d(20): Error: function declaration without return type
+fail_compilation/fail16.d(20):        Note that constructors are always named `this`
+fail_compilation/fail16.d(20): Error: variable name expected after type `bar!(typeof(X))(X)`, not `;`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail163.d b/gcc/testsuite/gdc.test/fail_compilation/fail163.d
index 7f8f028fa52d..590bf23931c9 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail163.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail163.d
@@ -14,7 +14,8 @@ void test1()
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail163.d(24): Error: cannot implicitly convert expression `p` of type `const(int***)` to `const(int)***`
+fail_compilation/fail163.d(25): Error: cannot implicitly convert `const(int***)` to `const(int)***`
+fail_compilation/fail163.d(25):        Note: Converting const to mutable requires an explicit cast (`cast(int*)`).
 ---
 */
 void test2()
@@ -27,7 +28,7 @@ void test2()
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail163.d(37): Error: cannot modify `const` expression `p`
+fail_compilation/fail163.d(38): Error: cannot modify `const` expression `p`
 ---
 */
 void test3()
@@ -40,7 +41,7 @@ void test3()
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail163.d(50): Error: cannot implicitly convert expression `cp` of type `const(int)***[]` to `const(uint***)[]`
+fail_compilation/fail163.d(51): Error: cannot implicitly convert expression `cp` of type `const(int)***[]` to `const(uint***)[]`
 ---
 */
 void test4()
@@ -53,7 +54,7 @@ void test4()
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail163.d(63): Error: cannot modify `const` expression `*p`
+fail_compilation/fail163.d(64): Error: cannot modify `const` expression `*p`
 ---
 */
 void test5()
@@ -66,8 +67,8 @@ void test5()
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail163.d(76): Error: cannot implicitly convert expression `& x` of type `int*` to `immutable(int)*`
-fail_compilation/fail163.d(77): Error: cannot modify `immutable` expression `*p`
+fail_compilation/fail163.d(77): Error: cannot implicitly convert expression `& x` of type `int*` to `immutable(int)*`
+fail_compilation/fail163.d(78): Error: cannot modify `immutable` expression `*p`
 ---
 */
 void test6()
@@ -80,7 +81,8 @@ void test6()
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail163.d(89): Error: cannot implicitly convert expression `& x` of type `const(int)*` to `int*`
+fail_compilation/fail163.d(91): Error: cannot implicitly convert `const(int)*` to `int*`
+fail_compilation/fail163.d(91):        Note: Converting const to mutable requires an explicit cast (`cast(int*)`).
 ---
 */
 void test7()
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail18219.d b/gcc/testsuite/gdc.test/fail_compilation/fail18219.d
index bf4b189f6ebc..f5fc27f1a89d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail18219.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail18219.d
@@ -3,11 +3,14 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail18219.d(17): Error: no property `Foobar` for type `AST`, did you mean `b18219.Foobar`?
-fail_compilation/fail18219.d(18): Error: no property `Bar` for type `a18219.AST`
+fail_compilation/fail18219.d(20): Error: no property `Foobar` for type `AST`
+fail_compilation/imports/b18219.d(3):        did you mean `b18219.Foobar`?
+fail_compilation/fail18219.d(21): Error: no property `Bar` for type `a18219.AST`
 fail_compilation/imports/a18219.d(3):        struct `AST` defined here
-fail_compilation/fail18219.d(19): Error: no property `fun` for type `AST`, did you mean `b18219.fun`?
-fail_compilation/fail18219.d(20): Error: no property `Foobar` for type `AST`, did you mean `b18219.Foobar`?
+fail_compilation/fail18219.d(22): Error: no property `fun` for type `AST`
+fail_compilation/imports/b18219.d(15):        did you mean `b18219.fun`?
+fail_compilation/fail18219.d(23): Error: no property `Foobar` for type `AST`
+fail_compilation/imports/b18219.d(3):        did you mean `b18219.Foobar`?
 ---
 */
 import imports.a18219;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19103.d b/gcc/testsuite/gdc.test/fail_compilation/fail19103.d
index c1abd0df90af..e617249ed713 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail19103.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19103.d
@@ -5,10 +5,10 @@ fail_compilation/fail19103.d(14): Error: no property `puts` for `new C` of type
 fail_compilation/fail19103.d(26):        class `C` defined here
 fail_compilation/fail19103.d(16): Error: no property `puts` for `s1` of type `fail19103.S1`
 fail_compilation/fail19103.d(30):        struct `S1` defined here
-fail_compilation/fail19103.d(18): Error: no property `puts` for type `S2`, did you mean `core.stdc.stdio.puts`?
+fail_compilation/fail19103.d(18): Error: no property `puts` for type `S2`
+$p:druntime/import/core/stdc/stdio.d$($n$):        did you mean `core.stdc.stdio.puts`?
 ---
 */
-
 void main()
 {
     (new C).puts("OK."); // Error: no property puts for type test.C, did you mean core.stdc.stdio.puts(T...)(T args)?
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail196.d b/gcc/testsuite/gdc.test/fail_compilation/fail196.d
index 78c596390b56..a5d4499f3fff 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail196.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail196.d
@@ -21,7 +21,7 @@ fail_compilation/fail196.d(44):        expression: `";\n    assert(s == "`
 fail_compilation/fail196.d(45): Error: found `}` when expecting `;` following expression
 fail_compilation/fail196.d(45):        expression: `xxx`
 fail_compilation/fail196.d(47): Error: found `<` when expecting `;` following expression
-fail_compilation/fail196.d(45):        expression: `");\n\n    s = q" < foo`
+fail_compilation/fail196.d(47):        expression: `");\n\n    s = q" < foo`
 fail_compilation/fail196.d(48): Error: found `foo` when expecting `;` following expression
 fail_compilation/fail196.d(47):        expression: `xxx >> ";\n    assert(s == "`
 fail_compilation/fail196.d(48): Error: found `<` instead of statement
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail21547.d b/gcc/testsuite/gdc.test/fail_compilation/fail21547.d
index 7a6a44a4a133..440a301de514 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail21547.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail21547.d
@@ -3,8 +3,10 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail21547.d(32): Error: struct `Bar` has constructors, cannot use `{ initializers }`, use `Bar( initializers )` instead
-fail_compilation/fail21547.d(33): Error: struct `Bar1` has constructors, cannot use `{ initializers }`, use `Bar1( initializers )` instead
+fail_compilation/fail21547.d(34): Error: Cannot use struct initializer syntax for struct `Bar` because it has a constructor
+fail_compilation/fail21547.d(34):        Use `Bar( arguments )` instead of `{ initializers }`
+fail_compilation/fail21547.d(35): Error: Cannot use struct initializer syntax for struct `Bar1` because it has a constructor
+fail_compilation/fail21547.d(35):        Use `Bar1( arguments )` instead of `{ initializers }`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23439.d b/gcc/testsuite/gdc.test/fail_compilation/fail23439.d
index b070e581a4a7..6f16bc134366 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail23439.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23439.d
@@ -2,7 +2,8 @@
 // PERMUTE_ARGS: -lowmem
 /* TEST_OUTPUT:
 ---
-fail_compilation/fail23439.d(13): Error: variable `fail23439.ice23439` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead.
+fail_compilation/fail23439.d(14): Error: variable `fail23439.ice23439` is a thread-local class and cannot have a static initializer
+fail_compilation/fail23439.d(14):        use `static this()` to initialize instead
 ---
 */
 class C23439
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail305.d b/gcc/testsuite/gdc.test/fail_compilation/fail305.d
deleted file mode 100644
index aef1624a07ca..000000000000
--- a/gcc/testsuite/gdc.test/fail_compilation/fail305.d
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
-TEST_OUTPUT:
----
-fail_compilation/fail305.d(10): Error: cannot return non-void from `void` function
----
-*/
-
-void main()
-{
-    return "a";
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail336.d b/gcc/testsuite/gdc.test/fail_compilation/fail336.d
index 9df207120b36..8fb9857d4dc4 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail336.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail336.d
@@ -1,7 +1,8 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail336.d(16): Error: struct `S` has constructors, cannot use `{ initializers }`, use `S( initializers )` instead
+fail_compilation/fail336.d(17): Error: Cannot use struct initializer syntax for struct `S` because it has a constructor
+fail_compilation/fail336.d(17):        Use `S( arguments )` instead of `{ initializers }`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail347.d b/gcc/testsuite/gdc.test/fail_compilation/fail347.d
index c56acf5642cd..996990bd4001 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail347.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail347.d
@@ -3,16 +3,16 @@ EXTRA_FILES: imports/fail347a.d
 TEST_OUTPUT:
 ---
 fail_compilation/fail347.d(26): Error: undefined identifier `bbr`, did you mean variable `bar`?
-fail_compilation/fail347.d(27): Error: no property `ofo` for type `S`, did you mean `fail347.S.foo`?
-fail_compilation/fail347.d(29): Error: no property `fool` for `sp` of type `fail347.S*`
-fail_compilation/fail347.d(20):        did you mean variable `foo`?
+fail_compilation/fail347.d(27): Error: no property `ofo` for type `S`
+fail_compilation/fail347.d(20):        did you mean `foo`?
+fail_compilation/fail347.d(29): Error: no property `fool` for type `S*`
+fail_compilation/fail347.d(20):        did you mean `foo`?
 fail_compilation/fail347.d(30): Error: undefined identifier `strlenx`, did you mean function `strlen`?
 fail_compilation/fail347.d(31): Error: no property `strlenx` for `"hello"` of type `string`
 fail_compilation/imports/fail347a.d(3):        did you mean function `strlen`?
 ---
 */
 
-//import core.stdc.string;
 import imports.fail347a;
 
 struct S
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail41.d b/gcc/testsuite/gdc.test/fail_compilation/fail41.d
deleted file mode 100644
index 6d8939505399..000000000000
--- a/gcc/testsuite/gdc.test/fail_compilation/fail41.d
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
-TEST_OUTPUT:
----
-fail_compilation/fail41.d(17): Error: cannot return non-void from `void` function
----
-*/
-
-class MyClass
-{
-}
-
-MyClass[char[]] myarray;
-
-void fn()
-{
-    foreach (MyClass mc; myarray)
-        return mc;
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail98.d b/gcc/testsuite/gdc.test/fail_compilation/fail98.d
index 7541d3718c7b..20b18d19db5b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail98.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail98.d
@@ -1,7 +1,10 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail98.d(17): Error: cannot implicitly convert expression `256` of type `int` to `E`
+fail_compilation/fail98.d(20): Error: cannot implicitly convert expression `256` of type `int` to `E`
+fail_compilation/fail98.d(21): Error: cannot automatically assign value to enum member `fail98.D3DTS_WORLD1` because base type `E` is an enum; provide an explicit value
+fail_compilation/fail98.d(22): Error: cannot automatically assign value to enum member `fail98.D3DTS_WORLD2` because base type `E` is an enum; provide an explicit value
+fail_compilation/fail98.d(23): Error: cannot automatically assign value to enum member `fail98.D3DTS_WORLD3` because base type `E` is an enum; provide an explicit value
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_pretty_errors.d b/gcc/testsuite/gdc.test/fail_compilation/fail_pretty_errors.d
index 79242b163eea..ebd36a7cc1d2 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail_pretty_errors.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail_pretty_errors.d
@@ -16,7 +16,7 @@ fail_compilation/fail_pretty_errors.d(44): Error: mixin `fail_pretty_errors.test
     ^
 fail_compilation/fail_pretty_errors.d(50): Error: invalid array operation `"" + ""` (possible missing [])
     auto x = ""+"";
-             ^
+               ^
 fail_compilation/fail_pretty_errors.d(50):        did you mean to concatenate (`"" ~ ""`) instead ?
 fail_compilation/fail_pretty_errors.d(53): Error: cannot implicitly convert expression `1111` of type `int` to `byte`
         byte ɑ =    1111;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d b/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d
index b6c3bc906a15..749d98f9bd0c 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d
@@ -1,14 +1,15 @@
 /* TEST_OUTPUT:
 ---
-fail_compilation/failcontracts.d(17): Error: missing `{ ... }` for function literal
-fail_compilation/failcontracts.d(17): Error: semicolon expected following auto declaration, not `bode`
-fail_compilation/failcontracts.d(18): Error: function declaration without return type. (Note that constructors are always named `this`)
-fail_compilation/failcontracts.d(18): Error: variable name expected after type `test1()`, not `bode`
-fail_compilation/failcontracts.d(18): Error: semicolon expected following function declaration, not `bode`
+fail_compilation/failcontracts.d(18): Error: missing `{ ... }` for function literal
+fail_compilation/failcontracts.d(18): Error: semicolon expected following auto declaration, not `bode`
+fail_compilation/failcontracts.d(19): Error: function declaration without return type
+fail_compilation/failcontracts.d(19):        Note that constructors are always named `this`
+fail_compilation/failcontracts.d(19): Error: variable name expected after type `test1()`, not `bode`
 fail_compilation/failcontracts.d(19): Error: semicolon expected following function declaration, not `bode`
-fail_compilation/failcontracts.d(21): Error: unexpected `(` in declarator
-fail_compilation/failcontracts.d(21): Error: found `T` when expecting `)`
-fail_compilation/failcontracts.d(21): Error: expected `{`, not `;` for enum declaration
+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: expected `{`, not `;` for enum declaration
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fix19613.d b/gcc/testsuite/gdc.test/fail_compilation/fix19613.d
new file mode 100644
index 000000000000..beca56fd7091
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fix19613.d
@@ -0,0 +1,16 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fix19613.d(15): Error: function `fix19613.B.a` cannot override `final` function `fix19613.A.a`
+fail_compilation/fix19613.d(15): Error: function `fix19613.B.a` does not override any function
+fail_compilation/fix19613.d(15):        Did you mean to override `void fix19613.A.a(string)`?
+---
+*/
+
+class A {
+        final void a(int) {}
+        void a(string) {}
+}
+class B : A {
+        override void a(int) {}
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fix20075.d b/gcc/testsuite/gdc.test/fail_compilation/fix20075.d
new file mode 100644
index 000000000000..00f229d326b3
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fix20075.d
@@ -0,0 +1,21 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fix20075.d(15): Error: none of the overloads of `this` can construct an immutable object with argument types `(int*)`. Expected `immutable(int*)`
+fail_compilation/fix20075.d(11):        Candidate is: `fix20075.Foo.this(immutable(int*) a) immutable`
+---
+*/
+
+struct Foo {
+    @disable this();
+    immutable this(immutable int* a) {}
+}
+
+immutable(Foo) getFoo(int* a) {
+    return immutable Foo(a);
+}
+
+void main() {
+    int x;
+    auto foo = getFoo(&x);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fix20318.d b/gcc/testsuite/gdc.test/fail_compilation/fix20318.d
new file mode 100644
index 000000000000..f32030001278
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fix20318.d
@@ -0,0 +1,46 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fix20318.d(16): Error: cannot implicitly convert expression `c` of type `const(Bar)` to `Bar` because struct `Bar` contains pointers or references
+fail_compilation/fix20318.d(20): Error: cannot implicitly convert expression `complex_c` of type `const(ComplexBar)` to `ComplexBar` because struct `ComplexBar` contains pointers or references
+---
+*/
+
+void main() {
+    // This should work - struct without pointers
+    const Foo a;
+    Foo b = a; // This is okay
+
+    // This should fail with improved diagnostic message
+    const Bar c;
+    Bar d = c; // Error with improved diagnostic message
+
+    // Test with a more complex struct with nested pointers
+    const ComplexBar complex_c;
+    ComplexBar complex_d = complex_c; // Give improved error message
+}
+
+struct Foo {
+    int value;
+}
+
+struct Bar {
+    void* ptr;
+}
+
+// Simple struct without pointers
+struct Simple {
+    int value;
+}
+
+// Struct with a pointer
+struct WithPointer {
+    int* ptr;
+}
+
+// Complex struct that contains another struct with pointers
+struct ComplexBar {
+    Simple simple;       // This is fine
+    int data;            // This is fine
+    WithPointer nested;  // This field prevents implicit conversion
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fix20867.d b/gcc/testsuite/gdc.test/fail_compilation/fix20867.d
new file mode 100644
index 000000000000..0ccad0980317
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fix20867.d
@@ -0,0 +1,20 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fix20867.d(14): Error: cannot use `final switch` on enum `E` while it is being defined
+---
+*/
+
+// Test case from Issue #20867
+enum E
+{
+    a = 3,
+    b = () {
+        E e;
+        final switch (e)  // This should error out instead of segfaulting
+        {
+            case E.a: break;
+        }
+        return 4;
+    } ()
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fix21042.d b/gcc/testsuite/gdc.test/fail_compilation/fix21042.d
new file mode 100644
index 000000000000..b2b224e5196e
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fix21042.d
@@ -0,0 +1,15 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fix21042.d(14): Error: template `gun` is not callable using argument types `!()(int)`
+fail_compilation/fix21042.d(14):        no parameter named `x`
+fail_compilation/fix21042.d(10):        Candidate is: `gun(T)(T a)`
+---
+*/
+
+void gun(T)(T a) {}
+
+void main()
+{
+	gun(x: 1); // (no explanation) --> (no parameter named `x`)
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fix21165.d b/gcc/testsuite/gdc.test/fail_compilation/fix21165.d
new file mode 100644
index 000000000000..1d38013b4df0
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fix21165.d
@@ -0,0 +1,30 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fix21165.d(12): Error: undefined identifier `foo`
+fail_compilation/fix21165.d(16): Error: undefined identifier `foo`
+fail_compilation/fix21165.d(21): Error: undefined identifier `foo`
+fail_compilation/fix21165.d(30): Error: undefined identifier `foo`
+---
+*/
+
+// Test case from Issue #21165
+foo
+f() {}
+
+// Test case from Issue #21171
+foo
+bar;
+
+// Test case from Issue #21169
+void fun(
+	foo x
+) {}
+
+// Test case from Issue #21168
+enum plusOne(int x) = x + 1;
+
+alias fooPlusOne =
+	plusOne
+	!
+	foo;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fix21166.d b/gcc/testsuite/gdc.test/fail_compilation/fix21166.d
new file mode 100644
index 000000000000..24dbf8b4675c
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fix21166.d
@@ -0,0 +1,13 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fix21166.d(12): Error: invalid array operation `"foo" + "bar"` (possible missing [])
+fail_compilation/fix21166.d(12):        did you mean to concatenate (`"foo" ~ "bar"`) instead ?
+---
+*/
+
+// Test case for https://github.com/dlang/dmd/issues/21166
+auto r =
+	"foo"
+	+
+	"bar";
diff --git a/gcc/testsuite/gdc.test/fail_compilation/hidden_ctor.d b/gcc/testsuite/gdc.test/fail_compilation/hidden_ctor.d
new file mode 100644
index 000000000000..8d6e6959f29b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/hidden_ctor.d
@@ -0,0 +1,27 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/hidden_ctor.d(25): Error: constructor `hidden_ctor.B.this(string s)` is not callable using argument types `()`
+fail_compilation/hidden_ctor.d(25):        Note: constructor `hidden_ctor.B.this` hides base class constructor `hidden_ctor.A.this`
+---
+*/
+
+class A {
+    int a;
+
+    this() {
+        this.a = 1;
+    }
+}
+class B : A {
+    string b;
+
+    this(string s) {
+        super();
+        this.b = s;
+    }
+}
+void main() {
+    auto b = new B();
+    b = new B("Hi, Mom!");
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11153.d b/gcc/testsuite/gdc.test/fail_compilation/ice11153.d
index 826bd8cd7ec1..936d987c1528 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice11153.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice11153.d
@@ -1,8 +1,9 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/ice11153.d(11): Error: function declaration without return type. (Note that constructors are always named `this`)
-fail_compilation/ice11153.d(11): Error: variable name expected after type `foo()`, not `{`
+fail_compilation/ice11153.d(12): Error: function declaration without return type
+fail_compilation/ice11153.d(12):        Note that constructors are always named `this`
+fail_compilation/ice11153.d(12): Error: variable name expected after type `foo()`, not `{`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice19755.d b/gcc/testsuite/gdc.test/fail_compilation/ice19755.d
index 6d60fc43c1b2..2770676294c2 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice19755.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice19755.d
@@ -1,7 +1,8 @@
 /* TEST_OUTPUT:
 ---
-fail_compilation/ice19755.d(11): Error: no property `x` for `self` of type `ice19755.Thunk!int*`
-fail_compilation/ice19755.d(16): Error: template instance `ice19755.Thunk!int` error instantiating
+fail_compilation/ice19755.d(12): Error: no property `x` for `self` of type `ice19755.Thunk!int*`
+fail_compilation/ice19755.d(8):        struct `Thunk` defined here
+fail_compilation/ice19755.d(17): Error: template instance `ice19755.Thunk!int` error instantiating
 ---
 */
 struct Thunk(Dummy) {
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/imp18127a.c b/gcc/testsuite/gdc.test/fail_compilation/imports/imp18127a.c
new file mode 100644
index 000000000000..2ef629e3b5b2
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/imp18127a.c
@@ -0,0 +1,83 @@
+// https://github.com/dlang/dmd/issues/18127
+// union in here, struct in other
+union struct_or_union {
+    int x;
+};
+
+// mismatching number of fields
+struct S_n_fields {
+    int x, y;
+};
+
+// mismatched types
+struct S_types {
+    float x;
+};
+
+// mismatched names
+struct S_names {
+    float x;
+};
+
+struct B {
+    int x;
+};
+
+// Contains a struct that is incompatible
+struct S_b {
+    struct B b;
+};
+
+// mismatched anonymous struct
+struct S_contains_anon_named {
+    struct {
+        int x;
+    } a;
+};
+
+struct S_contains_anon_unnamed {
+    struct {
+        int x;
+    };
+};
+
+// bitfields
+struct S_bitfields_mismatch1 {
+    unsigned x: 3;
+    unsigned y: 1;
+};
+struct S_bitfields_mismatch2 {
+    unsigned x;
+    unsigned y: 1;
+};
+
+struct S_bitfields_widths {
+    unsigned x: 3;
+    unsigned y: 1;
+};
+
+struct S_bitfields_anon {
+    unsigned x: 3;
+    unsigned : 1;
+};
+
+// mismatched alignment
+struct S_alignas {
+    _Alignas(8) float x;
+};
+struct S_aligned {
+    float x;
+}__attribute__((aligned(8)));
+
+// mismatched packing
+struct __attribute__((packed)) S_pack_1 {
+    float x;
+    char c;
+};
+#pragma pack(push)
+#pragma pack(1)
+struct S_pack_2 {
+    float x;
+    char c;
+};
+#pragma pack(pop)
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/imp18127b.c b/gcc/testsuite/gdc.test/fail_compilation/imports/imp18127b.c
new file mode 100644
index 000000000000..3cbbf7a9a638
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/imp18127b.c
@@ -0,0 +1,80 @@
+// https://github.com/dlang/dmd/issues/18127
+// struct in here, union in other
+struct struct_or_union {
+    int x;
+};
+
+// mismatching number of fields
+struct S_n_fields {
+    int x;
+};
+
+// mismatched types
+struct S_types {
+    int x;
+};
+
+// mismatched names
+struct S_names {
+    float y;
+};
+
+struct B {
+    float x;
+};
+
+// Contains a struct that is incompatible
+struct S_b {
+    struct B b;
+};
+
+// mismatched anonymous struct
+struct S_contains_anon_named {
+    struct {
+        float x;
+    } a;
+};
+
+struct S_contains_anon_unnamed {
+    struct {
+        float x;
+    };
+};
+
+// bitfields
+struct S_bitfields_mismatch1 {
+    unsigned x: 3;
+    unsigned y;
+};
+struct S_bitfields_mismatch2 {
+    unsigned x: 3;
+    unsigned y: 1;
+};
+
+struct S_bitfields_widths {
+    unsigned x: 3;
+    unsigned y: 2;
+};
+
+struct S_bitfields_anon {
+    unsigned x: 3;
+    unsigned y: 1;
+};
+
+// mismatched alignment
+struct S_alignas {
+    float x;
+};
+struct S_aligned {
+    float x;
+}__attribute__((aligned(4)));
+
+// mismatched packing
+struct S_pack_1 {
+    float x;
+    char c;
+};
+struct S_pack_2 {
+    float x;
+    char c;
+};
diff --git a/gcc/testsuite/gdc.test/fail_compilation/lookup.d b/gcc/testsuite/gdc.test/fail_compilation/lookup.d
index fe752f2f4d74..db7eedab30ac 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/lookup.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/lookup.d
@@ -2,10 +2,12 @@
 EXTRA_FILES: imports/imp1.d imports/imp2.d
 TEST_OUTPUT:
 ---
-fail_compilation/lookup.d(24): Error: no property `X` for type `lookup.B`, did you mean `imports.imp2.X`?
-fail_compilation/lookup.d(24):        while evaluating: `static assert((B).X == 0)`
-fail_compilation/lookup.d(25): Error: no property `Y` for type `lookup.B`, did you mean `imports.imp2.Y`?
-fail_compilation/lookup.d(25):        while evaluating: `static assert((B).Y == 2)`
+fail_compilation/lookup.d(26): Error: no property `X` for type `lookup.B`
+fail_compilation/imports/imp2.d(3):        did you mean `imports.imp2.X`?
+fail_compilation/lookup.d(26):        while evaluating: `static assert((B).X == 0)`
+fail_compilation/lookup.d(27): Error: no property `Y` for type `lookup.B`
+fail_compilation/imports/imp2.d(4):        did you mean `imports.imp2.Y`?
+fail_compilation/lookup.d(27):        while evaluating: `static assert((B).Y == 2)`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/mixinprop.d b/gcc/testsuite/gdc.test/fail_compilation/mixinprop.d
index db8bf5968ddc..103c6b2a0473 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/mixinprop.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/mixinprop.d
@@ -1,9 +1,9 @@
 /* TEST_OUTPUT:
 ---
-fail_compilation/mixinprop.d(12): Error: no property `x` for `mixin Foo!() F;
-` of type `void`
+fail_compilation/mixinprop.d(12): Error: no property `x` for `mixin Foo!() F;` of type `void`
 ---
 */
+
 mixin template Foo() { }
 
 void main()
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 125ebcc926e5..761e1d4c78c1 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d
@@ -1,26 +1,27 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/named_arguments_error.d(37): Error: function `f` is not callable using argument types `(int, int, int)`
-fail_compilation/named_arguments_error.d(37):        parameter `x` assigned twice
-fail_compilation/named_arguments_error.d(31):        `named_arguments_error.f(int x, int y, int z)` declared here
 fail_compilation/named_arguments_error.d(38): Error: function `f` is not callable using argument types `(int, int, int)`
-fail_compilation/named_arguments_error.d(38):        argument `4` goes past end of parameter list
-fail_compilation/named_arguments_error.d(31):        `named_arguments_error.f(int x, int y, int z)` declared here
+fail_compilation/named_arguments_error.d(38):        parameter `x` assigned twice
+fail_compilation/named_arguments_error.d(32):        `named_arguments_error.f(int x, int y, int z)` declared here
 fail_compilation/named_arguments_error.d(39): Error: function `f` is not callable using argument types `(int, int, int)`
-fail_compilation/named_arguments_error.d(39):        parameter `y` assigned twice
-fail_compilation/named_arguments_error.d(31):        `named_arguments_error.f(int x, int y, int z)` declared here
+fail_compilation/named_arguments_error.d(39):        argument `4` goes past end of parameter list
+fail_compilation/named_arguments_error.d(32):        `named_arguments_error.f(int x, int y, int z)` declared here
 fail_compilation/named_arguments_error.d(40): Error: function `f` is not callable using argument types `(int, int, int)`
-fail_compilation/named_arguments_error.d(40):        no parameter named `a`
-fail_compilation/named_arguments_error.d(31):        `named_arguments_error.f(int x, int y, int z)` declared here
-fail_compilation/named_arguments_error.d(41): Error: function `g` is not callable using argument types `(int, int)`
-fail_compilation/named_arguments_error.d(41):        missing argument for parameter #1: `int x`
-fail_compilation/named_arguments_error.d(33):        `named_arguments_error.g(int x, int y, int z = 3)` declared here
-fail_compilation/named_arguments_error.d(43): Error: no named argument `element` allowed for array dimension
-fail_compilation/named_arguments_error.d(44): Error: no named argument `number` allowed for scalar
-fail_compilation/named_arguments_error.d(45): Error: cannot implicitly convert expression `g(x: 3, y: 4, z: 5)` of type `int` to `string`
-fail_compilation/named_arguments_error.d(46): Error: template `tempfun` is not callable using argument types `!()(int, int)`
-fail_compilation/named_arguments_error.d(49):        Candidate is: `tempfun(T, U)(T t, U u)`
+fail_compilation/named_arguments_error.d(40):        parameter `y` assigned twice
+fail_compilation/named_arguments_error.d(32):        `named_arguments_error.f(int x, int y, int z)` declared here
+fail_compilation/named_arguments_error.d(41): Error: function `f` is not callable using argument types `(int, int, int)`
+fail_compilation/named_arguments_error.d(41):        no parameter named `a`
+fail_compilation/named_arguments_error.d(32):        `named_arguments_error.f(int x, int y, int z)` declared here
+fail_compilation/named_arguments_error.d(42): Error: function `g` is not callable using argument types `(int, int)`
+fail_compilation/named_arguments_error.d(42):        missing argument for parameter #1: `int x`
+fail_compilation/named_arguments_error.d(34):        `named_arguments_error.g(int x, int y, int z = 3)` declared here
+fail_compilation/named_arguments_error.d(44): Error: no named argument `element` allowed for array dimension
+fail_compilation/named_arguments_error.d(45): Error: no named argument `number` allowed for scalar
+fail_compilation/named_arguments_error.d(46): Error: cannot implicitly convert expression `g(x: 3, y: 4, z: 5)` of type `int` to `string`
+fail_compilation/named_arguments_error.d(47): Error: template `tempfun` is not callable using argument types `!()(int, int)`
+fail_compilation/named_arguments_error.d(47):        argument `1` goes past end of parameter list
+fail_compilation/named_arguments_error.d(50):        Candidate is: `tempfun(T, U)(T t, U u)`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/named_arguments_ifti_error.d b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_ifti_error.d
index 6d8a70a2c469..a73fd3cb2e6f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/named_arguments_ifti_error.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_ifti_error.d
@@ -1,12 +1,15 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/named_arguments_ifti_error.d(17): Error: template `f` is not callable using argument types `!()(int, int)`
-fail_compilation/named_arguments_ifti_error.d(13):        Candidate is: `f(T, U)(T x, U y)`
-fail_compilation/named_arguments_ifti_error.d(18): Error: template `f` is not callable using argument types `!()(int, int)`
-fail_compilation/named_arguments_ifti_error.d(13):        Candidate is: `f(T, U)(T x, U y)`
-fail_compilation/named_arguments_ifti_error.d(19): Error: template `f` is not callable using argument types `!()(int)`
-fail_compilation/named_arguments_ifti_error.d(13):        Candidate is: `f(T, U)(T x, U y)`
+fail_compilation/named_arguments_ifti_error.d(20): Error: template `f` is not callable using argument types `!()(int, int)`
+fail_compilation/named_arguments_ifti_error.d(20):        parameter `x` assigned twice
+fail_compilation/named_arguments_ifti_error.d(16):        Candidate is: `f(T, U)(T x, U y)`
+fail_compilation/named_arguments_ifti_error.d(21): Error: template `f` is not callable using argument types `!()(int, int)`
+fail_compilation/named_arguments_ifti_error.d(21):        argument `3` goes past end of parameter list
+fail_compilation/named_arguments_ifti_error.d(16):        Candidate is: `f(T, U)(T x, U y)`
+fail_compilation/named_arguments_ifti_error.d(22): Error: template `f` is not callable using argument types `!()(int)`
+fail_compilation/named_arguments_ifti_error.d(22):        missing argument for parameter #1: `T x`
+fail_compilation/named_arguments_ifti_error.d(16):        Candidate is: `f(T, U)(T x, U y)`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/nogc3.d b/gcc/testsuite/gdc.test/fail_compilation/nogc3.d
index 17daa96358b1..f1a469b5445f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/nogc3.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/nogc3.d
@@ -94,3 +94,33 @@ int[] bar13702(bool b) @nogc
     auto aux = 1 ~ [2]; // error
     return aux;
 }
+
+/**********  Enum and pointer types ***************/
+// https://github.com/dlang/dmd/issues/21052
+/*
+TEST_OUTPUT:
+---
+fail_compilation/nogc3.d(111): Error: this array literal causes a GC allocation in `@nogc` function `f`
+fail_compilation/nogc3.d(112): Error: this array literal causes a GC allocation in `@nogc` function `f`
+---
+*/
+
+void f() @nogc
+{
+    enum DA : int[] { a = [1,2,3] }
+    DA da = DA.a;
+    int i = *cast(int*)cast(char[4])['0', '0', '0', '0'];
+}
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/nogc3.d(125): Error: this array literal causes a GC allocation in `@nogc` function `g`
+---
+*/
+
+// https://github.com/dlang/dmd/issues/21054
+void g() @nogc
+{
+    int[] x = (int[2]).init[];
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/nonvoid_return.d b/gcc/testsuite/gdc.test/fail_compilation/nonvoid_return.d
new file mode 100644
index 000000000000..bcced1b9bff2
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/nonvoid_return.d
@@ -0,0 +1,37 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/nonvoid_return.d(15): Error: cannot return non-void from `void` function
+fail_compilation/nonvoid_return.d(18): Error: cannot return non-void from `void` function
+fail_compilation/nonvoid_return.d(29): Error: cannot return non-void from `void` function
+fail_compilation/nonvoid_return.d(32): Error: undefined identifier `NONEXISTENT`
+---
+*/
+
+
+
+void main()
+{
+    return 10;
+}
+
+void fs() => "a";
+
+class MyClass
+{
+}
+
+MyClass[char[]] myarray;
+
+void fn()
+{
+    foreach (MyClass mc; myarray)
+        return mc;
+}
+
+auto err() { NONEXISTENT++; }
+
+// Because `err` contains an error, it fails to infer void and gets an error return type
+// Don't print the 'cannot return non-void' error in this case
+
+void fe() => err;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/noreturn2.d b/gcc/testsuite/gdc.test/fail_compilation/noreturn2.d
index ec6bd3ebce99..b49417436a53 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/noreturn2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/noreturn2.d
@@ -117,7 +117,7 @@ TEST_OUTPUT:
 ---
 fail_compilation/noreturn2.d(130): Error: cannot create instance of interface `I`
 fail_compilation/noreturn2.d(133): Error: can only throw class objects derived from `Throwable`, not type `int[]`
-fail_compilation/noreturn2.d(138): Error: undefined identifier `UnkownException`
+fail_compilation/noreturn2.d(139): Error: undefined identifier `UnkownException`
 ---
 +/
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/powinline.d b/gcc/testsuite/gdc.test/fail_compilation/powinline.d
new file mode 100644
index 000000000000..11ebacd16aaa
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/powinline.d
@@ -0,0 +1,38 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/powinline.d(25): Error: cannot implicitly convert expression `(a + 5.0) ^^ 2L` of type `double` to `int`
+fail_compilation/powinline.d(26): Error: cannot implicitly convert expression `(1.0 / foo()) ^^ 2L` of type `double` to `int`
+fail_compilation/powinline.d(31): Error: void has no value
+fail_compilation/powinline.d(31): Error: incompatible types for `(5.0) * (bar())`: `double` and `void`
+fail_compilation/powinline.d(37): Error: cannot modify `immutable` expression `a`
+---
+*/
+
+double foo()
+{
+    return 5.0;
+}
+
+void bar()
+{
+    return;
+}
+
+void test1()
+{
+    double a = 2.0;
+    int b = (a + 5.0) ^^ 2.0;
+    b = (1 / foo()) ^^ 2.0;
+}
+
+void test2()
+{
+    double a = (5.0 * bar()) ^^ 2.0;
+}
+
+void test3()
+{
+    immutable double a = 3.0;
+    (a ^^= 2.0) = 6;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope3.d b/gcc/testsuite/gdc.test/fail_compilation/retscope3.d
index 438fdd76e1b0..8802469de2c4 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/retscope3.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/retscope3.d
@@ -55,7 +55,9 @@ TEST_OUTPUT:
 ---
 fail_compilation/retscope3.d(4003): Error: escaping a reference to parameter `u` by copying `u[]` into allocated memory is not allowed in a `@safe` function
 fail_compilation/retscope3.d(4016): Error: storing reference to outer local variable `i` into allocated memory causes it to escape
+fail_compilation/retscope3.d(4025): Deprecation: slice of static array temporary returned by `makeSA()` assigned to longer lived variable `a`
 fail_compilation/retscope3.d(4025): Error: escaping reference to stack allocated value returned by `makeSA()` into allocated memory
+fail_compilation/retscope3.d(4032): Error: escaping a reference to local variable `i` by copying `& i` into allocated memory is not allowed in a `@safe` function
 ---
 */
 
@@ -87,3 +89,11 @@ void bar4003() @safe
 {
     int[][] a = [makeSA()[]];
 }
+
+// https://github.com/dlang/dmd/issues/20901
+int* f20901() @safe
+{
+    int i = 3;
+    auto x = &[&i][0]; // Should error, i is escaped into allocated memory
+    return *x;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/seq_assign.d b/gcc/testsuite/gdc.test/fail_compilation/seq_assign.d
new file mode 100644
index 000000000000..560bc344242c
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/seq_assign.d
@@ -0,0 +1,43 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/seq_assign.d(28): Error: cannot assign `int` to expression sequence `(int)`
+fail_compilation/seq_assign.d(29): Error: cannot implicitly convert expression `s` of type `string` to `int`
+fail_compilation/seq_assign.d(30): Error: cannot modify constant `2`
+fail_compilation/seq_assign.d(31): Error: mismatched sequence lengths, 1 and 2
+fail_compilation/seq_assign.d(35): Error: mismatched sequence lengths, 1 and 2
+fail_compilation/seq_assign.d(36): Error: cannot implicitly convert expression `__t_field_0` of type `string` to `int`
+fail_compilation/seq_assign.d(40): Error: cannot assign `IntString` to expression sequence `(string, int)`
+fail_compilation/seq_assign.d(42): Error: cannot implicitly convert expression `AliasSeq!(b, c)` of type `(int, int)` to `IntString`
+---
+*/
+
+alias Seq(A...) = A;
+
+struct IntString
+{
+    Seq!(int, string) expand;
+    alias this = expand;
+}
+
+void main()
+{
+    int b, c;
+    string s;
+
+    Seq!(b,) = 1; // RHS not seq
+    Seq!(b,) = Seq!(s,); // b type error
+    Seq!(2,) = Seq!(1,); // not lvalue
+    Seq!(b,) = Seq!(1, 2); // too many
+
+    auto t = Seq!("two", 3);
+    Seq!(s, b) = t; // OK
+    Seq!(b,) = t; // too many
+    Seq!(b, c) = t; // b type error
+
+    IntString t2;
+    Seq!(b, s) = t2; // OK
+    t = t2; // type mismatch
+    t2 = Seq!(b, s); // OK
+    t2 = Seq!(b, c); // c wrong type
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15989.d b/gcc/testsuite/gdc.test/fail_compilation/test15989.d
index 38ca33126724..85b74bfad583 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test15989.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test15989.d
@@ -1,9 +1,11 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/test15989.d(39): Error: variable `test15989.main.ctRegex` : Unable to initialize enum with class or pointer to struct. Use static const variable instead.
-fail_compilation/test15989.d(48): Error: variable `test15989.test.c` : Unable to initialize enum with class or pointer to struct. Use static const variable instead.
-fail_compilation/test15989.d(49): Error: cannot use non-constant CTFE pointer in an initializer `new int(3)`
+fail_compilation/test15989.d(41): Error: variable `test15989.main.ctRegex` : Unable to initialize enum with class or pointer to struct
+fail_compilation/test15989.d(41):        use static const variable instead
+fail_compilation/test15989.d(50): Error: variable `test15989.test.c` : Unable to initialize enum with class or pointer to struct
+fail_compilation/test15989.d(50):        use static const variable instead
+fail_compilation/test15989.d(51): Error: cannot use non-constant CTFE pointer in an initializer `new int(3)`
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test18127.d b/gcc/testsuite/gdc.test/fail_compilation/test18127.d
new file mode 100644
index 000000000000..ec0487cd8925
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test18127.d
@@ -0,0 +1,106 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/imports/imp18127b.c(3): Error: struct `struct_or_union` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(3):        previously declared here
+fail_compilation/imports/imp18127b.c(3):        `imp18127b.struct_or_union` is a struct while `imp18127a.struct_or_union` is a union
+fail_compilation/imports/imp18127b.c(3):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(8): Error: struct `S_n_fields` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(8):        previously declared here
+fail_compilation/imports/imp18127b.c(8):        `imp18127b.S_n_fields` has 1 field(s) while `imp18127a.S_n_fields` has 2 field(s)
+fail_compilation/imports/imp18127b.c(8):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(13): Error: struct `S_types` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(13):        previously declared here
+fail_compilation/imports/imp18127b.c(14):        Field 0 differs in type
+fail_compilation/imports/imp18127b.c(14):        typeof(x): int
+fail_compilation/imports/imp18127a.c(14):        typeof(x): float
+fail_compilation/imports/imp18127b.c(13):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(18): Error: struct `S_names` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(18):        previously declared here
+fail_compilation/imports/imp18127b.c(19):        Field 0 differs in name
+fail_compilation/imports/imp18127b.c(19):        y
+fail_compilation/imports/imp18127a.c(19):        x
+fail_compilation/imports/imp18127b.c(18):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(22): Error: struct `B` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(22):        previously declared here
+fail_compilation/imports/imp18127b.c(23):        Field 0 differs in type
+fail_compilation/imports/imp18127b.c(23):        typeof(x): float
+fail_compilation/imports/imp18127a.c(23):        typeof(x): int
+fail_compilation/imports/imp18127b.c(22):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(27): Error: struct `S_b` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(27):        previously declared here
+fail_compilation/imports/imp18127b.c(27):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(33): Error: struct `(anonymous struct)` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(33):        previously declared here
+fail_compilation/imports/imp18127b.c(34):        Field 0 differs in type
+fail_compilation/imports/imp18127b.c(34):        typeof(x): float
+fail_compilation/imports/imp18127a.c(34):        typeof(x): int
+fail_compilation/imports/imp18127b.c(32): Error: struct `S_contains_anon_named` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(32):        previously declared here
+fail_compilation/imports/imp18127b.c(35):        Field 0 differs in type
+fail_compilation/imports/imp18127b.c(35):        typeof(a): (anonymous struct)
+fail_compilation/imports/imp18127a.c(35):        typeof(a): (anonymous struct)
+fail_compilation/imports/imp18127b.c(32):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(38): Error: struct `S_contains_anon_unnamed` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(38):        previously declared here
+fail_compilation/imports/imp18127b.c(40):        Field 0 differs in type
+fail_compilation/imports/imp18127b.c(40):        typeof(x): float
+fail_compilation/imports/imp18127a.c(40):        typeof(x): int
+fail_compilation/imports/imp18127b.c(38):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(45): Error: struct `S_bitfields_mismatch1` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(45):        previously declared here
+fail_compilation/imports/imp18127b.c(47):        Field 1 differs in being a bitfield
+fail_compilation/imports/imp18127b.c(47):        `imp18127b.S_bitfields_mismatch1.y` is not a bitfield
+fail_compilation/imports/imp18127a.c(47):        `imp18127a.S_bitfields_mismatch1.y` is a bitfield
+fail_compilation/imports/imp18127b.c(45):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(49): Error: struct `S_bitfields_mismatch2` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(49):        previously declared here
+fail_compilation/imports/imp18127b.c(50):        Field 0 differs in being a bitfield
+fail_compilation/imports/imp18127b.c(50):        `imp18127b.S_bitfields_mismatch2.x` *is a bitfield
+fail_compilation/imports/imp18127a.c(50):        `imp18127a.S_bitfields_mismatch2.x` is not a bitfield
+fail_compilation/imports/imp18127b.c(49):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(54): Error: struct `S_bitfields_widths` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(54):        previously declared here
+fail_compilation/imports/imp18127b.c(56):        Field 1 differs in bitfield width
+fail_compilation/imports/imp18127b.c(56):        `imp18127b.S_bitfields_widths.y`: 2
+fail_compilation/imports/imp18127a.c(56):        `imp18127a.S_bitfields_widths.y`: 1
+fail_compilation/imports/imp18127b.c(54):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(59): Error: struct `S_bitfields_anon` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(59):        previously declared here
+fail_compilation/imports/imp18127b.c(61):        Field 1 differs in name
+fail_compilation/imports/imp18127b.c(61):        y
+fail_compilation/imports/imp18127a.c(61):        (anonymous)
+fail_compilation/imports/imp18127b.c(59):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(65): Error: struct `S_alignas` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(65):        previously declared here
+fail_compilation/imports/imp18127b.c(66):        Field 0 differs in alignment or packing
+fail_compilation/imports/imp18127b.c(66):        `imp18127b.S_alignas.x` alignment: default
+fail_compilation/imports/imp18127a.c(66):        `imp18127a.S_alignas.x` alignment: 8
+fail_compilation/imports/imp18127b.c(65):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(68): Error: struct `S_aligned` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(68):        previously declared here
+fail_compilation/imports/imp18127b.c(68):        `imp18127b.S_aligned` has different alignment or packing
+fail_compilation/imports/imp18127b.c(68):        `imp18127b.S_aligned` alignment: 4
+fail_compilation/imports/imp18127a.c(68):        `imp18127a.S_aligned` alignment: 8
+fail_compilation/imports/imp18127b.c(68):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(73): Error: struct `S_pack_1` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(73):        previously declared here
+fail_compilation/imports/imp18127b.c(73):        `imp18127b.S_pack_1` has different alignment or packing
+fail_compilation/imports/imp18127b.c(73):        `imp18127b.S_pack_1` alignment: default
+fail_compilation/imports/imp18127a.c(73):        `imp18127a.S_pack_1` alignment: 1
+fail_compilation/imports/imp18127b.c(73):        `imp18127b.S_pack_1` packed: false
+fail_compilation/imports/imp18127a.c(73):        `imp18127a.S_pack_1` packed: true
+fail_compilation/imports/imp18127b.c(73):        C structs with the same name from different imports are merged
+fail_compilation/imports/imp18127b.c(77): Error: struct `S_pack_2` already exists with an incompatible definition.
+fail_compilation/imports/imp18127a.c(79):        previously declared here
+fail_compilation/imports/imp18127b.c(77):        `imp18127b.S_pack_2` has different alignment or packing
+fail_compilation/imports/imp18127b.c(77):        `imp18127b.S_pack_2` alignment: default
+fail_compilation/imports/imp18127a.c(79):        `imp18127a.S_pack_2` alignment: 1
+fail_compilation/imports/imp18127b.c(77):        C structs with the same name from different imports are merged
+---
+*/
+
+// https://github.com/dlang/dmd/issues/18127
+
+import imports.imp18127a;
+import imports.imp18127b;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test19661.d b/gcc/testsuite/gdc.test/fail_compilation/test19661.d
index 369c0a862495..712721487caa 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test19661.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test19661.d
@@ -2,7 +2,8 @@
 EXTRA_FILES: imports/imp19661.d
 TEST_OUTPUT:
 ---
-fail_compilation/test19661.d(11): Error: variables cannot be initialized with an expression of type `void`. Use `void` initialization instead.
+fail_compilation/test19661.d(12): Error: variables cannot be initialized with an expression of type `void`
+fail_compilation/test19661.d(12):        only `= void;` is allowed, which prevents default initialization
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test20489.d b/gcc/testsuite/gdc.test/fail_compilation/test20489.d
new file mode 100644
index 000000000000..1cd5350959c5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test20489.d
@@ -0,0 +1,20 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test20489.d(19): Error: function `pure nothrow @nogc @safe int test20489.D.f(int delegate(int) pure nothrow @nogc @safe body)` does not override any function, did you mean to override `pure nothrow @nogc @safe int test20489.B.f(scope int delegate(int) pure nothrow @nogc @safe)`?
+fail_compilation/test20489.d(19):        Did you intend to override:
+fail_compilation/test20489.d(19):        `pure nothrow @nogc @safe int test20489.B.f(scope int delegate(int) pure nothrow @nogc @safe)`
+fail_compilation/test20489.d(19):        Parameter 1 is missing `scope`
+---
+*/
+
+// Test case for https://github.com/dlang/dmd/issues/20489
+// Improved error message on override mismatches
+
+class B {
+    pure nothrow @nogc @safe int f(scope int delegate(int) pure nothrow @nogc @safe) { return 0; }
+}
+
+class D : B {
+    override pure nothrow @nogc @safe int f(int delegate(int) pure nothrow @nogc @safe body) { return 0; }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21215.d b/gcc/testsuite/gdc.test/fail_compilation/test21215.d
new file mode 100644
index 000000000000..5efa315723c2
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21215.d
@@ -0,0 +1,35 @@
+/* TEST_OUTPUT:
+---
+fail_compilation/test21215.d(13): Error: `y` is not a member of `S`
+fail_compilation/test21215.d(18): Error: `xhs` is not a member of `S`, did you mean variable `xsh`?
+fail_compilation/test21215.d(28): Error: `y` is not a member of `S`
+fail_compilation/test21215.d(32): Error: `yashu` is not a member of `S`
+---
+*/
+struct S { int xsh; }
+
+void test() {
+	auto s1 = S(
+		y:
+    1
+	);
+
+  auto s2 = S(
+    xhs:
+    1
+  );
+
+  auto s3 = S(
+    xsh: 1
+  );
+
+  auto s4 = S(
+    xsh: 1,
+    y: 2
+  );
+
+  auto s5 = S(
+    yashu:
+    2
+  );
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21304.d b/gcc/testsuite/gdc.test/fail_compilation/test21304.d
new file mode 100644
index 000000000000..9789e2b9c956
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21304.d
@@ -0,0 +1,6 @@
+/* TEST_OUTPUT:
+---
+fail_compilation/test21304.d(6): Error: undefined identifier `unknown`
+---
+*/
+int[unknown] values = [1, 2, 3];
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21317.d b/gcc/testsuite/gdc.test/fail_compilation/test21317.d
new file mode 100644
index 000000000000..39b3963799eb
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21317.d
@@ -0,0 +1,39 @@
+module dmd.compiler.test.fail_compilation.test21317;
+
+/* TEST_OUTPUT:
+---
+fail_compilation/test21317.d(16): Error: `writeln` is not defined, perhaps `import std.stdio;` ?
+fail_compilation/test21317.d(21): Error: undefined identifier `Zero`, did you mean variable `zero`?
+fail_compilation/test21317.d(25): Error: undefined identifier `NULL`, did you mean `null`?
+fail_compilation/test21317.d(31): Error: undefined identifier `this`, did you mean `typeof(this)`?
+fail_compilation/test21317.d(38): Error: undefined identifier `unknown`
+---
+*/
+
+// Weird formatting is intended to check the loc
+
+int[
+  writeln
+  ] arr1;
+
+int zero = 0;
+int [
+  Zero
+  ] arr2;
+
+int [
+  NULL
+  ] arr3;
+
+struct S4
+{
+    enum E4 :
+    this
+    {
+        fail,
+    }
+}
+
+int [
+  unknown
+  ] arr5;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/testrvaluecpctor.d b/gcc/testsuite/gdc.test/fail_compilation/testrvaluecpctor.d
index 1173d14480d0..a0ade760fe52 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/testrvaluecpctor.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/testrvaluecpctor.d
@@ -5,7 +5,7 @@ TEST_OUTPUT:
 ---
 fail_compilation/testrvaluecpctor.d(16): Error: cannot define both an rvalue constructor and a copy constructor for `struct Foo`
 fail_compilation/testrvaluecpctor.d(24):        Template instance `testrvaluecpctor.Foo!int.Foo.__ctor!(immutable(Foo!int), immutable(Foo!int))` creates an rvalue constructor for `struct Foo`
-fail_compilation/testrvaluecpctor.d(24): Error: none of the overloads of `this` can construct a `immutable` object with argument types `(immutable(Foo!int))`
+fail_compilation/testrvaluecpctor.d(24): Error: none of the overloads of `this` can construct an immutable object with argument types `(immutable(Foo!int))`. Expected `immutable(immutable(Foo!int))`
 fail_compilation/testrvaluecpctor.d(18):        Candidates are: `testrvaluecpctor.Foo!int.Foo.this(ref scope Foo!int rhs)`
 fail_compilation/testrvaluecpctor.d(16):                        `this(Rhs, this This)(scope Rhs rhs)`
 ---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/uda_lambda.d b/gcc/testsuite/gdc.test/fail_compilation/uda_lambda.d
new file mode 100644
index 000000000000..bd3ff49e0e36
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/uda_lambda.d
@@ -0,0 +1,7 @@
+/+
+TEST_OUTPUT:
+---
+fail_compilation/uda_lambda.d(7): Error: declaration expected, not `=>`
+---
++/
+@a => 7 int b;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/union_conv.d b/gcc/testsuite/gdc.test/fail_compilation/union_conv.d
index f08809c48500..134da36ecdbf 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/union_conv.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/union_conv.d
@@ -2,7 +2,7 @@
 REQUIRED_ARGS: -preview=fixImmutableConv
 TEST_OUTPUT:
 ---
-fail_compilation/union_conv.d(18): Error: cannot implicitly convert expression `c` of type `const(U)` to `U`
+fail_compilation/union_conv.d(18): Error: cannot implicitly convert expression `c` of type `const(U)` to `U` because union `U` contains pointers or references
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/runnable/placenew.d b/gcc/testsuite/gdc.test/runnable/placenew.d
index d90d10a5e744..834a1f76bcbf 100644
--- a/gcc/testsuite/gdc.test/runnable/placenew.d
+++ b/gcc/testsuite/gdc.test/runnable/placenew.d
@@ -93,6 +93,47 @@ void test6()
 
 /*************************************************/
 
+struct S7
+{
+    int x = 10;
+    int y = 20;
+}
+
+void test7()
+{
+    S7 t = void;
+    new (t) S7(10,20);
+    assert(t.x == 10 && t.y == 20);
+}
+
+/*************************************************/
+// https://github.com/dlang/dmd/issues/21203
+
+struct Y8
+{
+    int a;
+    this() @disable; // default disabled
+    this(int i) { a = i; }
+}
+
+struct S8
+{
+    Y8 m;
+
+    this(int x)
+    {
+        new(m) Y8(x); // initialise `m`
+    }
+}
+
+void test8()
+{
+    S8 s = S8(3);
+    assert(s.m.a == 3);
+}
+
+/*************************************************/
+
 int main()
 {
     test1();
@@ -101,6 +142,8 @@ int main()
     test4();
     test5();
     test6();
+    test7();
+    test8();
 
     return 0;
 }
diff --git a/gcc/testsuite/gdc.test/runnable/powinline.d b/gcc/testsuite/gdc.test/runnable/powinline.d
new file mode 100644
index 000000000000..92d1c04e5564
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/powinline.d
@@ -0,0 +1,64 @@
+/*
+REQUIRED_ARGS: -betterC
+RUN_OUTPUT:
+---
+Success
+---
+*/
+import core.stdc.stdio;
+
+void test1()
+{
+    enum real Two = 2.0;
+    static assert(Two^^3 == 8.0);
+}
+
+void test2()
+{
+    double x = 5.0;
+    assert(x^^-1 == 1/x);
+    x = -1.0;
+    assert(x^^1 == x);
+    assert((x += 3) ^^ 2.0 == 4.0);
+    assert((x) ^^ 2.0 == 4.0);
+    assert((x *= 5) ^^ 2.0 == (x * x));
+    assert(x^^-1 == 1.0 / x);
+    assert((x^^-1) ^^ 0.0 == 1.0);
+}
+
+void test3()
+{
+    int x = 6;
+    assert(x ^^ 0 == 1);
+    assert((x += 3) ^^ 2 == 81);
+    assert(x ^^ 2 == (x ^^ 1) * (x ^^ 1));
+    static assert(4.0 ^^ -1 == 0.25);
+}
+
+void test4()
+{
+    // Test that LHS side effects are evaluated.
+    int count = 0;
+    double x()
+    {
+        count++;
+        return 8.0;
+    }
+    assert(x ^^ -1 == 1.0 / 8.0);
+    assert(count == 1);
+    assert(x ^^ 0 == 1.0);
+    assert(count == 2);
+    assert(x ^^ 1 == 8.0);
+    assert(count == 3);
+    assert(x ^^ 2 == 64.0);
+    assert(count == 4);
+}
+
+extern(C) void main()
+{
+    test1();
+    test2();
+    test3();
+    test4();
+    printf("Success\n");
+}
diff --git a/gcc/testsuite/gdc.test/runnable/testaa2.d b/gcc/testsuite/gdc.test/runnable/testaa2.d
index e1abcb4418c5..3d199d984125 100644
--- a/gcc/testsuite/gdc.test/runnable/testaa2.d
+++ b/gcc/testsuite/gdc.test/runnable/testaa2.d
@@ -307,6 +307,26 @@ void testinenum()
     assert("one" in aa);
 }
 
+// https://github.com/dlang/dmd/issues/21258
+void test21258()
+{
+	alias AliasSeq(TList...) = TList;
+
+	struct S { int x; } // use a local type to not generate required TypeInfo elsewhere
+    foreach (T; AliasSeq!(S[int]))
+        enum E { a = T.init, } // bug report uses bad syntax here, but this crashed, too
+}
+
+// https://github.com/dlang/dmd/issues/21207
+void test21207()
+{
+	struct S { int x; } // use a local type to not generate required TypeInfo elsewhere
+    enum aa = ["baz": S(7)];
+
+    void foo(S[string] x = aa) { }
+    foo();
+}
+
 /************************************************/
 
 int main()
@@ -318,6 +338,7 @@ int main()
     test3825x();
     testinout();
     testinenum();
+    test21258();
 
     printf("Success\n");
     return 0;
diff --git a/gcc/testsuite/gdc.test/runnable/testinvariant.d b/gcc/testsuite/gdc.test/runnable/testinvariant.d
index 0ce855719117..11b8829b9fce 100644
--- a/gcc/testsuite/gdc.test/runnable/testinvariant.d
+++ b/gcc/testsuite/gdc.test/runnable/testinvariant.d
@@ -228,8 +228,52 @@ void test16384()
     assert(s == "needs to be thrown2");
 }
 
-
 /***************************************************/
+// Fix: https://github.com/dlang/dmd/issues/20924 (invariant not called on extern(C++) classes)
+
+extern(C++) class C
+{
+    invariant { assert(0); }
+    void f() {}
+}
+
+extern(D) class D
+{
+    invariant { assert(0); }
+    void f() {}
+}
+
+void test20924()
+{
+    import core.exception : AssertError;
+    // Test extern(C++) class invariant
+    try
+    {
+        auto c = new C();
+        c.f(); // Trigger invariant
+        assert(false, "Failed: invariant in extern(C++) class not checked");
+    }
+    catch (AssertError e)
+    {
+        // Expected behavior - invariant was checked
+        return;
+    }
+    assert(0, "Invariant in extern(C++) class was not checked");
+
+    // Test extern(D) class invariant
+    try
+    {
+        auto d = new D();
+        d.f(); // Trigger invariant
+        assert(false, "Failed: invariant in extern(D) class not checked");
+    }
+    catch (AssertError e)
+    {
+        // Expected behavior - invariant was checked
+        return;
+    }
+    assert(0, "Invariant in extern(D) class was not checked");
+}
 
 void main()
 {
@@ -238,4 +282,5 @@ void main()
     test16384();
     test13113();
     test13147();
+    test20924();
 }
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 840f8dd4f9d9..62d90e5770b5 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-09ed02ce56ea5bf3e59f21ee0390cd85eb8bfaa7
+1017635a9636ef6a7a4bda35b1e091875d829871
 
 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/Makefile.am b/libphobos/libdruntime/Makefile.am
index 4c8d65b76f5f..0e9b71bfa5d2 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -297,8 +297,9 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
 	core/sys/linux/sys/mman.d core/sys/linux/sys/mount.d \
 	core/sys/linux/sys/prctl.d core/sys/linux/sys/procfs.d \
 	core/sys/linux/sys/signalfd.d core/sys/linux/sys/socket.d \
-	core/sys/linux/sys/sysinfo.d core/sys/linux/sys/time.d \
-	core/sys/linux/sys/xattr.d core/sys/linux/termios.d \
+	core/sys/linux/sys/syscall.d core/sys/linux/sys/sysinfo.d \
+	core/sys/linux/sys/time.d core/sys/linux/sys/xattr.d \
+	core/sys/linux/syscall.d core/sys/linux/termios.d \
 	core/sys/linux/time.d core/sys/linux/timerfd.d core/sys/linux/tipc.d \
 	core/sys/linux/uinput.d core/sys/linux/unistd.d
 
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index a6bbb76c216b..8543c6e53edc 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -385,8 +385,9 @@ am__objects_19 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \
 	core/sys/linux/sys/mman.lo core/sys/linux/sys/mount.lo \
 	core/sys/linux/sys/prctl.lo core/sys/linux/sys/procfs.lo \
 	core/sys/linux/sys/signalfd.lo core/sys/linux/sys/socket.lo \
-	core/sys/linux/sys/sysinfo.lo core/sys/linux/sys/time.lo \
-	core/sys/linux/sys/xattr.lo core/sys/linux/termios.lo \
+	core/sys/linux/sys/syscall.lo core/sys/linux/sys/sysinfo.lo \
+	core/sys/linux/sys/time.lo core/sys/linux/sys/xattr.lo \
+	core/sys/linux/syscall.lo core/sys/linux/termios.lo \
 	core/sys/linux/time.lo core/sys/linux/timerfd.lo \
 	core/sys/linux/tipc.lo core/sys/linux/uinput.lo \
 	core/sys/linux/unistd.lo
@@ -981,8 +982,9 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
 	core/sys/linux/sys/mman.d core/sys/linux/sys/mount.d \
 	core/sys/linux/sys/prctl.d core/sys/linux/sys/procfs.d \
 	core/sys/linux/sys/signalfd.d core/sys/linux/sys/socket.d \
-	core/sys/linux/sys/sysinfo.d core/sys/linux/sys/time.d \
-	core/sys/linux/sys/xattr.d core/sys/linux/termios.d \
+	core/sys/linux/sys/syscall.d core/sys/linux/sys/sysinfo.d \
+	core/sys/linux/sys/time.d core/sys/linux/sys/xattr.d \
+	core/sys/linux/syscall.d core/sys/linux/termios.d \
 	core/sys/linux/time.d core/sys/linux/timerfd.d core/sys/linux/tipc.d \
 	core/sys/linux/uinput.d core/sys/linux/unistd.d
 
@@ -1756,9 +1758,11 @@ core/sys/linux/sys/prctl.lo: core/sys/linux/sys/$(am__dirstamp)
 core/sys/linux/sys/procfs.lo: core/sys/linux/sys/$(am__dirstamp)
 core/sys/linux/sys/signalfd.lo: core/sys/linux/sys/$(am__dirstamp)
 core/sys/linux/sys/socket.lo: core/sys/linux/sys/$(am__dirstamp)
+core/sys/linux/sys/syscall.lo: core/sys/linux/sys/$(am__dirstamp)
 core/sys/linux/sys/sysinfo.lo: core/sys/linux/sys/$(am__dirstamp)
 core/sys/linux/sys/time.lo: core/sys/linux/sys/$(am__dirstamp)
 core/sys/linux/sys/xattr.lo: core/sys/linux/sys/$(am__dirstamp)
+core/sys/linux/syscall.lo: core/sys/linux/$(am__dirstamp)
 core/sys/linux/termios.lo: core/sys/linux/$(am__dirstamp)
 core/sys/linux/time.lo: core/sys/linux/$(am__dirstamp)
 core/sys/linux/timerfd.lo: core/sys/linux/$(am__dirstamp)
diff --git a/libphobos/libdruntime/core/int128.d b/libphobos/libdruntime/core/int128.d
index 27c8b99d2cbf..b1247891e69c 100644
--- a/libphobos/libdruntime/core/int128.d
+++ b/libphobos/libdruntime/core/int128.d
@@ -36,6 +36,12 @@ else
     else             private enum Cent_alignment = (size_t.sizeof * 2);
 }
 
+version (X86_64)
+{
+    version (GNU) version = GNU_OR_LDC_X86_64;
+    version (LDC) version = GNU_OR_LDC_X86_64;
+}
+
 /**
  * 128 bit integer type.
  * See_also: $(REF Int128, std,int128).
@@ -189,10 +195,8 @@ Cent sar1(Cent c)
  */
 pure
 Cent shl(Cent c, uint n)
+in (n < Ubits * 2)
 {
-    if (n >= Ubits * 2)
-        return Zero;
-
     if (n >= Ubits)
     {
         c.hi = c.lo << (n - Ubits);
@@ -216,10 +220,8 @@ Cent shl(Cent c, uint n)
  */
 pure
 Cent shr(Cent c, uint n)
+in (n < Ubits * 2)
 {
-    if (n >= Ubits * 2)
-        return Zero;
-
     if (n >= Ubits)
     {
         c.lo = c.hi >> (n - Ubits);
@@ -243,18 +245,13 @@ Cent shr(Cent c, uint n)
  */
 pure
 Cent sar(Cent c, uint n)
+in (n < Ubits * 2)
 {
     const signmask = -(c.hi >> (Ubits - 1));
     const signshift = (Ubits * 2) - n;
     c = shr(c, n);
 
-    // Sign extend all bits beyond the precision of Cent.
-    if (n >= Ubits * 2)
-    {
-        c.hi = signmask;
-        c.lo = signmask;
-    }
-    else if (signshift >= Ubits * 2)
+    if (signshift == Ubits * 2)
     {
     }
     else if (signshift >= Ubits)
@@ -317,6 +314,8 @@ pure
 Cent rol(Cent c, uint n)
 {
     n &= Ubits * 2 - 1;
+    if (n == 0)
+        return c;
     Cent l = shl(c, n);
     Cent r = shr(c, Ubits * 2 - n);
     return or(l, r);
@@ -334,6 +333,8 @@ pure
 Cent ror(Cent c, uint n)
 {
     n &= Ubits * 2 - 1;
+    if (n == 0)
+        return c;
     Cent r = shr(c, n);
     Cent l = shl(c, Ubits * 2 - n);
     return or(r, l);
@@ -458,6 +459,55 @@ Cent mul(Cent c1, Cent c2)
     return ret;
 }
 
+/****************************
+ * Multiply 64-bit operands u1 * u2 in 128-bit precision.
+ * Params:
+ *      u1 = operand 1
+ *      u2 = operand 2
+ * Returns:
+ *      u1 * u2 in 128-bit precision
+ */
+pure
+Cent mul(ulong u1, ulong u2)
+{
+    if (!__ctfe)
+    {
+        version (GNU_OR_LDC_X86_64)
+        {
+            Cent ret = void;
+            asm pure @trusted nothrow @nogc
+            {
+                "mulq %3"
+                : "=a"(ret.lo), "=d"(ret.hi)
+                : "a"(u1), "r"(u2)
+                : "cc";
+            }
+            return ret;
+        }
+        else version (D_InlineAsm_X86_64)
+        {
+            U lo = void;
+            U hi = void;
+            asm pure @trusted nothrow @nogc
+            {
+                mov RAX, u1;
+                mul u2;
+                mov lo, RAX;
+                mov hi, RDX;
+            }
+            return Cent(lo: lo, hi: hi);
+        }
+    }
+
+    return mul(Cent(lo: u1), Cent(lo: u2));
+}
+
+unittest
+{
+    assert(mul(3, 42) == Cent(lo: 126));
+    assert(mul(1L << 60, 1 << 10) == Cent(hi: 1 << 6));
+}
+
 
 /****************************
  * Unsigned divide c1 / c2.
@@ -490,63 +540,6 @@ Cent udivmod(Cent c1, Cent c2, out Cent modulus)
     // Based on "Unsigned Doubleword Division" in Hacker's Delight
     import core.bitop;
 
-    // Divides a 128-bit dividend by a 64-bit divisor.
-    // The result must fit in 64 bits.
-    static U udivmod128_64(Cent c1, U c2, out U modulus)
-    {
-        // We work in base 2^^32
-        enum base = 1UL << 32;
-        enum divmask = (1UL << (Ubits / 2)) - 1;
-        enum divshift = Ubits / 2;
-
-        // Check for overflow and divide by 0
-        if (c1.hi >= c2)
-        {
-            modulus = 0UL;
-            return ~0UL;
-        }
-
-        // Computes [num1 num0] / den
-        static uint udiv96_64(U num1, uint num0, U den)
-        {
-            // Extract both digits of the denominator
-            const den1 = cast(uint)(den >> divshift);
-            const den0 = cast(uint)(den & divmask);
-            // Estimate ret as num1 / den1, and then correct it
-            U ret = num1 / den1;
-            const t2 = (num1 % den1) * base + num0;
-            const t1 = ret * den0;
-            if (t1 > t2)
-                ret -= (t1 - t2 > den) ? 2 : 1;
-            return cast(uint)ret;
-        }
-
-        // Determine the normalization factor. We multiply c2 by this, so that its leading
-        // digit is at least half base. In binary this means just shifting left by the number
-        // of leading zeros, so that there's a 1 in the MSB.
-        // We also shift number by the same amount. This cannot overflow because c1.hi < c2.
-        const shift = (Ubits - 1) - bsr(c2);
-        c2 <<= shift;
-        U num2 = c1.hi;
-        num2 <<= shift;
-        num2 |= (c1.lo >> (-shift & 63)) & (-cast(I)shift >> 63);
-        c1.lo <<= shift;
-
-        // Extract the low digits of the numerator (after normalizing)
-        const num1 = cast(uint)(c1.lo >> divshift);
-        const num0 = cast(uint)(c1.lo & divmask);
-
-        // Compute q1 = [num2 num1] / c2
-        const q1 = udiv96_64(num2, num1, c2);
-        // Compute the true (partial) remainder
-        const rem = num2 * base + num1 - q1 * c2;
-        // Compute q0 = [rem num0] / c2
-        const q0 = udiv96_64(rem, num0, c2);
-
-        modulus = (rem * base + num0 - q0 * c2) >> shift;
-        return (cast(U)q1 << divshift) | q0;
-    }
-
     // Special cases
     if (!tst(c2))
     {
@@ -576,7 +569,7 @@ Cent udivmod(Cent c1, Cent c2, out Cent modulus)
         if (q1)
             c1.hi = c1.hi % c2.lo;
         Cent rem;
-        const q0 = udivmod128_64(c1, c2.lo, rem.lo);
+        const q0 = udivmod(c1, c2.lo, rem.lo);
         modulus = rem;
         const Cent ret = { lo:q0, hi:q1 };
         return ret;
@@ -597,7 +590,7 @@ Cent udivmod(Cent c1, Cent c2, out Cent modulus)
 
     // Get quotient from divide unsigned operation.
     U rem_ignored;
-    const Cent q1 = { lo:udivmod128_64(u1, v1, rem_ignored) };
+    const Cent q1 = { lo:udivmod(u1, v1, rem_ignored) };
 
     // Undo normalization and division of c1 by 2.
     Cent quotient = shr(shl(q1, shift), 63);
@@ -624,6 +617,107 @@ Cent udivmod(Cent c1, Cent c2, out Cent modulus)
     return quotient;
 }
 
+/****************************
+ * Unsigned divide 128-bit c1 / 64-bit c2. The result must fit in 64 bits.
+ * The remainder after division is stored to modulus.
+ * Params:
+ *      c1 = dividend
+ *      c2 = divisor
+ *      modulus = set to c1 % c2
+ * Returns:
+ *      quotient c1 / c2
+ */
+pure
+U udivmod(Cent c1, U c2, out U modulus)
+{
+    import core.bitop;
+
+    if (!__ctfe)
+    {
+        version (GNU_OR_LDC_X86_64)
+        {
+            U ret = void;
+            asm pure @trusted nothrow @nogc
+            {
+                "divq %4"
+                : "=a"(ret), "=d"(modulus)
+                : "a"(c1.lo), "d"(c1.hi), "r"(c2)
+                : "cc";
+            }
+            return ret;
+        }
+        else version (D_InlineAsm_X86_64)
+        {
+            const lo = c1.lo;
+            const hi = c1.hi;
+            U mod = void;
+            U ret = void;
+            asm pure @trusted nothrow @nogc
+            {
+                mov RAX, lo;
+                mov RDX, hi;
+                div c2;
+                mov mod, RDX; // DMD bug: cannot use modulus directly
+                mov ret, RAX;
+            }
+            modulus = mod;
+            return ret;
+        }
+    }
+
+    // We work in base 2^^32
+    enum base = 1UL << 32;
+    enum divmask = (1UL << (Ubits / 2)) - 1;
+    enum divshift = Ubits / 2;
+
+    // Check for overflow and divide by 0
+    if (c1.hi >= c2)
+    {
+        modulus = 0UL;
+        return ~0UL;
+    }
+
+    // Computes [num1 num0] / den
+    static uint udiv96_64(U num1, uint num0, U den)
+    {
+        // Extract both digits of the denominator
+        const den1 = cast(uint)(den >> divshift);
+        const den0 = cast(uint)(den & divmask);
+        // Estimate ret as num1 / den1, and then correct it
+        U ret = num1 / den1;
+        const t2 = (num1 % den1) * base + num0;
+        const t1 = ret * den0;
+        if (t1 > t2)
+            ret -= (t1 - t2 > den) ? 2 : 1;
+        return cast(uint)ret;
+    }
+
+    // Determine the normalization factor. We multiply c2 by this, so that its leading
+    // digit is at least half base. In binary this means just shifting left by the number
+    // of leading zeros, so that there's a 1 in the MSB.
+    // We also shift number by the same amount. This cannot overflow because c1.hi < c2.
+    const shift = (Ubits - 1) - bsr(c2);
+    c2 <<= shift;
+    U num2 = c1.hi;
+    num2 <<= shift;
+    num2 |= (c1.lo >> (-shift & 63)) & (-cast(I)shift >> 63);
+    c1.lo <<= shift;
+
+    // Extract the low digits of the numerator (after normalizing)
+    const num1 = cast(uint)(c1.lo >> divshift);
+    const num0 = cast(uint)(c1.lo & divmask);
+
+    // Compute q1 = [num2 num1] / c2
+    const q1 = udiv96_64(num2, num1, c2);
+    // Compute the true (partial) remainder
+    const rem = num2 * base + num1 - q1 * c2;
+    // Compute q0 = [rem num0] / c2
+    const q0 = udiv96_64(rem, num0, c2);
+
+    modulus = (rem * base + num0 - q0 * c2) >> shift;
+    return (cast(U)q1 << divshift) | q0;
+}
+
 
 /****************************
  * Signed divide c1 / c2.
@@ -893,18 +987,14 @@ unittest
     assert(shl(C10,0) == C10);
     assert(shl(C10,Ubits) == C10_0);
     assert(shl(C10,1) == C20);
-    assert(shl(C10,Ubits * 2) == C0);
     assert(shr(C10_0,0) == C10_0);
     assert(shr(C10_0,Ubits) == C10);
     assert(shr(C10_0,Ubits - 1) == C20);
     assert(shr(C10_0,Ubits + 1) == C5);
-    assert(shr(C10_0,Ubits * 2) == C0);
     assert(sar(C10_0,0) == C10_0);
     assert(sar(C10_0,Ubits) == C10);
     assert(sar(C10_0,Ubits - 1) == C20);
     assert(sar(C10_0,Ubits + 1) == C5);
-    assert(sar(C10_0,Ubits * 2) == C0);
-    assert(sar(Cm1,Ubits * 2) == Cm1);
 
     assert(shl1(C10) == C20);
     assert(shr1(C10_0) == C5_0);
@@ -916,7 +1006,6 @@ unittest
     assert(udiv(C10,C2) == C5);
     assert(udivmod(C10,C2, modulus) ==  C5);   assert(modulus == C0);
     assert(udivmod(C10,C3, modulus) ==  C3);   assert(modulus == C1);
-    assert(udivmod(C10,C0, modulus) == Cm1);   assert(modulus == C0);
     assert(udivmod(C2,C90_30, modulus) == C0); assert(modulus == C2);
     assert(udiv(mul(C90_30, C2), C2) == C90_30);
     assert(udiv(mul(C90_30, C2), C90_30) == C2);
@@ -961,4 +1050,6 @@ unittest
     assert(rol(ror(C7_9, 5), 5) == C7_9);
     assert(rol(C7_9, 1) == rol1(C7_9));
     assert(ror(C7_9, 1) == ror1(C7_9));
+    assert(rol(C7_9, 0) == C7_9);
+    assert(ror(C7_9, 0) == C7_9);
 }
diff --git a/libphobos/libdruntime/core/internal/array/capacity.d b/libphobos/libdruntime/core/internal/array/capacity.d
index 10ce2c65c958..11bd357d7c27 100644
--- a/libphobos/libdruntime/core/internal/array/capacity.d
+++ b/libphobos/libdruntime/core/internal/array/capacity.d
@@ -9,64 +9,314 @@
 */
 module core.internal.array.capacity;
 
-// HACK: `nothrow` and `pure` is faked.
-private extern (C) void[] _d_arraysetlengthT(const TypeInfo ti, size_t newlength, void[]* p) nothrow pure;
-private extern (C) void[] _d_arraysetlengthiT(const TypeInfo ti, size_t newlength, void[]* p) nothrow pure;
-
-/*
- * This template is needed because there need to be a `_d_arraysetlengthTTrace!Tarr` instance for every
- * `_d_arraysetlengthT!Tarr`. By wrapping both of these functions inside of this template we force the
- * compiler to create a instance of both function for every type that is used.
- */
-
-/// Implementation of `_d_arraysetlengthT` and `_d_arraysetlengthTTrace`
-template _d_arraysetlengthTImpl(Tarr : T[], T)
+debug (PRINTF) import core.stdc.stdio : printf;
+debug (VALGRIND) import etc.valgrind.valgrind;
+
+// for now, all GC array functions are not exposed via core.memory.
+extern(C) {
+    bool gc_expandArrayUsed(void[] slice, size_t newUsed, bool atomic) nothrow pure;
+    size_t gc_reserveArrayCapacity(void[] slice, size_t request, bool atomic) nothrow pure;
+    bool gc_shrinkArrayUsed(void[] slice, size_t existingUsed, bool atomic) nothrow pure;
+}
+/**
+Set the array capacity.
+
+If the array capacity isn't currently large enough
+to hold the requested capacity (in number of elements), then the array is
+resized/reallocated to the appropriate size.
+
+Pass in a requested capacity of 0 to get the current capacity.
+
+Params:
+    T = the type of the elements in the array (this should be unqualified)
+    newcapacity = requested new capacity
+    p = pointer to array to set. Its `length` is left unchanged.
+    isshared = true if the underlying data is shared
+
+Returns: the number of elements that can actually be stored once the resizing is done
+*/
+size_t _d_arraysetcapacityPureNothrow(T)(size_t newcapacity, void[]* p, bool isshared) pure nothrow @trusted
+do
+{
+    alias PureNothrowType = size_t function(size_t, void[]*, bool) pure nothrow @trusted;
+    return (cast(PureNothrowType) &_d_arraysetcapacity!T)(newcapacity, p, isshared);
+}
+
+size_t _d_arraysetcapacity(T)(size_t newcapacity, void[]* p, bool isshared) @trusted
+in
+{
+    assert(!(*p).length || (*p).ptr);
+}
+do
+{
+    import core.checkedint : mulu;
+    import core.exception : onOutOfMemoryError;
+    import core.stdc.string : memcpy, memset;
+    import core.internal.array.utils: __typeAttrs;
+    import core.internal.lifetime : __doPostblit;
+
+    import core.memory : GC;
+
+    alias BlkAttr = GC.BlkAttr;
+
+    auto size = T.sizeof;
+    bool overflow = false;
+    const reqsize = mulu(size, newcapacity, overflow);
+    if (overflow)
+    {
+        onOutOfMemoryError();
+        assert(0);
+    }
+
+    // step 1, see if we can ensure the capacity is valid in-place
+    auto datasize = (*p).length * size;
+    auto curCapacity = gc_reserveArrayCapacity((*p).ptr[0 .. datasize], reqsize, isshared);
+    if (curCapacity != 0) // in-place worked!
+        return curCapacity / size;
+
+    if (reqsize <= datasize) // requested size is less than array size, the current array satisfies
+        // the request. But this is not an appendable GC array, so return 0.
+        return 0;
+
+    // step 2, if reserving in-place doesn't work, allocate a new array with at
+    // least the requested allocated size.
+    auto attrs = __typeAttrs!T((*p).ptr) | BlkAttr.APPENDABLE;
+
+    // use this static enum to avoid recomputing TypeInfo for every call.
+    static enum ti = typeid(T);
+    auto ptr = GC.malloc(reqsize, attrs, ti);
+    if (ptr is null)
+    {
+        onOutOfMemoryError();
+        assert(0);
+    }
+
+    // copy the data over.
+    // note that malloc will have initialized the data we did not request to 0.
+    memcpy(ptr, (*p).ptr, datasize);
+
+    // handle postblit
+    __doPostblit!T(cast(T[])ptr[0 .. datasize]);
+
+    if (!(attrs & BlkAttr.NO_SCAN))
+    {
+        // need to memset the newly requested data, except for the data that
+        // malloc returned that we didn't request.
+        void* endptr = ptr + reqsize;
+        void* begptr = ptr + datasize;
+
+        // sanity check
+        assert(endptr >= begptr);
+        memset(begptr, 0, endptr - begptr);
+    }
+
+    *p = ptr[0 .. (*p).length];
+
+    // set up the correct length. Note that we need to do this here, because
+    // the GC malloc will automatically set the used size to what we requested.
+    gc_shrinkArrayUsed(ptr[0 .. datasize], reqsize, isshared);
+
+    curCapacity = gc_reserveArrayCapacity(ptr[0 .. datasize], 0, isshared);
+    assert(curCapacity);
+    return curCapacity / size;
+}
+
+/**
+Resize a dynamic array by setting its `.length` property.
+
+Newly created elements are initialized based on their default value.
+If the array's elements initialize to `0`, memory is zeroed out. Otherwise, elements are explicitly initialized.
+
+This function handles memory allocation, expansion, and initialization while maintaining array integrity.
+
+---
+void main()
+{
+    int[] a = [1, 2];
+    a.length = 3; // Gets lowered to `_d_arraysetlengthT!(int)(a, 3, false)`
+}
+---
+
+Params:
+    arr         = The array to resize.
+    newlength   = The new value for the array's `.length`.
+
+Returns:
+    The resized array with updated length and properly initialized elements.
+
+Throws:
+    OutOfMemoryError if allocation fails.
+*/
+size_t _d_arraysetlengthT(Tarr : T[], T)(return ref scope Tarr arr, size_t newlength) @trusted
+{
+    import core.internal.traits : Unqual;
+
+    // Check if the type is shared
+    enum isShared = is(T == shared);
+
+    // Unqualify the type to remove `const`, `immutable`, `shared`, etc.
+    alias UnqT = Unqual!T;
+
+    // Cast the array to the unqualified type
+    auto unqual_arr = cast(UnqT[]) arr;
+
+    // Call the implementation with the unqualified array and sharedness flag
+    size_t result = _d_arraysetlengthT_(unqual_arr, newlength, isShared);
+
+    arr = cast(Tarr) unqual_arr;
+    // Return the result
+    return result;
+}
+
+private size_t _d_arraysetlengthT_(Tarr : T[], T)(return ref scope Tarr arr, size_t newlength, bool isShared) @trusted
 {
-    private enum errorMessage = "Cannot resize arrays if compiling without support for runtime type information!";
-
-    /**
-     * Resize dynamic array
-     * Params:
-     *  arr = the array that will be resized, taken as a reference
-     *  newlength = new length of array
-     * Returns:
-     *  The new length of the array
-     * Bugs:
-     *   The safety level of this function is faked. It shows itself as `@trusted pure nothrow` to not break existing code.
-     */
-    size_t _d_arraysetlengthT(return scope ref Tarr arr, size_t newlength) @trusted pure nothrow
+    import core.checkedint : mulu;
+    import core.exception : onFinalizeError, onOutOfMemoryError;
+    import core.stdc.string : memcpy, memset;
+    import core.internal.traits : hasElaborateCopyConstructor, Unqual;
+    import core.lifetime : emplace;
+    import core.memory;
+    import core.internal.lifetime : __doPostblit;
+
+    alias BlkAttr = GC.BlkAttr;
+    alias UnqT = Unqual!T;
+
+    debug(PRINTF)
+    {
+        printf("_d_arraysetlengthT(arr.ptr = %p, arr.length = %zd, newlength = %zd)\n",
+            arr.ptr, arr.length, newlength);
+    }
+
+    // If the new length is less than or equal to the current length, just truncate the array
+    if (newlength <= arr.length)
+    {
+        arr = arr[0 .. newlength];
+        return newlength;
+    }
+
+    enum sizeelem = T.sizeof;
+    enum hasPostblit = __traits(hasMember, T, "__postblit");
+    enum hasEnabledPostblit = hasPostblit && !__traits(isDisabled, T.__postblit);
+
+    bool overflow = false;
+    const newsize = mulu(sizeelem, newlength, overflow);
+    if (overflow)
     {
-        version (DigitalMars) pragma(inline, false);
-        version (D_TypeInfo)
+        onOutOfMemoryError();
+        assert(0);
+    }
+
+    debug(PRINTF) printf("newsize = %zx\n", newsize);
+
+    uint gcAttrs = BlkAttr.APPENDABLE;
+    static if (is(T == struct) && __traits(hasMember, T, "xdtor"))
+    {
+        gcAttrs |= BlkAttr.FINALIZE;
+    }
+
+    if (!arr.ptr)
+    {
+        assert(arr.length == 0);
+        void* ptr = GC.malloc(newsize, gcAttrs);
+        if (!ptr)
+        {
+            onOutOfMemoryError();
+            assert(0);
+        }
+
+        static if (__traits(isZeroInit, T))
+        {
+            memset(ptr, 0, newsize);
+        }
+        else static if (hasElaborateCopyConstructor!T && !hasPostblit)
         {
-            auto ti = typeid(Tarr);
+            foreach (i; 0 .. newlength)
+                emplace(cast(UnqT*) ptr + i, UnqT.init); // safe default construction
+        }
+        else
+        {
+            auto temp = UnqT.init;
+            foreach (i; 0 .. newlength)
+                memcpy(cast(UnqT*) ptr + i, cast(const void*)&temp, T.sizeof);
+
+            static if (hasEnabledPostblit)
+                __doPostblit!T((cast(T*) ptr)[0 .. newlength]);
+        }
+
+        arr = (cast(T*) ptr)[0 .. newlength];
+        return newlength;
+    }
 
-            static if (__traits(isZeroInit, T))
-                ._d_arraysetlengthT(ti, newlength, cast(void[]*)&arr);
-            else
-                ._d_arraysetlengthiT(ti, newlength, cast(void[]*)&arr);
+    size_t oldsize = arr.length * sizeelem;
 
-            return arr.length;
+    auto newdata = cast(void*) arr.ptr;
+
+    if (!gc_expandArrayUsed(newdata[0 .. oldsize], newsize, isShared))
+    {
+        newdata = GC.malloc(newsize, gcAttrs);
+        if (!newdata)
+        {
+            onOutOfMemoryError();
+            assert(0);
+        }
+        static if (hasElaborateCopyConstructor!T && !hasPostblit)
+        {
+            // Use emplace for types with copy constructors but not postblit
+            foreach (i; 0 .. arr.length)
+                emplace(cast(UnqT*)newdata + i, arr[i]); // safe copy
         }
         else
-            assert(0, errorMessage);
+        {
+            memcpy(newdata, cast(const(void)*)arr.ptr, oldsize);
+
+            // Postblit handling for types with postblit, but ensure it compiles
+            static if (hasEnabledPostblit)
+                __doPostblit!T((cast(T*) (cast(ubyte*)newdata))[0 .. arr.length]);
+        }
+    }
+
+    // Handle initialization based on whether the type requires zero-init
+    static if (__traits(isZeroInit, T))
+        memset(cast(void*) (cast(ubyte*)newdata + oldsize), 0, newsize - oldsize);
+    else static if (hasElaborateCopyConstructor!T && !hasPostblit)
+    {
+        foreach (i; 0 .. newlength - arr.length)
+            emplace(cast(UnqT*) (cast(ubyte*)newdata + oldsize) + i, UnqT.init);
+    }
+    else
+    {
+        auto temp = UnqT.init;
+        foreach (i; 0 .. newlength - arr.length)
+            memcpy(cast(UnqT*) (cast(ubyte*)newdata + oldsize) + i, cast(const void*)&temp, T.sizeof);
+
+        static if (hasEnabledPostblit)
+            __doPostblit!T((cast(T*) (cast(ubyte*)newdata + oldsize))[0 .. newlength - arr.length]);
     }
 
-    version (D_ProfileGC)
+    arr = (cast(T*) newdata)[0 .. newlength];
+    return newlength;
+}
+
+version (D_ProfileGC)
+{
+    enum errorMessage = "Cannot resize arrays";
+    import core.internal.array.utils : _d_HookTraceImpl;
+
+    // Function wrapper around the hook, so it’s callable
+    size_t _d_arraysetlengthTTrace(Tarr : T[], T)(
+        return ref scope Tarr arr,
+        size_t newlength,
+        string file = __FILE__,
+        int line = __LINE__,
+        string func = __FUNCTION__
+    ) @trusted
     {
-        import core.internal.array.utils : _d_HookTraceImpl;
-
-        /**
-         * TraceGC wrapper around $(REF _d_arraysetlengthT, core,internal,array,core.internal.array.capacity).
-         * Bugs:
-         *  This function template was ported from a much older runtime hook that bypassed safety,
-         *  purity, and throwabilty checks. To prevent breaking existing code, this function template
-         *  is temporarily declared `@trusted pure nothrow` until the implementation can be brought up to modern D expectations.
-         */
-        alias _d_arraysetlengthTTrace = _d_HookTraceImpl!(Tarr, _d_arraysetlengthT, errorMessage);
+        alias Hook = _d_HookTraceImpl!(Tarr, _d_arraysetlengthT!Tarr, errorMessage);
+        return Hook(arr, newlength, file, line, func);
     }
 }
 
+// @safe unittest remains intact
 @safe unittest
 {
     struct S
@@ -75,13 +325,13 @@ template _d_arraysetlengthTImpl(Tarr : T[], T)
     }
 
     int[] arr;
-    _d_arraysetlengthTImpl!(typeof(arr))._d_arraysetlengthT(arr, 16);
+    _d_arraysetlengthT!(typeof(arr))(arr, 16);
     assert(arr.length == 16);
     foreach (int i; arr)
         assert(i == int.init);
 
     shared S[] arr2;
-    _d_arraysetlengthTImpl!(typeof(arr2))._d_arraysetlengthT(arr2, 16);
+    _d_arraysetlengthT!(typeof(arr2))(arr2, 16);
     assert(arr2.length == 16);
     foreach (s; arr2)
         assert(s == S.init);
diff --git a/libphobos/libdruntime/core/internal/array/concatenation.d b/libphobos/libdruntime/core/internal/array/concatenation.d
index 13ec5fad40fd..fab2a5a9b7c1 100644
--- a/libphobos/libdruntime/core/internal/array/concatenation.d
+++ b/libphobos/libdruntime/core/internal/array/concatenation.d
@@ -19,7 +19,8 @@ module core.internal.array.concatenation;
  */
 Tret _d_arraycatnTX(Tret, Tarr...)(auto ref Tarr froms) @trusted
 {
-    import core.internal.array.capacity : _d_arraysetlengthTImpl;
+    import core.exception : onOutOfMemoryError;
+    import core.internal.array.utils : __arrayAlloc;
     import core.internal.traits : hasElaborateCopyConstructor, Unqual;
     import core.lifetime : copyEmplace;
     import core.stdc.string : memcpy;
@@ -27,37 +28,27 @@ Tret _d_arraycatnTX(Tret, Tarr...)(auto ref Tarr froms) @trusted
     Tret res;
     size_t totalLen;
 
-    alias T = typeof(res[0]);
-    enum elemSize = T.sizeof;
-    enum hasPostblit = __traits(hasPostblit, T);
+    alias T = typeof(res[0]); // Element type of the result array
+    alias UnqT = Unqual!T;    // Unqualified version of T (strips const/immutable)
+    enum elemSize = T.sizeof; // Size of each element
+    enum hasPostblit = __traits(hasPostblit, T); // Whether T has a postblit constructor
 
+    // Compute total length of the resulting array
     static foreach (from; froms)
-        static if (is (typeof(from) : T))
-            totalLen++;
+        static if (is(typeof(from) : T))
+            totalLen++; // Single element contributes one to length
         else
-            totalLen += from.length;
+            totalLen += from.length; // Arrays contribute their full length
 
     if (totalLen == 0)
-        return res;
+        return res; // Return an empty array if no elements are present
 
-    // We cannot use this, because it refuses to work if the array type has disabled default construction.
-    // res.length = totalLen;
-    // Call the runtime function directly instead.
-    // TODO: once `__arrayAlloc` is templated, call that instead.
-    version (D_ProfileGC)
-    {
-        // TODO: forward file, line, name from _d_arraycatnTXTrace
-        _d_arraysetlengthTImpl!(typeof(res))._d_arraysetlengthTTrace(
-            res, totalLen, __FILE__, __LINE__, __FUNCTION__);
-    }
-    else
-    {
-        _d_arraysetlengthTImpl!(typeof(res))._d_arraysetlengthT(res, totalLen);
-    }
+    // Allocate memory for mutable arrays using __arrayAlloc
+    res = cast(Tret) __arrayAlloc!(UnqT)(elemSize * totalLen);
+
+    if (res.ptr is null)
+        onOutOfMemoryError(); // Abort if allocation fails
 
-    /* Currently, if both a postblit and a cpctor are defined, the postblit is
-     * used. If this changes, the condition below will have to be adapted.
-     */
     static if (hasElaborateCopyConstructor!T && !hasPostblit)
     {
         size_t i = 0;
@@ -73,16 +64,16 @@ Tret _d_arraycatnTX(Tret, Tarr...)(auto ref Tarr froms) @trusted
     }
     else
     {
-        auto resptr = cast(Unqual!T *) res;
+        auto resptr = cast(UnqT *) res;
         foreach (ref from; froms)
             static if (is (typeof(from) : T))
-                memcpy(resptr++, cast(Unqual!T *) &from, elemSize);
+                memcpy(resptr++, cast(UnqT *) &from, elemSize);
             else
             {
                 const len = from.length;
                 if (len)
                 {
-                    memcpy(resptr, cast(Unqual!T *) from, len * elemSize);
+                    memcpy(resptr, cast(UnqT *) from, len * elemSize);
                     resptr += len;
                 }
             }
diff --git a/libphobos/libdruntime/core/internal/array/construction.d b/libphobos/libdruntime/core/internal/array/construction.d
index 40e5a61bbded..76811ef3ffd0 100644
--- a/libphobos/libdruntime/core/internal/array/construction.d
+++ b/libphobos/libdruntime/core/internal/array/construction.d
@@ -505,7 +505,7 @@ version (D_ProfileGC)
  * Returns:
  *    newly allocated array
  */
-Tarr _d_newarraymTX(Tarr : U[], T, U)(size_t[] dims, bool isShared=false) @trusted
+Tarr _d_newarraymTX(Tarr : U[], T, U)(scope size_t[] dims, bool isShared=false) @trusted
 {
     debug(PRINTF) printf("_d_newarraymTX(dims.length = %zd)\n", dims.length);
 
@@ -520,7 +520,7 @@ Tarr _d_newarraymTX(Tarr : U[], T, U)(size_t[] dims, bool isShared=false) @trust
 
         auto dim = dims[0];
 
-        debug(PRINTF) printf("__allocateInnerArray(UnqT = %s, dim = %lu, ndims = %lu\n", UnqT.stringof.ptr, dim, dims.length);
+        debug(PRINTF) printf("__allocateInnerArray(UnqT = %s, dim = %u, ndims = %u)\n", UnqT.stringof.ptr, cast(uint)dim, cast(uint)dims.length);
         if (dims.length == 1)
         {
             auto r = _d_newarrayT!UnqT(dim, isShared);
@@ -602,7 +602,7 @@ version (D_ProfileGC)
     /**
     * TraceGC wrapper around $(REF _d_newarraymT, core,internal,array,construction).
     */
-    Tarr _d_newarraymTXTrace(Tarr : U[], T, U)(size_t[] dims, bool isShared=false, string file = __FILE__, int line = __LINE__, string funcname = __FUNCTION__) @trusted
+    Tarr _d_newarraymTXTrace(Tarr : U[], T, U)(scope size_t[] dims, bool isShared=false, string file = __FILE__, int line = __LINE__, string funcname = __FUNCTION__) @trusted
     {
         version (D_TypeInfo)
         {
diff --git a/libphobos/libdruntime/core/internal/array/utils.d b/libphobos/libdruntime/core/internal/array/utils.d
index deaae3f95da6..1d105e6ebf19 100644
--- a/libphobos/libdruntime/core/internal/array/utils.d
+++ b/libphobos/libdruntime/core/internal/array/utils.d
@@ -156,3 +156,28 @@ void[] __arrayAlloc(T)(size_t arrSize) @trusted
         return ptr[0 .. arrSize];
     return null;
 }
+
+uint __typeAttrs(T)(void *copyAttrsFrom = null)
+{
+    import core.internal.traits : hasIndirections, hasElaborateDestructor;
+    import core.memory : GC;
+
+    alias BlkAttr = GC.BlkAttr;
+
+    if (copyAttrsFrom)
+    {
+        // try to copy attrs from the given block
+        auto info = GC.query(copyAttrsFrom);
+        if (info.base)
+            return info.attr;
+    }
+
+    uint attrs = 0;
+    static if (!hasIndirections!T)
+        attrs |= BlkAttr.NO_SCAN;
+
+    static if (is(T == struct) && hasElaborateDestructor!T)
+        attrs |= BlkAttr.FINALIZE;
+
+    return attrs;
+}
diff --git a/libphobos/libdruntime/core/internal/lifetime.d b/libphobos/libdruntime/core/internal/lifetime.d
index a7446debae65..fd78de221d11 100644
--- a/libphobos/libdruntime/core/internal/lifetime.d
+++ b/libphobos/libdruntime/core/internal/lifetime.d
@@ -202,3 +202,22 @@ void swap(T)(ref T lhs, ref T rhs)
     moveEmplace(rhs, lhs);
     moveEmplace(tmp, rhs);
 }
+
+void __doPostblit(T)(T[] arr)
+{
+    // infer static postblit type, run postblit if any
+    static if (__traits(hasPostblit, T))
+    {
+        static if (__traits(isStaticArray, T) && is(T : E[], E))
+            __doPostblit(cast(E[]) arr);
+        else static if (!__traits(compiles, arr[0].__xpostblit))
+        {
+            alias Unqual_T = Unqual!T;
+            foreach (ref elem; (() @trusted => cast(Unqual_T[]) arr)())
+                elem.__xpostblit();
+        }
+        else
+            foreach (ref elem; arr)
+                elem.__xpostblit();
+    }
+}
diff --git a/libphobos/libdruntime/core/stdc/fenv.d b/libphobos/libdruntime/core/stdc/fenv.d
index ce77d5c1e6b2..7d42d5c8c023 100644
--- a/libphobos/libdruntime/core/stdc/fenv.d
+++ b/libphobos/libdruntime/core/stdc/fenv.d
@@ -440,6 +440,11 @@ else version (CRuntime_Musl)
         }
         alias uint fexcept_t;
     }
+    else version (RICV64)
+    {
+        alias uint fenv_t;
+        alias uint fexcept_t;
+    }
     else
     {
         static assert(false, "Architecture not supported.");
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index 1f384f9cbd46..5b78d6f61f36 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -1509,51 +1509,51 @@ extern (D)
 {
     //int isgreater(real-floating x, real-floating y);
     ///
-    pure int isgreater(float x, float y)        { return x > y; }
+    pure int isgreater()(float x, float y)        { return x > y; }
     ///
-    pure int isgreater(double x, double y)      { return x > y; }
+    pure int isgreater()(double x, double y)      { return x > y; }
     ///
-    pure int isgreater(real x, real y)          { return x > y; }
+    pure int isgreater()(real x, real y)          { return x > y; }
 
     //int isgreaterequal(real-floating x, real-floating y);
     ///
-    pure int isgreaterequal(float x, float y)   { return x >= y; }
+    pure int isgreaterequal()(float x, float y)   { return x >= y; }
     ///
-    pure int isgreaterequal(double x, double y) { return x >= y; }
+    pure int isgreaterequal()(double x, double y) { return x >= y; }
     ///
-    pure int isgreaterequal(real x, real y)     { return x >= y; }
+    pure int isgreaterequal()(real x, real y)     { return x >= y; }
 
     //int isless(real-floating x, real-floating y);
     ///
-    pure int isless(float x, float y)           { return x < y; }
+    pure int isless()(float x, float y)           { return x < y; }
     ///
-    pure int isless(double x, double y)         { return x < y; }
+    pure int isless()(double x, double y)         { return x < y; }
     ///
-    pure int isless(real x, real y)             { return x < y; }
+    pure int isless()(real x, real y)             { return x < y; }
 
     //int islessequal(real-floating x, real-floating y);
     ///
-    pure int islessequal(float x, float y)      { return x <= y; }
+    pure int islessequal()(float x, float y)      { return x <= y; }
     ///
-    pure int islessequal(double x, double y)    { return x <= y; }
+    pure int islessequal()(double x, double y)    { return x <= y; }
     ///
-    pure int islessequal(real x, real y)        { return x <= y; }
+    pure int islessequal()(real x, real y)        { return x <= y; }
 
     //int islessgreater(real-floating x, real-floating y);
     ///
-    pure int islessgreater(float x, float y)    { return x != y && !isunordered(x, y); }
+    pure int islessgreater()(float x, float y)    { return x != y && !isunordered(x, y); }
     ///
-    pure int islessgreater(double x, double y)  { return x != y && !isunordered(x, y); }
+    pure int islessgreater()(double x, double y)  { return x != y && !isunordered(x, y); }
     ///
-    pure int islessgreater(real x, real y)      { return x != y && !isunordered(x, y); }
+    pure int islessgreater()(real x, real y)      { return x != y && !isunordered(x, y); }
 
     //int isunordered(real-floating x, real-floating y);
     ///
-    pure int isunordered(float x, float y)      { return isnan(x) || isnan(y); }
+    pure int isunordered()(float x, float y)      { return isnan(x) || isnan(y); }
     ///
-    pure int isunordered(double x, double y)    { return isnan(x) || isnan(y); }
+    pure int isunordered()(double x, double y)    { return isnan(x) || isnan(y); }
     ///
-    pure int isunordered(real x, real y)        { return isnan(x) || isnan(y); }
+    pure int isunordered()(real x, real y)        { return isnan(x) || isnan(y); }
 }
 
 /* MS define some functions inline.
diff --git a/libphobos/libdruntime/core/stdc/stdarg.d b/libphobos/libdruntime/core/stdc/stdarg.d
index 0ba1ebe34e38..c694dfb3ac3f 100644
--- a/libphobos/libdruntime/core/stdc/stdarg.d
+++ b/libphobos/libdruntime/core/stdc/stdarg.d
@@ -316,7 +316,7 @@ else version (LDC)
 }
 else version (DigitalMars)
 {
-    void va_end(va_list ap) {}
+    void va_end()(va_list ap) {}
 }
 
 
diff --git a/libphobos/libdruntime/core/sys/bionic/err.d b/libphobos/libdruntime/core/sys/bionic/err.d
index e2756e10c91b..a14f21bb1ec1 100644
--- a/libphobos/libdruntime/core/sys/bionic/err.d
+++ b/libphobos/libdruntime/core/sys/bionic/err.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.bionic.err;
 import core.stdc.stdarg : va_list;
diff --git a/libphobos/libdruntime/core/sys/bionic/string.d b/libphobos/libdruntime/core/sys/bionic/string.d
index 10a5610ac449..9430a7bab4e3 100644
--- a/libphobos/libdruntime/core/sys/bionic/string.d
+++ b/libphobos/libdruntime/core/sys/bionic/string.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.bionic.string;
 
diff --git a/libphobos/libdruntime/core/sys/darwin/err.d b/libphobos/libdruntime/core/sys/darwin/err.d
index d96c790f3b66..19b51626a167 100644
--- a/libphobos/libdruntime/core/sys/darwin/err.d
+++ b/libphobos/libdruntime/core/sys/darwin/err.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.darwin.err;
 import core.stdc.stdarg : va_list;
diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d
index ac988b58f0d4..14bae215cde7 100644
--- a/libphobos/libdruntime/core/sys/darwin/string.d
+++ b/libphobos/libdruntime/core/sys/darwin/string.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.darwin.string;
 
diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/err.d b/libphobos/libdruntime/core/sys/dragonflybsd/err.d
index c3693f85f5ea..7f7cf9467fa0 100644
--- a/libphobos/libdruntime/core/sys/dragonflybsd/err.d
+++ b/libphobos/libdruntime/core/sys/dragonflybsd/err.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.dragonflybsd.err;
 import core.stdc.stdarg : va_list;
diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/string.d b/libphobos/libdruntime/core/sys/dragonflybsd/string.d
index 1a85ba606a19..c15bb9268e58 100644
--- a/libphobos/libdruntime/core/sys/dragonflybsd/string.d
+++ b/libphobos/libdruntime/core/sys/dragonflybsd/string.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.dragonflybsd.string;
 
diff --git a/libphobos/libdruntime/core/sys/freebsd/err.d b/libphobos/libdruntime/core/sys/freebsd/err.d
index 8937e0ec7057..5cb443a6f8a2 100644
--- a/libphobos/libdruntime/core/sys/freebsd/err.d
+++ b/libphobos/libdruntime/core/sys/freebsd/err.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.freebsd.err;
 import core.stdc.stdarg : va_list;
diff --git a/libphobos/libdruntime/core/sys/freebsd/string.d b/libphobos/libdruntime/core/sys/freebsd/string.d
index 459e9115878e..ba7b3c019d90 100644
--- a/libphobos/libdruntime/core/sys/freebsd/string.d
+++ b/libphobos/libdruntime/core/sys/freebsd/string.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.freebsd.string;
 
diff --git a/libphobos/libdruntime/core/sys/linux/err.d b/libphobos/libdruntime/core/sys/linux/err.d
index c3752de52070..d346a0805ff4 100644
--- a/libphobos/libdruntime/core/sys/linux/err.d
+++ b/libphobos/libdruntime/core/sys/linux/err.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.linux.err;
 import core.stdc.stdarg : va_list;
diff --git a/libphobos/libdruntime/core/sys/linux/linux/if_packet.d b/libphobos/libdruntime/core/sys/linux/linux/if_packet.d
index b50b6a339140..6dd95808d61c 100644
--- a/libphobos/libdruntime/core/sys/linux/linux/if_packet.d
+++ b/libphobos/libdruntime/core/sys/linux/linux/if_packet.d
@@ -169,7 +169,7 @@ struct tpacket_hdr
 }
 
 enum TPACKET_ALIGNMENT = 16;
-size_t TPACKET_ALIGN(size_t x) { return (x + TPACKET_ALIGNMENT - 1) &~ (TPACKET_ALIGNMENT - 1); }
+size_t TPACKET_ALIGN()(size_t x) { return (x + TPACKET_ALIGNMENT - 1) &~ (TPACKET_ALIGNMENT - 1); }
 enum TPACKET_HDRLEN = TPACKET_ALIGN(tpacket_hdr.sizeof) + sockaddr_ll.sizeof;
 
 struct tpacket2_hdr
diff --git a/libphobos/libdruntime/core/sys/linux/netinet/in_.d b/libphobos/libdruntime/core/sys/linux/netinet/in_.d
index 1b428f5aeccc..f3c23572fb2c 100644
--- a/libphobos/libdruntime/core/sys/linux/netinet/in_.d
+++ b/libphobos/libdruntime/core/sys/linux/netinet/in_.d
@@ -82,28 +82,28 @@ version (linux_libc)
 
     enum IPPORT_USERRESERVED = 5000;
 
-    extern(D) bool IN_CLASSA(in_addr_t i) pure @safe { return (i & 0x80000000) == 0; }
+    extern(D) bool IN_CLASSA()(in_addr_t i) pure @safe { return (i & 0x80000000) == 0; }
     enum IN_CLASSA_NET    = 0xff000000;
     enum IN_CLASSA_NSHIFT = 24;
     enum IN_CLASSA_HOST   = 0xffffffff & ~IN_CLASSA_NET;
     enum IN_CLASSA_MAX    = 128;
 
-    extern(D) bool IN_CLASSB(in_addr_t i) pure @safe { return (i & 0xc0000000) == 0x80000000; }
+    extern(D) bool IN_CLASSB()(in_addr_t i) pure @safe { return (i & 0xc0000000) == 0x80000000; }
     enum IN_CLASSB_NET    = 0xffff0000;
     enum IN_CLASSB_NSHIFT = 16;
     enum IN_CLASSB_HOST   = 0xffffffff & ~IN_CLASSB_NET;
     enum IN_CLASSB_MAX    = 65536;
 
-    extern(D) bool IN_CLASSC(in_addr_t i) pure @safe { return (i & 0xe0000000) == 0xc0000000; }
+    extern(D) bool IN_CLASSC()(in_addr_t i) pure @safe { return (i & 0xe0000000) == 0xc0000000; }
     enum IN_CLASSC_NET    = 0xffffff00;
     enum IN_CLASSC_NSHIFT = 8;
     enum IN_CLASSC_HOST   = 0xffffffff & ~IN_CLASSC_NET;
 
-    extern(D) bool IN_CLASSD(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xe0000000; }
-    extern(D) bool IN_MULTICAST(in_addr_t i) { return IN_CLASSD(i); }
+    extern(D) bool IN_CLASSD()(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xe0000000; }
+    extern(D) bool IN_MULTICAST()(in_addr_t i) { return IN_CLASSD(i); }
 
-    extern(D) bool IN_EXPERIMENTAL(in_addr_t i) pure @safe { return (i & 0xe0000000) == 0xe0000000; }
-    extern(D) bool IN_BADCLASS(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xf0000000; }
+    extern(D) bool IN_EXPERIMENTAL()(in_addr_t i) pure @safe { return (i & 0xe0000000) == 0xe0000000; }
+    extern(D) bool IN_BADCLASS()(in_addr_t i) pure @safe { return (i & 0xf0000000) == 0xf0000000; }
 
     enum IN_LOOPBACKNET = 127;
 
diff --git a/libphobos/libdruntime/core/sys/linux/perf_event.d b/libphobos/libdruntime/core/sys/linux/perf_event.d
index 0ad072974d5c..f8bedfb81bd9 100644
--- a/libphobos/libdruntime/core/sys/linux/perf_event.d
+++ b/libphobos/libdruntime/core/sys/linux/perf_event.d
@@ -13,82 +13,13 @@ nothrow:
 import core.sys.posix.sys.ioctl;
 import core.sys.posix.unistd;
 
-version (HPPA)    version = HPPA_Any;
-version (HPPA64)  version = HPPA_Any;
-version (PPC)     version = PPC_Any;
-version (PPC64)   version = PPC_Any;
-version (RISCV32) version = RISCV_Any;
-version (RISCV64) version = RISCV_Any;
-version (S390)    version = IBMZ_Any;
-version (SPARC)   version = SPARC_Any;
-version (SPARC64) version = SPARC_Any;
-version (SystemZ) version = IBMZ_Any;
-
-version (X86_64)
-{
-    version (D_X32)
-        enum __NR_perf_event_open = 0x40000000 + 298;
-    else
-        enum __NR_perf_event_open = 298;
-}
-else version (X86)
-{
-        enum __NR_perf_event_open = 336;
-}
-else version (ARM)
-{
-        enum __NR_perf_event_open = 364;
-}
-else version (AArch64)
-{
-        enum __NR_perf_event_open = 241;
-}
-else version (HPPA_Any)
-{
-        enum __NR_perf_event_open = 318;
-}
-else version (IBMZ_Any)
-{
-        enum __NR_perf_event_open = 331;
-}
-else version (MIPS32)
-{
-        enum __NR_perf_event_open = 4333;
-}
-else version (MIPS64)
-{
-    version (MIPS_N32)
-        enum __NR_perf_event_open = 6296;
-    else version (MIPS_N64)
-        enum __NR_perf_event_open = 5292;
-    else
-        static assert(0, "Architecture not supported");
-}
-else version (PPC_Any)
-{
-        enum __NR_perf_event_open = 319;
-}
-else version (RISCV_Any)
-{
-        enum __NR_perf_event_open = 241;
-}
-else version (SPARC_Any)
-{
-        enum __NR_perf_event_open = 327;
-}
-else version (LoongArch64)
-{
-        enum __NR_perf_event_open = 241;
-}
-else
-{
-        static assert(0, "Architecture not supported");
-}
-extern (C) extern long syscall(long __sysno, ...);
 static long perf_event_open(perf_event_attr* hw_event, pid_t pid, int cpu, int group_fd, ulong flags)
 {
-        return syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
+    import core.sys.linux.unistd : syscall;
+    import core.sys.linux.syscall : __NR_perf_event_open;
+    return syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
 }
+
 /*
  * User-space ABI bits:
  */
diff --git a/libphobos/libdruntime/core/sys/linux/sched.d b/libphobos/libdruntime/core/sys/linux/sched.d
index 5cd512e82630..0a940db65ed4 100644
--- a/libphobos/libdruntime/core/sys/linux/sched.d
+++ b/libphobos/libdruntime/core/sys/linux/sched.d
@@ -41,31 +41,31 @@ private // helpers
     /* Macros */
 
     /* Basic access functions.  */
-    size_t __CPUELT(size_t cpu) pure
+    size_t __CPUELT()(size_t cpu) pure
     {
         return cpu / __NCPUBITS;
     }
-    cpu_mask __CPUMASK(size_t cpu) pure
+    cpu_mask __CPUMASK()(size_t cpu) pure
     {
         return 1UL << (cpu % __NCPUBITS);
     }
 
-    cpu_set_t* __CPU_ALLOC(size_t count)
+    cpu_set_t* __CPU_ALLOC()(size_t count)
     {
         return cast(cpu_set_t*) malloc(__CPU_ALLOC_SIZE(count));
     }
 
-    size_t __CPU_ALLOC_SIZE(size_t count) pure
+    size_t __CPU_ALLOC_SIZE()(size_t count) pure
     {
         return ((count + __NCPUBITS - 1) / __NCPUBITS) * cpu_mask.sizeof;
     }
 
-    void __CPU_FREE(cpu_set_t* set)
+    void __CPU_FREE()(cpu_set_t* set)
     {
         free(cast(void*) set);
     }
 
-    cpu_mask __CPU_SET_S(size_t cpu, size_t setsize, cpu_set_t* cpusetp) pure
+    cpu_mask __CPU_SET_S()(size_t cpu, size_t setsize, cpu_set_t* cpusetp) pure
     {
         if (cpu < 8 * setsize)
         {
@@ -76,14 +76,14 @@ private // helpers
         return 0;
     }
 
-    bool __CPU_ISSET_S(size_t cpu, size_t setsize, cpu_set_t* cpusetp) pure
+    bool __CPU_ISSET_S()(size_t cpu, size_t setsize, cpu_set_t* cpusetp) pure
     {
         if (cpu < 8 * setsize)
             return (cpusetp.__bits[__CPUELT(cpu)] & __CPUMASK(cpu)) != 0;
         return false;
     }
 
-    int __CPU_COUNT_S(size_t setsize, cpu_set_t* cpusetp) pure
+    int __CPU_COUNT_S()(size_t setsize, cpu_set_t* cpusetp) pure
     {
         int s = 0;
         foreach (i; cpusetp.__bits[0 .. (setsize / cpu_mask.sizeof)])
@@ -103,37 +103,37 @@ struct cpu_set_t
 
 /// Access macros for 'cpu_set' (missing a lot of them)
 
-cpu_set_t* CPU_ALLOC(size_t count)
+cpu_set_t* CPU_ALLOC()(size_t count)
 {
     return __CPU_ALLOC(count);
 }
 
-size_t CPU_ALLOC_SIZE(size_t count) pure
+size_t CPU_ALLOC_SIZE()(size_t count) pure
 {
     return __CPU_ALLOC_SIZE(count);
 }
 
-void CPU_FREE(cpu_set_t* set)
+void CPU_FREE()(cpu_set_t* set)
 {
     __CPU_FREE(set);
 }
 
-cpu_mask CPU_SET(size_t cpu, cpu_set_t* cpusetp) pure
+cpu_mask CPU_SET()(size_t cpu, cpu_set_t* cpusetp) pure
 {
      return __CPU_SET_S(cpu, cpu_set_t.sizeof, cpusetp);
 }
 
-bool CPU_ISSET(size_t cpu, cpu_set_t* cpusetp) pure
+bool CPU_ISSET()(size_t cpu, cpu_set_t* cpusetp) pure
 {
     return __CPU_ISSET_S(cpu, cpu_set_t.sizeof, cpusetp);
 }
 
-int CPU_COUNT(cpu_set_t* cpusetp) pure
+int CPU_COUNT()(cpu_set_t* cpusetp) pure
 {
     return __CPU_COUNT_S(cpu_set_t.sizeof, cpusetp);
 }
 
-int CPU_COUNT_S(size_t setsize, cpu_set_t* cpusetp) pure
+int CPU_COUNT_S()(size_t setsize, cpu_set_t* cpusetp) pure
 {
     return __CPU_COUNT_S(setsize, cpusetp);
 }
diff --git a/libphobos/libdruntime/core/sys/linux/string.d b/libphobos/libdruntime/core/sys/linux/string.d
index a8da39824612..7288231730d1 100644
--- a/libphobos/libdruntime/core/sys/linux/string.d
+++ b/libphobos/libdruntime/core/sys/linux/string.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.linux.string;
 
diff --git a/libphobos/libdruntime/core/sys/linux/sys/syscall.d b/libphobos/libdruntime/core/sys/linux/sys/syscall.d
new file mode 100644
index 000000000000..9e313e15c93d
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/linux/sys/syscall.d
@@ -0,0 +1,127 @@
+/**
+ * D header file for GNU/Linux
+ *
+ * $(LINK2 https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/sys/syscall.h, glibc sys/syscall.h)
+ */
+
+module core.sys.linux.sys.syscall;
+
+version (linux):
+extern (C):
+@nogc:
+nothrow:
+
+version (HPPA)    version = HPPA_Any;
+version (HPPA64)  version = HPPA_Any;
+version (PPC)     version = PPC_Any;
+version (PPC64)   version = PPC_Any;
+version (RISCV32) version = RISCV_Any;
+version (RISCV64) version = RISCV_Any;
+version (S390)    version = IBMZ_Any;
+version (SPARC)   version = SPARC_Any;
+version (SPARC64) version = SPARC_Any;
+version (SystemZ) version = IBMZ_Any;
+
+/+
+    Check out the following links for handy tables:
+
+    - <https://gpages.juszkiewicz.com.pl/syscalls-table/syscalls.html>
+    - <https://github.com/hrw/syscalls-table>
+ +/
+
+// <asm/unistd.h>
+// List the numbers of the system calls the system knows.
+version (X86_64)
+{
+    version (D_X32)
+    {
+        private enum __X32_SYSCALL_BIT = 0x40000000;
+
+        enum __NR_getrandom = __X32_SYSCALL_BIT + 318;
+        enum __NR_perf_event_open = __X32_SYSCALL_BIT + 298;
+    }
+    else
+    {
+        enum __NR_getrandom = 318;
+        enum __NR_perf_event_open = 298;
+    }
+}
+else version (X86)
+{
+    enum __NR_getrandom = 355;
+    enum __NR_perf_event_open = 336;
+}
+else version (ARM)
+{
+    enum __NR_getrandom = 384;
+    enum __NR_perf_event_open = 364;
+}
+else version (AArch64)
+{
+    enum __NR_getrandom = 278;
+    enum __NR_perf_event_open = 241;
+}
+else version (HPPA_Any)
+{
+    enum __NR_getrandom = 339;
+    enum __NR_perf_event_open = 318;
+}
+else version (IBMZ_Any)
+{
+    enum __NR_getrandom = 349;
+    enum __NR_perf_event_open = 331;
+}
+else version (MIPS32)
+{
+    enum __NR_getrandom = 4353;
+    enum __NR_perf_event_open = 4333;
+}
+else version (MIPS64)
+{
+    version (MIPS_N32)
+    {
+        enum __NR_getrandom = 6317;
+        enum __NR_perf_event_open = 6296;
+    }
+    else version (MIPS_N64)
+    {
+        enum __NR_getrandom = 5313;
+        enum __NR_perf_event_open = 5292;
+    }
+    else
+        static assert(0, "Architecture not supported");
+}
+else version (PPC_Any)
+{
+    enum __NR_getrandom = 359;
+    enum __NR_perf_event_open = 319;
+}
+else version (RISCV_Any)
+{
+    enum __NR_getrandom = 278;
+    enum __NR_perf_event_open = 241;
+}
+else version (SPARC_Any)
+{
+    enum __NR_getrandom = 347;
+    enum __NR_perf_event_open = 327;
+}
+else version (LoongArch64)
+{
+    enum __NR_getrandom = 278;
+    enum __NR_perf_event_open = 241;
+}
+else version (Xtensa)
+{
+    enum __NR_getrandom = 338;
+    enum __NR_perf_event_open = 327;
+}
+else
+{
+    static assert(0, "Architecture not supported");
+}
+
+// <bits/syscall.h>
+// Defines SYS_* names for the __NR_* numbers of known names.
+enum SYS_getrandom = __NR_getrandom;
+enum SYS_perf_event_open = __NR_perf_event_open;
diff --git a/libphobos/libdruntime/core/sys/linux/sys/time.d b/libphobos/libdruntime/core/sys/linux/sys/time.d
index 4b56229687c7..9eb48f1c5ef7 100644
--- a/libphobos/libdruntime/core/sys/linux/sys/time.d
+++ b/libphobos/libdruntime/core/sys/linux/sys/time.d
@@ -23,7 +23,7 @@ version (linux):
  */
 extern (D) pure @safe @nogc nothrow {
 
-    void timeradd(const timeval* a, const timeval* b,
+    void timeradd()(const timeval* a, const timeval* b,
             timeval* result)
     {
         result.tv_sec = a.tv_sec + b.tv_sec;
@@ -35,7 +35,7 @@ extern (D) pure @safe @nogc nothrow {
         }
     }
 
-    void timersub(const timeval* a, const timeval* b,
+    void timersub()(const timeval* a, const timeval* b,
             timeval *result)
     {
         result.tv_sec = a.tv_sec - b.tv_sec;
@@ -46,12 +46,12 @@ extern (D) pure @safe @nogc nothrow {
         }
     }
 
-    void timerclear(timeval* tvp)
+    void timerclear()(timeval* tvp)
     {
         (tvp.tv_sec = tvp.tv_usec = 0);
     }
 
-    int timerisset(timeval* tvp)
+    int timerisset()(timeval* tvp)
     {
         return cast(int) (tvp.tv_sec || tvp.tv_usec);
     }
diff --git a/libphobos/libdruntime/core/sys/linux/syscall.d b/libphobos/libdruntime/core/sys/linux/syscall.d
new file mode 100644
index 000000000000..84d03e75fb1a
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/linux/syscall.d
@@ -0,0 +1,14 @@
+/**
+ * D header file for GNU/Linux
+ *
+ * $(LINK2 https://sourceware.org/git/?p=glibc.git;a=blob;f=misc/syscall.h, glibc syscall.h)
+ */
+
+module core.sys.linux.syscall;
+
+version (linux):
+extern (C):
+@nogc:
+nothrow:
+
+public import core.sys.linux.sys.syscall;
diff --git a/libphobos/libdruntime/core/sys/linux/unistd.d b/libphobos/libdruntime/core/sys/linux/unistd.d
index 548870268dbf..3194ec2962c6 100644
--- a/libphobos/libdruntime/core/sys/linux/unistd.d
+++ b/libphobos/libdruntime/core/sys/linux/unistd.d
@@ -7,6 +7,8 @@ extern(C):
 nothrow:
 @nogc:
 
+import core.stdc.config : c_long;
+
 // Additional seek constants for sparse file handling
 // from Linux's unistd.h, stdio.h, and linux/fs.h
 // (see http://man7.org/linux/man-pages/man2/lseek.2.html)
@@ -25,3 +27,6 @@ void exit_group(int status);
 
 /// Close all open file descriptors greater or equal to `lowfd`
 void closefrom(int lowfd);
+
+/// Invoke system call number `sysno`, passing it the remaining arguments.
+c_long syscall(c_long sysno, ...);
diff --git a/libphobos/libdruntime/core/sys/netbsd/err.d b/libphobos/libdruntime/core/sys/netbsd/err.d
index 44eb66adc2fc..399ddea989a8 100644
--- a/libphobos/libdruntime/core/sys/netbsd/err.d
+++ b/libphobos/libdruntime/core/sys/netbsd/err.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.netbsd.err;
 import core.stdc.stdarg : va_list;
diff --git a/libphobos/libdruntime/core/sys/netbsd/string.d b/libphobos/libdruntime/core/sys/netbsd/string.d
index f1281da275b7..d83d22d56dd8 100644
--- a/libphobos/libdruntime/core/sys/netbsd/string.d
+++ b/libphobos/libdruntime/core/sys/netbsd/string.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.netbsd.string;
 
diff --git a/libphobos/libdruntime/core/sys/netbsd/sys/featuretest.d b/libphobos/libdruntime/core/sys/netbsd/sys/featuretest.d
index 3901ea9703ba..ded053a36e49 100644
--- a/libphobos/libdruntime/core/sys/netbsd/sys/featuretest.d
+++ b/libphobos/libdruntime/core/sys/netbsd/sys/featuretest.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.netbsd.sys.featuretest;
 
diff --git a/libphobos/libdruntime/core/sys/openbsd/err.d b/libphobos/libdruntime/core/sys/openbsd/err.d
index b4676140e382..271f2c4bfc63 100644
--- a/libphobos/libdruntime/core/sys/openbsd/err.d
+++ b/libphobos/libdruntime/core/sys/openbsd/err.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.openbsd.err;
 import core.stdc.stdarg : va_list;
diff --git a/libphobos/libdruntime/core/sys/openbsd/string.d b/libphobos/libdruntime/core/sys/openbsd/string.d
index 4480c94ac37b..e0c33be9d678 100644
--- a/libphobos/libdruntime/core/sys/openbsd/string.d
+++ b/libphobos/libdruntime/core/sys/openbsd/string.d
@@ -3,7 +3,7 @@
   *
   * Copyright: Copyright © 2019, The D Language Foundation
   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
-  * Authors: Ernesto Castellotti
+  * Authors: Emily Castellotti
   */
 module core.sys.openbsd.string;
 
diff --git a/libphobos/libdruntime/core/sys/posix/netdb.d b/libphobos/libdruntime/core/sys/posix/netdb.d
index 70a5fe1901f3..4713f4b49559 100644
--- a/libphobos/libdruntime/core/sys/posix/netdb.d
+++ b/libphobos/libdruntime/core/sys/posix/netdb.d
@@ -153,7 +153,7 @@ version (CRuntime_Glibc)
         int     h_addrtype;
         int     h_length;
         char**  h_addr_list;
-        char*   h_addr() @property { return h_addr_list[0]; } // non-standard
+        char*   h_addr()() @property { return h_addr_list[0]; } // non-standard
     }
 
     struct netent
@@ -237,7 +237,7 @@ else version (Darwin)
         int     h_addrtype;
         int     h_length;
         char**  h_addr_list;
-        char*   h_addr() @property { return h_addr_list[0]; } // non-standard
+        char*   h_addr()() @property { return h_addr_list[0]; } // non-standard
     }
 
     struct netent
@@ -321,7 +321,7 @@ else version (FreeBSD)
         int     h_addrtype;
         int     h_length;
         char**  h_addr_list;
-        extern (D) char* h_addr() @property { return h_addr_list[0]; } // non-standard
+        extern (D) char* h_addr()() @property { return h_addr_list[0]; } // non-standard
     }
 
     struct netent
@@ -405,7 +405,7 @@ else version (NetBSD)
         int     h_addrtype;
         int     h_length;
         char**  h_addr_list;
-        extern (D) char* h_addr() @property { return h_addr_list[0]; } // non-standard
+        extern (D) char* h_addr()() @property { return h_addr_list[0]; } // non-standard
     }
 
     struct netent
@@ -512,7 +512,7 @@ else version (OpenBSD)
         int       h_addrtype;
         int       h_length;
         char**    h_addr_list;
-        extern (D) char* h_addr() @property { return h_addr_list[0]; } // non-standard
+        extern (D) char* h_addr()() @property { return h_addr_list[0]; } // non-standard
     }
 
     struct netent
@@ -608,7 +608,7 @@ else version (DragonFlyBSD)
         int     h_addrtype;
         int     h_length;
         char**  h_addr_list;
-        extern (D) char* h_addr() @property { return h_addr_list[0]; } // non-standard
+        extern (D) char* h_addr()() @property { return h_addr_list[0]; } // non-standard
     }
 
     struct netent
@@ -706,7 +706,7 @@ else version (Solaris)
         int h_length;
         char** h_addr_list;
 
-        extern (D) char* h_addr() @property { return h_addr_list[0]; } // non-standard
+        extern (D) char* h_addr()() @property { return h_addr_list[0]; } // non-standard
     }
 
     struct netent
@@ -793,7 +793,7 @@ else version (CRuntime_Bionic)
         int     h_addrtype;
         int     h_length;
         char**  h_addr_list;
-        extern (D) char* h_addr() @property { return h_addr_list[0]; } // non-standard
+        extern (D) char* h_addr()() @property { return h_addr_list[0]; } // non-standard
     }
 
     struct netent
@@ -874,7 +874,7 @@ else version (CRuntime_Musl)
         int     h_addrtype;
         int     h_length;
         char**  h_addr_list;
-        char*   h_addr() @property { return h_addr_list[0]; } // non-standard
+        char*   h_addr()() @property { return h_addr_list[0]; } // non-standard
     }
 
     struct netent
@@ -952,7 +952,7 @@ else version (CRuntime_UClibc)
         int     h_addrtype;
         int     h_length;
         char**  h_addr_list;
-        extern (D) char* h_addr() @property { return h_addr_list[0]; } // non-standard
+        extern (D) char* h_addr()() @property { return h_addr_list[0]; } // non-standard
     }
 
     struct netent
diff --git a/libphobos/libdruntime/core/sys/posix/netinet/in_.d b/libphobos/libdruntime/core/sys/posix/netinet/in_.d
index 5818ee6e22b6..09a4a5e07d10 100644
--- a/libphobos/libdruntime/core/sys/posix/netinet/in_.d
+++ b/libphobos/libdruntime/core/sys/posix/netinet/in_.d
@@ -547,7 +547,7 @@ version (CRuntime_Glibc)
     }
 
     // macros
-    extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_UNSPECIFIED()(const scope in6_addr* add) pure
     {
         return (cast(uint32_t*) addr)[0] == 0 &&
                (cast(uint32_t*) addr)[1] == 0 &&
@@ -555,7 +555,7 @@ version (CRuntime_Glibc)
                (cast(uint32_t*) addr)[3] == 0;
     }
 
-    extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_LOOPBACK()(const scope in6_addr* add) pure
     {
         return (cast(uint32_t*) addr)[0] == 0  &&
                (cast(uint32_t*) addr)[1] == 0  &&
@@ -563,29 +563,29 @@ version (CRuntime_Glibc)
                (cast(uint32_t*) addr)[3] == htonl( 1 );
     }
 
-    extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MULTICAST()(const scope in6_addr* add) pure
     {
         return (cast(uint8_t*) addr)[0] == 0xff;
     }
 
-    extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_LINKLOCAL()(const scope in6_addr* add) pure
     {
         return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfe800000 );
     }
 
-    extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_SITELOCAL()(const scope in6_addr* add) pure
     {
         return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfec00000 );
     }
 
-    extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_V4MAPPED()(const scope in6_addr* add) pure
     {
         return (cast(uint32_t*) addr)[0] == 0 &&
                (cast(uint32_t*) addr)[1] == 0 &&
                (cast(uint32_t*) addr)[2] == htonl( 0xffff );
     }
 
-    extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_V4COMPAT()(const scope in6_addr* add) pure
     {
         return (cast(uint32_t*) addr)[0] == 0 &&
                (cast(uint32_t*) addr)[1] == 0 &&
@@ -593,31 +593,31 @@ version (CRuntime_Glibc)
                ntohl( (cast(uint32_t*) addr)[3] ) > 1;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_NODELOCAL()(const scope in6_addr* add) pure
     {
         return IN6_IS_ADDR_MULTICAST( addr ) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0x1;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()(const scope in6_addr* add) pure
     {
         return IN6_IS_ADDR_MULTICAST( addr ) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0x2;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_SITELOCAL()(const scope in6_addr* add) pure
     {
         return IN6_IS_ADDR_MULTICAST(addr) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0x5;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()(const scope in6_addr* add) pure
     {
         return IN6_IS_ADDR_MULTICAST( addr) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0x8;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_GLOBAL()(const scope in6_addr* add) pure
     {
         return IN6_IS_ADDR_MULTICAST( addr ) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0xe;
@@ -670,7 +670,7 @@ else version (Darwin)
     }
 
     // macros
-    extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_UNSPECIFIED()(const scope in6_addr* add) pure
     {
         return (cast(uint32_t*) addr)[0] == 0 &&
                (cast(uint32_t*) addr)[1] == 0 &&
@@ -678,7 +678,7 @@ else version (Darwin)
                (cast(uint32_t*) addr)[3] == 0;
     }
 
-    extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_LOOPBACK()(const scope in6_addr* add) pure
     {
         return (cast(uint32_t*) addr)[0] == 0  &&
                (cast(uint32_t*) addr)[1] == 0  &&
@@ -686,29 +686,29 @@ else version (Darwin)
                (cast(uint32_t*) addr)[3] == ntohl( 1 );
     }
 
-    extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MULTICAST()(const scope in6_addr* add) pure
     {
         return addr.s6_addr[0] == 0xff;
     }
 
-    extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_LINKLOCAL()(const scope in6_addr* add) pure
     {
         return addr.s6_addr[0] == 0xfe && (addr.s6_addr[1] & 0xc0) == 0x80;
     }
 
-    extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_SITELOCAL()(const scope in6_addr* add) pure
     {
         return addr.s6_addr[0] == 0xfe && (addr.s6_addr[1] & 0xc0) == 0xc0;
     }
 
-    extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_V4MAPPED()(const scope in6_addr* add) pure
     {
         return (cast(uint32_t*) addr)[0] == 0 &&
                (cast(uint32_t*) addr)[1] == 0 &&
                (cast(uint32_t*) addr)[2] == ntohl( 0x0000ffff );
     }
 
-    extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_V4COMPAT()(const scope in6_addr* add) pure
     {
         return (cast(uint32_t*) addr)[0] == 0 &&
                (cast(uint32_t*) addr)[1] == 0 &&
@@ -717,31 +717,31 @@ else version (Darwin)
                (cast(uint32_t*) addr)[3] != ntohl( 1 );
     }
 
-    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_NODELOCAL()(const scope in6_addr* add) pure
     {
         return IN6_IS_ADDR_MULTICAST( addr ) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0x1;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()(const scope in6_addr* add) pure
     {
         return IN6_IS_ADDR_MULTICAST( addr ) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0x2;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_SITELOCAL()(const scope in6_addr* add) pure
     {
         return IN6_IS_ADDR_MULTICAST(addr) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0x5;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()(const scope in6_addr* add) pure
     {
         return IN6_IS_ADDR_MULTICAST( addr) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0x8;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_GLOBAL()(const scope in6_addr* add) pure
     {
         return IN6_IS_ADDR_MULTICAST( addr ) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0xe;
@@ -804,7 +804,7 @@ else version (FreeBSD)
     }
 
     // macros
-    extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_UNSPECIFIED()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -812,7 +812,7 @@ else version (FreeBSD)
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);
     }
 
-    extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_LOOPBACK()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -820,7 +820,7 @@ else version (FreeBSD)
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));
     }
 
-    extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_V4COMPAT()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -829,58 +829,58 @@ else version (FreeBSD)
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));
     }
 
-    extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_V4MAPPED()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));
     }
 
-    extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_LINKLOCAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;
     }
 
-    extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_SITELOCAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;
     }
 
-    extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MULTICAST()( const scope in6_addr* a) pure
     {
         return a.s6_addr[0] == 0xff;
     }
 
-    extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure
+    extern (D) uint8_t __IPV6_ADDR_MC_SCOPE()( const scope in6_addr* a) pure
     {
         return a.s6_addr[1] & 0x0f;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_NODELOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_SITELOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_GLOBAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;
@@ -943,7 +943,7 @@ else version (NetBSD)
     }
 
     // macros
-    extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_UNSPECIFIED()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -951,7 +951,7 @@ else version (NetBSD)
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);
     }
 
-    extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_LOOPBACK()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -959,7 +959,7 @@ else version (NetBSD)
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));
     }
 
-    extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_V4COMPAT()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -968,58 +968,58 @@ else version (NetBSD)
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));
     }
 
-    extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_V4MAPPED()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));
     }
 
-    extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_LINKLOCAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;
     }
 
-    extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_SITELOCAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;
     }
 
-    extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MULTICAST()( const scope in6_addr* a) pure
     {
         return a.s6_addr[0] == 0xff;
     }
 
-    extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure
+    extern (D) uint8_t __IPV6_ADDR_MC_SCOPE()( const scope in6_addr* a) pure
     {
         return a.s6_addr[1] & 0x0f;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_NODELOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_SITELOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_GLOBAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;
@@ -1082,7 +1082,7 @@ else version (OpenBSD)
     }
 
     // macros
-    extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_UNSPECIFIED()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1090,7 +1090,7 @@ else version (OpenBSD)
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);
     }
 
-    extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_LOOPBACK()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1098,7 +1098,7 @@ else version (OpenBSD)
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));
     }
 
-    extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_V4COMPAT()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1107,58 +1107,58 @@ else version (OpenBSD)
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));
     }
 
-    extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_V4MAPPED()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));
     }
 
-    extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_LINKLOCAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;
     }
 
-    extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_SITELOCAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;
     }
 
-    extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MULTICAST()( const scope in6_addr* a) pure
     {
         return a.s6_addr[0] == 0xff;
     }
 
-    extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure
+    extern (D) uint8_t __IPV6_ADDR_MC_SCOPE()( const scope in6_addr* a) pure
     {
         return a.s6_addr[1] & 0x0f;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_NODELOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_SITELOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_GLOBAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;
@@ -1221,7 +1221,7 @@ else version (DragonFlyBSD)
     }
 
     // macros
-    extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_UNSPECIFIED()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1229,7 +1229,7 @@ else version (DragonFlyBSD)
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == 0);
     }
 
-    extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_LOOPBACK()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1237,7 +1237,7 @@ else version (DragonFlyBSD)
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) == ntohl(1));
     }
 
-    extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_V4COMPAT()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
@@ -1246,58 +1246,58 @@ else version (DragonFlyBSD)
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[12]) != ntohl(1));
     }
 
-    extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_V4MAPPED()( const scope in6_addr* a) pure
     {
         return (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[0]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[4]) == 0) &&
                (*cast(const uint32_t*) cast(const void*) (&a.s6_addr[8]) == ntohl(0x0000ffff));
     }
 
-    extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_LINKLOCAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0x80;
     }
 
-    extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_SITELOCAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr[0] == 0xfe && (a.s6_addr[1] & 0xc0) == 0xc0;
     }
 
-    extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MULTICAST()( const scope in6_addr* a) pure
     {
         return a.s6_addr[0] == 0xff;
     }
 
-    extern (D) uint8_t __IPV6_ADDR_MC_SCOPE( const scope in6_addr* a ) pure
+    extern (D) uint8_t __IPV6_ADDR_MC_SCOPE()( const scope in6_addr* a) pure
     {
         return a.s6_addr[1] & 0x0f;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_NODELOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_SITELOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_GLOBAL()( const scope in6_addr* a) pure
     {
         return IN6_IS_ADDR_MULTICAST(a) &&
                __IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL;
@@ -1350,67 +1350,67 @@ else version (Solaris)
     }
 
     // macros
-    extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_UNSPECIFIED()( const scope in6_addr* a) pure
     {
         return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&
                (a.s6_addr32[2] == 0) && (a.s6_addr32[3] == 0);
     }
 
-    extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_LOOPBACK()( const scope in6_addr* a) pure
     {
         return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&
                (a.s6_addr32[2] == 0) && (a.s6_addr32[3] == ntohl(1));
     }
 
-    extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_V4COMPAT()( const scope in6_addr* a) pure
     {
         return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&
                (a.s6_addr32[2] == 0) && (a.s6_addr32[3] != 0) &&
                (a.s6_addr32[3] != ntohl(1));
     }
 
-    extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_V4MAPPED()( const scope in6_addr* a) pure
     {
         return (a.s6_addr32[0] == 0) && (a.s6_addr32[1] == 0) &&
                (a.s6_addr32[2] == ntohl(0x0000ffff));
     }
 
-    extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_LINKLOCAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr8[0] == 0xfe && (a.s6_addr8[1] & 0xc0) == 0x80;
     }
 
-    extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_SITELOCAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr8[0] == 0xfe && (a.s6_addr8[1] & 0xc0) == 0xc0;
     }
 
-    extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MULTICAST()( const scope in6_addr* a) pure
     {
         return a.s6_addr8[0] == 0xff;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_NODELOCAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x01;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x02;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_SITELOCAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x05;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x08;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* a ) pure
+    extern (D) int IN6_IS_ADDR_MC_GLOBAL()( const scope in6_addr* a) pure
     {
         return a.s6_addr8[0] == 0xff && (a.s6_addr8[1] & 0x0f) == 0x0e;
     }
@@ -1640,7 +1640,7 @@ else version (CRuntime_UClibc)
     }
 
     // macros
-    extern (D) int IN6_IS_ADDR_UNSPECIFIED( in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_UNSPECIFIED()( in6_addr* addr) pure
     {
         return (cast(uint32_t*) addr)[0] == 0 &&
                (cast(uint32_t*) addr)[1] == 0 &&
@@ -1648,7 +1648,7 @@ else version (CRuntime_UClibc)
                (cast(uint32_t*) addr)[3] == 0;
     }
 
-    extern (D) int IN6_IS_ADDR_LOOPBACK( in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_LOOPBACK()( in6_addr* addr) pure
     {
         return (cast(uint32_t*) addr)[0] == 0  &&
                (cast(uint32_t*) addr)[1] == 0  &&
@@ -1656,29 +1656,29 @@ else version (CRuntime_UClibc)
                (cast(uint32_t*) addr)[3] == htonl( 1 );
     }
 
-    extern (D) int IN6_IS_ADDR_MULTICAST( in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MULTICAST()( in6_addr* addr) pure
     {
         return (cast(uint8_t*) addr)[0] == 0xff;
     }
 
-    extern (D) int IN6_IS_ADDR_LINKLOCAL( in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_LINKLOCAL()( in6_addr* addr) pure
     {
         return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfe800000 );
     }
 
-    extern (D) int IN6_IS_ADDR_SITELOCAL( in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_SITELOCAL()( in6_addr* addr) pure
     {
         return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfec00000 );
     }
 
-    extern (D) int IN6_IS_ADDR_V4MAPPED( in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_V4MAPPED()( in6_addr* addr) pure
     {
         return (cast(uint32_t*) addr)[0] == 0 &&
                (cast(uint32_t*) addr)[1] == 0 &&
                (cast(uint32_t*) addr)[2] == htonl( 0xffff );
     }
 
-    extern (D) int IN6_IS_ADDR_V4COMPAT( in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_V4COMPAT()( in6_addr* addr) pure
     {
         return (cast(uint32_t*) addr)[0] == 0 &&
                (cast(uint32_t*) addr)[1] == 0 &&
@@ -1686,7 +1686,7 @@ else version (CRuntime_UClibc)
                ntohl( (cast(uint32_t*) addr)[3] ) > 1;
     }
 
-    extern (D) int IN6_ARE_ADDR_EQUAL( in6_addr* a, in6_addr* b ) pure
+    extern (D) int IN6_ARE_ADDR_EQUAL()( in6_addr* a, in6_addr* b) pure
     {
         return (cast(uint32_t*) a)[0] == (cast(uint32_t*) b)[0] &&
                (cast(uint32_t*) a)[1] == (cast(uint32_t*) b)[1] &&
@@ -1694,31 +1694,31 @@ else version (CRuntime_UClibc)
                (cast(uint32_t*) a)[3] == (cast(uint32_t*) b)[3];
     }
 
-    extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_NODELOCAL()( in6_addr* addr) pure
     {
         return IN6_IS_ADDR_MULTICAST( addr ) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0x1;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()( in6_addr* addr) pure
     {
         return IN6_IS_ADDR_MULTICAST( addr ) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0x2;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_SITELOCAL()( in6_addr* addr) pure
     {
         return IN6_IS_ADDR_MULTICAST(addr) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0x5;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()( in6_addr* addr) pure
     {
         return IN6_IS_ADDR_MULTICAST( addr) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0x8;
     }
 
-    extern (D) int IN6_IS_ADDR_MC_GLOBAL( in6_addr* addr ) pure
+    extern (D) int IN6_IS_ADDR_MC_GLOBAL()( in6_addr* addr) pure
     {
         return IN6_IS_ADDR_MULTICAST( addr ) &&
                ((cast(uint8_t*) addr)[1] & 0xf) == 0xe;
diff --git a/libphobos/libdruntime/core/sys/posix/signal.d b/libphobos/libdruntime/core/sys/posix/signal.d
index e3d80fb02180..bdc68687d0f6 100644
--- a/libphobos/libdruntime/core/sys/posix/signal.d
+++ b/libphobos/libdruntime/core/sys/posix/signal.d
@@ -179,7 +179,7 @@ else version (linux)
         int __libc_current_sigrtmax();
     }
 
-    @property int SIGRTMIN() nothrow @nogc {
+    @property int SIGRTMIN()() nothrow @nogc {
         __gshared int sig = -1;
         if (sig == -1) {
             sig = __libc_current_sigrtmin();
@@ -187,7 +187,7 @@ else version (linux)
         return sig;
     }
 
-    @property int SIGRTMAX() nothrow @nogc {
+    @property int SIGRTMAX()() nothrow @nogc {
         __gshared int sig = -1;
         if (sig == -1) {
             sig = __libc_current_sigrtmax();
@@ -1012,12 +1012,12 @@ version (linux)
         } _sifields_t _sifields;
 
     nothrow @nogc:
-        @property ref pid_t si_pid() return { return _sifields._kill.si_pid; }
-        @property ref uid_t si_uid() return { return _sifields._kill.si_uid; }
-        @property ref void* si_addr() return { return _sifields._sigfault.si_addr; }
-        @property ref int si_status() return { return _sifields._sigchld.si_status; }
-        @property ref c_long si_band() return { return _sifields._sigpoll.si_band; }
-        @property ref sigval si_value() return { return _sifields._rt.si_sigval; }
+        @property ref pid_t si_pid()() { return _sifields._kill.si_pid; }
+        @property ref uid_t si_uid()() { return _sifields._kill.si_uid; }
+        @property ref void* si_addr()() { return _sifields._sigfault.si_addr; }
+        @property ref int si_status()() { return _sifields._sigchld.si_status; }
+        @property ref c_long si_band()() { return _sifields._sigpoll.si_band; }
+        @property ref sigval si_value()() { return _sifields._rt.si_sigval; }
     }
 
     enum
@@ -2763,6 +2763,11 @@ else version (CRuntime_Musl)
         enum MINSIGSTKSZ = 4096;
         enum SIGSTKSZ    = 16384;
     }
+    else version (RISCV64)
+    {
+        enum MINSIGSTKSZ = 2048;
+        enum SIGSTKSZ    = 8192;
+    }
     else
         static assert(0, "unimplemented");
 
diff --git a/libphobos/libdruntime/core/sys/posix/sys/ioctl.d b/libphobos/libdruntime/core/sys/posix/sys/ioctl.d
index caf3ebafb5a5..27584d357c4d 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/ioctl.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/ioctl.d
@@ -61,7 +61,7 @@ version (linux)
                (is(T == typeof(null)) ? 0 : T.sizeof << _IOC_SIZESHIFT);
     }
 
-    extern (D) int _IO(int type, int nr)
+    extern (D) int _IO()(int type, int nr)
     {
         return _IOC(_IOC_NONE, type, nr);
     }
@@ -81,22 +81,22 @@ version (linux)
         return _IOC!T(_IOC_READ | _IOC_WRITE, type, nr);
     }
 
-    extern (D) int _IOC_DIR(int nr)
+    extern (D) int _IOC_DIR()(int nr)
     {
         return (nr >> _IOC_DIRSHIFT) & _IOC_DIRMASK;
     }
 
-    extern (D) int _IOC_TYPE(int nr)
+    extern (D) int _IOC_TYPE()(int nr)
     {
         return (nr >> _IOC_TYPESHIFT) & _IOC_TYPEMASK;
     }
 
-    extern (D) int _IOC_NR(int nr)
+    extern (D) int _IOC_NR()(int nr)
     {
         return (nr >> _IOC_NRSHIFT) & _IOC_NRMASK;
     }
 
-    extern (D) int _IOC_SIZE(int nr)
+    extern (D) int _IOC_SIZE()(int nr)
     {
         return (nr >> _IOC_SIZESHIFT) & _IOC_SIZEMASK;
     }
diff --git a/libphobos/libdruntime/core/sys/posix/sys/select.d b/libphobos/libdruntime/core/sys/posix/sys/select.d
index bd3425032521..c8a88bddc0ca 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/select.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/select.d
@@ -57,12 +57,12 @@ version (CRuntime_Glibc)
         alias c_long __fd_mask;
         enum uint __NFDBITS = 8 * __fd_mask.sizeof;
 
-        extern (D) auto __FDELT( int d ) pure
+        extern (D) auto __FDELT()( int d ) pure
         {
             return d / __NFDBITS;
         }
 
-        extern (D) auto __FDMASK( int d ) pure
+        extern (D) auto __FDMASK()( int d ) pure
         {
             return cast(__fd_mask) 1 << ( d % __NFDBITS );
         }
@@ -75,22 +75,22 @@ version (CRuntime_Glibc)
         __fd_mask[FD_SETSIZE / __NFDBITS] fds_bits;
     }
 
-    extern (D) void FD_CLR( int fd, fd_set* fdset ) pure
+    extern (D) void FD_CLR()( int fd, fd_set* fdset ) pure
     {
         fdset.fds_bits[__FDELT( fd )] &= ~__FDMASK( fd );
     }
 
-    extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure
+    extern (D) bool FD_ISSET()( int fd, const(fd_set)* fdset ) pure
     {
         return (fdset.fds_bits[__FDELT( fd )] & __FDMASK( fd )) != 0;
     }
 
-    extern (D) void FD_SET( int fd, fd_set* fdset ) pure
+    extern (D) void FD_SET()( int fd, fd_set* fdset ) pure
     {
         fdset.fds_bits[__FDELT( fd )] |= __FDMASK( fd );
     }
 
-    extern (D) void FD_ZERO( fd_set* fdset ) pure
+    extern (D) void FD_ZERO()( fd_set* fdset ) pure
     {
         fdset.fds_bits[0 .. $] = 0;
     }
@@ -148,22 +148,22 @@ else version (Darwin)
         int[(FD_SETSIZE + (__DARWIN_NFDBITS - 1)) / __DARWIN_NFDBITS] fds_bits;
     }
 
-    extern (D) void FD_CLR( int fd, fd_set* fdset ) pure
+    extern (D) void FD_CLR()( int fd, fd_set* fdset ) pure
     {
         fdset.fds_bits[fd / __DARWIN_NFDBITS] &= ~(1 << (fd % __DARWIN_NFDBITS));
     }
 
-    extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure
+    extern (D) bool FD_ISSET()( int fd, const(fd_set)* fdset ) pure
     {
         return (fdset.fds_bits[fd / __DARWIN_NFDBITS] & (1 << (fd % __DARWIN_NFDBITS))) != 0;
     }
 
-    extern (D) void FD_SET( int fd, fd_set* fdset ) pure
+    extern (D) void FD_SET()( int fd, fd_set* fdset ) pure
     {
         fdset.fds_bits[fd / __DARWIN_NFDBITS] |= 1 << (fd % __DARWIN_NFDBITS);
     }
 
-    extern (D) void FD_ZERO( fd_set* fdset ) pure
+    extern (D) void FD_ZERO()( fd_set* fdset ) pure
     {
         fdset.fds_bits[0 .. $] = 0;
     }
@@ -187,27 +187,27 @@ else version (FreeBSD)
         deprecated("druntime incorrectly named fds_bits __fds_bits") alias __fds_bits = fds_bits;
     }
 
-    extern (D) __fd_mask __fdset_mask(uint n) pure
+    extern (D) __fd_mask __fdset_mask()(uint n) pure
     {
         return cast(__fd_mask) 1 << (n % _NFDBITS);
     }
 
-    extern (D) void FD_CLR( int n, fd_set* p ) pure
+    extern (D) void FD_CLR()( int n, fd_set* p ) pure
     {
         p.fds_bits[n / _NFDBITS] &= ~__fdset_mask(n);
     }
 
-    extern (D) bool FD_ISSET( int n, const(fd_set)* p ) pure
+    extern (D) bool FD_ISSET()( int n, const(fd_set)* p ) pure
     {
         return (p.fds_bits[n / _NFDBITS] & __fdset_mask(n)) != 0;
     }
 
-    extern (D) void FD_SET( int n, fd_set* p ) pure
+    extern (D) void FD_SET()( int n, fd_set* p ) pure
     {
         p.fds_bits[n / _NFDBITS] |= __fdset_mask(n);
     }
 
-    extern (D) void FD_ZERO( fd_set* p ) pure
+    extern (D) void FD_ZERO()( fd_set* p ) pure
     {
         fd_set *_p;
         size_t _n;
@@ -237,27 +237,27 @@ else version (NetBSD)
         deprecated("druntime incorrectly named fds_bits __fds_bits") alias __fds_bits = fds_bits;
     }
 
-    extern (D) __fd_mask __fdset_mask(uint n) pure
+    extern (D) __fd_mask __fdset_mask()(uint n) pure
     {
         return cast(__fd_mask) 1 << (n % _NFDBITS);
     }
 
-    extern (D) void FD_CLR( int n, fd_set* p ) pure
+    extern (D) void FD_CLR()( int n, fd_set* p ) pure
     {
         p.fds_bits[n / _NFDBITS] &= ~__fdset_mask(n);
     }
 
-    extern (D) bool FD_ISSET( int n, const(fd_set)* p ) pure
+    extern (D) bool FD_ISSET()( int n, const(fd_set)* p ) pure
     {
         return (p.fds_bits[n / _NFDBITS] & __fdset_mask(n)) != 0;
     }
 
-    extern (D) void FD_SET( int n, fd_set* p ) pure
+    extern (D) void FD_SET()( int n, fd_set* p ) pure
     {
         p.fds_bits[n / _NFDBITS] |= __fdset_mask(n);
     }
 
-    extern (D) void FD_ZERO( fd_set* p ) pure
+    extern (D) void FD_ZERO()( fd_set* p ) pure
     {
         fd_set *_p;
         size_t _n;
@@ -287,27 +287,27 @@ else version (OpenBSD)
         deprecated("druntime incorrectly named fds_bits __fds_bits") alias __fds_bits = fds_bits;
     }
 
-    extern (D) __fd_mask __fdset_mask(uint n) pure
+    extern (D) __fd_mask __fdset_mask()(uint n) pure
     {
         return cast(__fd_mask) 1 << (n % _NFDBITS);
     }
 
-    extern (D) void FD_CLR(int n, fd_set* p) pure
+    extern (D) void FD_CLR()(int n, fd_set* p) pure
     {
         p.fds_bits[n / _NFDBITS] &= ~__fdset_mask(n);
     }
 
-    extern (D) bool FD_ISSET(int n, const(fd_set)* p) pure
+    extern (D) bool FD_ISSET()(int n, const(fd_set)* p) pure
     {
         return (p.fds_bits[n / _NFDBITS] & __fdset_mask(n)) != 0;
     }
 
-    extern (D) void FD_SET(int n, fd_set* p) pure
+    extern (D) void FD_SET()(int n, fd_set* p) pure
     {
         p.fds_bits[n / _NFDBITS] |= __fdset_mask(n);
     }
 
-    extern (D) void FD_ZERO(fd_set* p) pure
+    extern (D) void FD_ZERO()(fd_set* p) pure
     {
         fd_set *_p = p;
         size_t _n = (FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS;
@@ -335,27 +335,27 @@ else version (DragonFlyBSD)
         deprecated("druntime incorrectly named fds_bits __fds_bits") alias __fds_bits = fds_bits;
     }
 
-    extern (D) __fd_mask __fdset_mask(uint n) pure
+    extern (D) __fd_mask __fdset_mask()(uint n) pure
     {
         return cast(__fd_mask) 1 << (n % _NFDBITS);
     }
 
-    extern (D) void FD_CLR( int n, fd_set* p ) pure
+    extern (D) void FD_CLR()( int n, fd_set* p ) pure
     {
         p.fds_bits[n / _NFDBITS] &= ~__fdset_mask(n);
     }
 
-    extern (D) bool FD_ISSET( int n, const(fd_set)* p ) pure
+    extern (D) bool FD_ISSET()( int n, const(fd_set)* p ) pure
     {
         return (p.fds_bits[n / _NFDBITS] & __fdset_mask(n)) != 0;
     }
 
-    extern (D) void FD_SET( int n, fd_set* p ) pure
+    extern (D) void FD_SET()( int n, fd_set* p ) pure
     {
         p.fds_bits[n / _NFDBITS] |= __fdset_mask(n);
     }
 
-    extern (D) void FD_ZERO( fd_set* p ) pure
+    extern (D) void FD_ZERO()( fd_set* p ) pure
     {
         fd_set *_p;
         size_t _n;
@@ -389,22 +389,22 @@ else version (Solaris)
         c_long[(FD_SETSIZE + (FD_NFDBITS - 1)) / FD_NFDBITS] fds_bits;
     }
 
-    extern (D) void FD_SET(int __n, fd_set* __p) pure
+    extern (D) void FD_SET()(int __n, fd_set* __p) pure
     {
         __p.fds_bits[__n / FD_NFDBITS] |= 1UL << (__n % FD_NFDBITS);
     }
 
-    extern (D) void FD_CLR(int __n, fd_set* __p) pure
+    extern (D) void FD_CLR()(int __n, fd_set* __p) pure
     {
         __p.fds_bits[__n / FD_NFDBITS] &= ~(1UL << (__n % FD_NFDBITS));
     }
 
-    extern (D) bool FD_ISSET(int __n, const(fd_set)* __p) pure
+    extern (D) bool FD_ISSET()(int __n, const(fd_set)* __p) pure
     {
         return (__p.fds_bits[__n / FD_NFDBITS] & (1UL << (__n % FD_NFDBITS))) != 0;
     }
 
-    extern (D) void FD_ZERO(fd_set* __p) pure
+    extern (D) void FD_ZERO()(fd_set* __p) pure
     {
         __p.fds_bits[0 .. $] = 0;
     }
@@ -419,12 +419,12 @@ else version (CRuntime_Bionic)
         alias c_ulong __fd_mask;
         enum uint __NFDBITS = 8 * __fd_mask.sizeof;
 
-        extern (D) auto __FDELT( int d ) pure
+        extern (D) auto __FDELT()( int d ) pure
         {
             return d / __NFDBITS;
         }
 
-        extern (D) auto __FDMASK( int d ) pure
+        extern (D) auto __FDMASK()( int d ) pure
         {
             return cast(__fd_mask) 1 << ( d % __NFDBITS );
         }
@@ -438,22 +438,22 @@ else version (CRuntime_Bionic)
     }
 
     // These functions are generated in assembly in bionic.
-    extern (D) void FD_CLR( int fd, fd_set* fdset ) pure
+    extern (D) void FD_CLR()( int fd, fd_set* fdset ) pure
     {
         fdset.fds_bits[__FDELT( fd )] &= ~__FDMASK( fd );
     }
 
-    extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure
+    extern (D) bool FD_ISSET()( int fd, const(fd_set)* fdset ) pure
     {
         return (fdset.fds_bits[__FDELT( fd )] & __FDMASK( fd )) != 0;
     }
 
-    extern (D) void FD_SET( int fd, fd_set* fdset ) pure
+    extern (D) void FD_SET()( int fd, fd_set* fdset ) pure
     {
         fdset.fds_bits[__FDELT( fd )] |= __FDMASK( fd );
     }
 
-    extern (D) void FD_ZERO( fd_set* fdset ) pure
+    extern (D) void FD_ZERO()( fd_set* fdset ) pure
     {
         fdset.fds_bits[0 .. $] = 0;
     }
@@ -471,12 +471,12 @@ else version (CRuntime_Musl)
     {
         enum uint __NFDBITS = 8 * fd_mask.sizeof;
 
-        extern (D) auto __FDELT( int d ) pure
+        extern (D) auto __FDELT()( int d ) pure
         {
             return d / __NFDBITS;
         }
 
-        extern (D) auto __FDMASK( int d ) pure
+        extern (D) auto __FDMASK()( int d ) pure
         {
             return cast(fd_mask) 1 << ( d % __NFDBITS );
         }
@@ -486,22 +486,22 @@ else version (CRuntime_Musl)
         ulong[FD_SETSIZE / 8 / long.sizeof] fds_bits;
     }
 
-    extern (D) void FD_CLR( int fd, fd_set* fdset ) pure
+    extern (D) void FD_CLR()( int fd, fd_set* fdset ) pure
     {
         fdset.fds_bits[__FDELT( fd )] &= ~__FDMASK( fd );
     }
 
-    extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure
+    extern (D) bool FD_ISSET()( int fd, const(fd_set)* fdset ) pure
     {
         return (fdset.fds_bits[__FDELT( fd )] & __FDMASK( fd )) != 0;
     }
 
-    extern (D) void FD_SET( int fd, fd_set* fdset ) pure
+    extern (D) void FD_SET()( int fd, fd_set* fdset ) pure
     {
         fdset.fds_bits[__FDELT( fd )] |= __FDMASK( fd );
     }
 
-    extern (D) void FD_ZERO( fd_set* fdset ) pure
+    extern (D) void FD_ZERO()( fd_set* fdset ) pure
     {
         fdset.fds_bits[0 .. $] = 0;
     }
@@ -517,12 +517,12 @@ else version (CRuntime_UClibc)
         alias c_long __fd_mask;
         enum uint __NFDBITS = 8 * __fd_mask.sizeof;
 
-        extern (D) auto __FDELT( int d ) pure
+        extern (D) auto __FDELT()( int d ) pure
         {
             return d / __NFDBITS;
         }
 
-        extern (D) auto __FDMASK( int d ) pure
+        extern (D) auto __FDMASK()( int d ) pure
         {
             return cast(__fd_mask) 1 << ( d % __NFDBITS );
         }
@@ -535,22 +535,22 @@ else version (CRuntime_UClibc)
         __fd_mask[FD_SETSIZE / __NFDBITS] fds_bits;
     }
 
-    extern (D) void FD_CLR( int fd, fd_set* fdset ) pure
+    extern (D) void FD_CLR()( int fd, fd_set* fdset ) pure
     {
         fdset.fds_bits[__FDELT( fd )] &= ~__FDMASK( fd );
     }
 
-    extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure
+    extern (D) bool FD_ISSET()( int fd, const(fd_set)* fdset ) pure
     {
         return (fdset.fds_bits[__FDELT( fd )] & __FDMASK( fd )) != 0;
     }
 
-    extern (D) void FD_SET( int fd, fd_set* fdset ) pure
+    extern (D) void FD_SET()( int fd, fd_set* fdset ) pure
     {
         fdset.fds_bits[__FDELT( fd )] |= __FDMASK( fd );
     }
 
-    extern (D) void FD_ZERO( fd_set* fdset ) pure
+    extern (D) void FD_ZERO()( fd_set* fdset ) pure
     {
         fdset.fds_bits[0 .. $] = 0;
     }
diff --git a/libphobos/libdruntime/core/sys/posix/sys/socket.d b/libphobos/libdruntime/core/sys/posix/sys/socket.d
index 12824373d586..5bdc22294c1d 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/socket.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/socket.d
@@ -233,12 +233,12 @@ version (linux)
 
     extern (D)
     {
-        size_t CMSG_ALIGN( size_t len ) pure nothrow @nogc
+        size_t CMSG_ALIGN()( size_t len ) pure nothrow @nogc
         {
             return (len + size_t.sizeof - 1) & cast(size_t) (~(size_t.sizeof - 1));
         }
 
-        size_t CMSG_LEN( size_t len ) pure nothrow @nogc
+        size_t CMSG_LEN()( size_t len ) pure nothrow @nogc
         {
             return CMSG_ALIGN(cmsghdr.sizeof) + len;
         }
@@ -668,13 +668,13 @@ else version (Darwin)
 
     extern (D)
     {
-        socklen_t CMSG_ALIGN(socklen_t len) pure nothrow @nogc { return (len + socklen_t.sizeof - 1) & cast(socklen_t) (~(socklen_t.sizeof - 1)); }
-        socklen_t CMSG_SPACE(socklen_t len) pure nothrow @nogc { return CMSG_ALIGN(len) + CMSG_ALIGN(cmsghdr.sizeof); }
-        socklen_t CMSG_LEN(socklen_t len) pure nothrow @nogc { return CMSG_ALIGN(cmsghdr.sizeof) + len; }
+        socklen_t CMSG_ALIGN()(socklen_t len) pure nothrow @nogc { return (len + socklen_t.sizeof - 1) & cast(socklen_t) (~(socklen_t.sizeof - 1)); }
+        socklen_t CMSG_SPACE()(socklen_t len) pure nothrow @nogc { return CMSG_ALIGN(len) + CMSG_ALIGN(cmsghdr.sizeof); }
+        socklen_t CMSG_LEN()(socklen_t len) pure nothrow @nogc { return CMSG_ALIGN(cmsghdr.sizeof) + len; }
 
-        inout(ubyte)*   CMSG_DATA( return scope inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); }
+        inout(ubyte)*   CMSG_DATA()( return scope inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); }
 
-        inout(cmsghdr)* CMSG_FIRSTHDR( inout(msghdr)* mhdr ) pure nothrow @nogc
+        inout(cmsghdr)* CMSG_FIRSTHDR()( inout(msghdr)* mhdr ) pure nothrow @nogc
         {
             return ( cast(socklen_t)mhdr.msg_controllen >= cmsghdr.sizeof ? cast(inout(cmsghdr)*) mhdr.msg_control : cast(inout(cmsghdr)*) null );
         }
diff --git a/libphobos/libdruntime/core/sys/posix/sys/stat.d b/libphobos/libdruntime/core/sys/posix/sys/stat.d
index 328f620a42a2..ab79a4067509 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/stat.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/stat.d
@@ -1464,19 +1464,19 @@ version (CRuntime_Glibc)
 
     private
     {
-        extern (D) bool S_ISTYPE( mode_t mode, uint mask )
+        extern (D) bool S_ISTYPE()( mode_t mode, uint mask )
         {
             return ( mode & S_IFMT ) == mask;
         }
     }
 
-    extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }
-    extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }
-    extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }
-    extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }
-    extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }
-    extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }
-    extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
+    extern (D) bool S_ISBLK()( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }
+    extern (D) bool S_ISCHR()( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }
+    extern (D) bool S_ISDIR()( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }
+    extern (D) bool S_ISFIFO()( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }
+    extern (D) bool S_ISREG()( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }
+    extern (D) bool S_ISLNK()( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }
+    extern (D) bool S_ISSOCK()( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
 
     int utimensat(int dirfd, const char *pathname,
         ref const(timespec)[2] times, int flags);
@@ -1501,19 +1501,19 @@ else version (Darwin)
 
     private
     {
-        extern (D) bool S_ISTYPE( mode_t mode, uint mask )
+        extern (D) bool S_ISTYPE()( mode_t mode, uint mask )
         {
             return ( mode & S_IFMT ) == mask;
         }
     }
 
-    extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }
-    extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }
-    extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }
-    extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }
-    extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }
-    extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }
-    extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
+    extern (D) bool S_ISBLK()( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }
+    extern (D) bool S_ISCHR()( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }
+    extern (D) bool S_ISDIR()( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }
+    extern (D) bool S_ISFIFO()( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }
+    extern (D) bool S_ISREG()( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }
+    extern (D) bool S_ISLNK()( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }
+    extern (D) bool S_ISSOCK()( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
 }
 else version (FreeBSD)
 {
@@ -1534,19 +1534,19 @@ else version (FreeBSD)
 
     private
     {
-        extern (D) bool S_ISTYPE( mode_t mode, uint mask )
+        extern (D) bool S_ISTYPE()( mode_t mode, uint mask )
         {
             return ( mode & S_IFMT ) == mask;
         }
     }
 
-    extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }
-    extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }
-    extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }
-    extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }
-    extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }
-    extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }
-    extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
+    extern (D) bool S_ISBLK()( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }
+    extern (D) bool S_ISCHR()( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }
+    extern (D) bool S_ISDIR()( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }
+    extern (D) bool S_ISFIFO()( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }
+    extern (D) bool S_ISREG()( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }
+    extern (D) bool S_ISLNK()( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }
+    extern (D) bool S_ISSOCK()( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
 
     // Since FreeBSD 11:
     version (none)
@@ -1575,19 +1575,19 @@ else version (NetBSD)
 
     private
     {
-        extern (D) bool S_ISTYPE( mode_t mode, uint mask )
+        extern (D) bool S_ISTYPE()( mode_t mode, uint mask )
         {
             return ( mode & S_IFMT ) == mask;
         }
     }
 
-    extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }
-    extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }
-    extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }
-    extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }
-    extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }
-    extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }
-    extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
+    extern (D) bool S_ISBLK()( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }
+    extern (D) bool S_ISCHR()( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }
+    extern (D) bool S_ISDIR()( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }
+    extern (D) bool S_ISFIFO()( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }
+    extern (D) bool S_ISREG()( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }
+    extern (D) bool S_ISLNK()( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }
+    extern (D) bool S_ISSOCK()( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
 }
 else version (OpenBSD)
 {
@@ -1606,13 +1606,13 @@ else version (OpenBSD)
     enum S_IXOTH    = 0x1; // 0000001
     enum S_IRWXO    = 0x7; // 0000007
 
-    extern (D) bool S_ISBLK(mode_t mode)  { return (mode & S_IFMT) == S_IFBLK;  }
-    extern (D) bool S_ISCHR(mode_t mode)  { return (mode & S_IFMT) == S_IFCHR;  }
-    extern (D) bool S_ISDIR(mode_t mode)  { return (mode & S_IFMT) == S_IFDIR;  }
-    extern (D) bool S_ISFIFO(mode_t mode) { return (mode & S_IFMT) == S_IFIFO;  }
-    extern (D) bool S_ISREG(mode_t mode)  { return (mode & S_IFMT) == S_IFREG;  }
-    extern (D) bool S_ISLNK(mode_t mode)  { return (mode & S_IFMT) == S_IFLNK;  }
-    extern (D) bool S_ISSOCK(mode_t mode) { return (mode & S_IFMT) == S_IFSOCK; }
+    extern (D) bool S_ISBLK()(mode_t mode)  { return (mode & S_IFMT) == S_IFBLK;  }
+    extern (D) bool S_ISCHR()(mode_t mode)  { return (mode & S_IFMT) == S_IFCHR;  }
+    extern (D) bool S_ISDIR()(mode_t mode)  { return (mode & S_IFMT) == S_IFDIR;  }
+    extern (D) bool S_ISFIFO()(mode_t mode) { return (mode & S_IFMT) == S_IFIFO;  }
+    extern (D) bool S_ISREG()(mode_t mode)  { return (mode & S_IFMT) == S_IFREG;  }
+    extern (D) bool S_ISLNK()(mode_t mode)  { return (mode & S_IFMT) == S_IFLNK;  }
+    extern (D) bool S_ISSOCK()(mode_t mode) { return (mode & S_IFMT) == S_IFSOCK; }
 }
 else version (DragonFlyBSD)
 {
@@ -1633,19 +1633,19 @@ else version (DragonFlyBSD)
 
     private
     {
-        extern (D) bool S_ISTYPE( mode_t mode, uint mask )
+        extern (D) bool S_ISTYPE()( mode_t mode, uint mask )
         {
             return ( mode & S_IFMT ) == mask;
         }
     }
 
-    extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }
-    extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }
-    extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }
-    extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }
-    extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }
-    extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }
-    extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
+    extern (D) bool S_ISBLK()( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }
+    extern (D) bool S_ISCHR()( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }
+    extern (D) bool S_ISDIR()( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }
+    extern (D) bool S_ISFIFO()( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }
+    extern (D) bool S_ISREG()( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }
+    extern (D) bool S_ISLNK()( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }
+    extern (D) bool S_ISSOCK()( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
 }
 else version (Solaris)
 {
@@ -1666,21 +1666,21 @@ else version (Solaris)
 
     private
     {
-        extern (D) bool S_ISTYPE(mode_t mode, uint mask)
+        extern (D) bool S_ISTYPE()(mode_t mode, uint mask)
         {
             return (mode & S_IFMT) == mask;
         }
     }
 
-    extern (D) bool S_ISBLK(mode_t mode) { return S_ISTYPE(mode, S_IFBLK); }
-    extern (D) bool S_ISCHR(mode_t mode) { return S_ISTYPE(mode, S_IFCHR); }
-    extern (D) bool S_ISDIR(mode_t mode) { return S_ISTYPE(mode, S_IFDIR); }
-    extern (D) bool S_ISFIFO(mode_t mode) { return S_ISTYPE(mode, S_IFIFO); }
-    extern (D) bool S_ISREG(mode_t mode) { return S_ISTYPE(mode, S_IFREG); }
-    extern (D) bool S_ISLNK(mode_t mode) { return S_ISTYPE(mode, S_IFLNK); }
-    extern (D) bool S_ISSOCK(mode_t mode) { return S_ISTYPE(mode, S_IFSOCK); }
-    extern (D) bool S_ISDOOR(mode_t mode) { return S_ISTYPE(mode, S_IFDOOR); }
-    extern (D) bool S_ISPORT(mode_t mode) { return S_ISTYPE(mode, S_IFPORT); }
+    extern (D) bool S_ISBLK()(mode_t mode) { return S_ISTYPE(mode, S_IFBLK); }
+    extern (D) bool S_ISCHR()(mode_t mode) { return S_ISTYPE(mode, S_IFCHR); }
+    extern (D) bool S_ISDIR()(mode_t mode) { return S_ISTYPE(mode, S_IFDIR); }
+    extern (D) bool S_ISFIFO()(mode_t mode) { return S_ISTYPE(mode, S_IFIFO); }
+    extern (D) bool S_ISREG()(mode_t mode) { return S_ISTYPE(mode, S_IFREG); }
+    extern (D) bool S_ISLNK()(mode_t mode) { return S_ISTYPE(mode, S_IFLNK); }
+    extern (D) bool S_ISSOCK()(mode_t mode) { return S_ISTYPE(mode, S_IFSOCK); }
+    extern (D) bool S_ISDOOR()(mode_t mode) { return S_ISTYPE(mode, S_IFDOOR); }
+    extern (D) bool S_ISPORT()(mode_t mode) { return S_ISTYPE(mode, S_IFPORT); }
 }
 else version (CRuntime_Bionic)
 {
@@ -1701,19 +1701,19 @@ else version (CRuntime_Bionic)
 
     private
     {
-        extern (D) bool S_ISTYPE( uint mode, uint mask )
+        extern (D) bool S_ISTYPE()( uint mode, uint mask )
         {
             return ( mode & S_IFMT ) == mask;
         }
     }
 
-    extern (D) bool S_ISBLK( uint mode )  { return S_ISTYPE( mode, S_IFBLK );  }
-    extern (D) bool S_ISCHR( uint mode )  { return S_ISTYPE( mode, S_IFCHR );  }
-    extern (D) bool S_ISDIR( uint mode )  { return S_ISTYPE( mode, S_IFDIR );  }
-    extern (D) bool S_ISFIFO( uint mode ) { return S_ISTYPE( mode, S_IFIFO );  }
-    extern (D) bool S_ISREG( uint mode )  { return S_ISTYPE( mode, S_IFREG );  }
-    extern (D) bool S_ISLNK( uint mode )  { return S_ISTYPE( mode, S_IFLNK );  }
-    extern (D) bool S_ISSOCK( uint mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
+    extern (D) bool S_ISBLK()( uint mode )  { return S_ISTYPE( mode, S_IFBLK );  }
+    extern (D) bool S_ISCHR()( uint mode )  { return S_ISTYPE( mode, S_IFCHR );  }
+    extern (D) bool S_ISDIR()( uint mode )  { return S_ISTYPE( mode, S_IFDIR );  }
+    extern (D) bool S_ISFIFO()( uint mode ) { return S_ISTYPE( mode, S_IFIFO );  }
+    extern (D) bool S_ISREG()( uint mode )  { return S_ISTYPE( mode, S_IFREG );  }
+    extern (D) bool S_ISLNK()( uint mode )  { return S_ISTYPE( mode, S_IFLNK );  }
+    extern (D) bool S_ISSOCK()( uint mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
 
     // Added since Lollipop
     int utimensat(int dirfd, const char *pathname,
@@ -1740,19 +1740,19 @@ else version (CRuntime_Musl)
 
   [...]

[diff truncated at 524288 bytes]


More information about the Gcc-cvs mailing list