diff mbox series

[committed] d: Merge upstream dmd, druntime 09faa4eacd, phobos 13ef27a56.

Message ID 20230221143536.1818454-1-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] d: Merge upstream dmd, druntime 09faa4eacd, phobos 13ef27a56. | expand

Commit Message

Iain Buclaw Feb. 21, 2023, 2:35 p.m. UTC
Hi,

This patch merges the D front-end/run-time library with upstream dmd
c8ae4adb2e, and standard library with phobos 792c8b7c1.

Synchronizing the latest bug fixes in the v2.102.0 beta release.

D front-end changes:

	- Import dmd v2.102.0-beta.1
	- `static assert' now supports multiple message arguments.

D runtime changes:

	- Import druntime v2.102.0-beta.1
	- The default `Throwable.TraceInfo' generation now is `@nogc'.
	- `Object.factory' method has now been deprecated.

Phobos changes:

	- Import phobos v2.102.0-beta.1
	- Added float- and double-precision implementations for log
	  function families in std.math.
	- `std.typecons.Unique' now calls `destroy` on struct types

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

Regards,
Iain.

---
gcc/d/ChangeLog:

	* Make-lang.in (D_FRONTEND_OBJS): Add d/location.o.
	* d-lang.cc (d_init_options): Update for new front-end interface.
	(d_post_options): Call Loc::set after handling options.
	* dmd/MERGE: Merge upstream dmd 09faa4eacd.
	* dmd/VERSION: Bump version to v2.102.0-beta.1.

libphobos/ChangeLog:

	* libdruntime/MERGE: Merge upstream druntime 09faa4eacd.
	* src/MERGE: Merge upstream phobos 13ef27a56.
	* testsuite/libphobos.exceptions/refcounted.d: Add test for chained
	reference counted exceptions.
	* testsuite/libphobos.shared/finalize.d: Add dg-warning for deprecated
	factory interfaces.
	* testsuite/libphobos.gc/issue22843.d: New test.

gcc/testsuite/ChangeLog:

	* gdc.dg/simd2a.d: Update.
	* gdc.dg/simd2b.d: Update.
	* gdc.dg/simd2c.d: Update.
	* gdc.dg/simd2d.d: Update.
	* gdc.dg/simd2e.d: Update.
	* gdc.dg/simd2f.d: Update.
	* gdc.dg/simd2g.d: Update.
	* gdc.dg/simd2h.d: Update.
	* gdc.dg/simd2i.d: Update.
	* gdc.dg/simd2j.d: Update.
---
 gcc/d/Make-lang.in                            |   1 +
 gcc/d/d-lang.cc                               |   5 +-
 gcc/d/dmd/MERGE                               |   2 +-
 gcc/d/dmd/README.md                           |   1 +
 gcc/d/dmd/VERSION                             |   2 +-
 gcc/d/dmd/access.d                            |   3 +-
 gcc/d/dmd/aggregate.d                         |   5 +-
 gcc/d/dmd/aggregate.h                         |   9 +-
 gcc/d/dmd/aliasthis.d                         |   5 +-
 gcc/d/dmd/aliasthis.h                         |   2 +-
 gcc/d/dmd/apply.d                             |   2 +-
 gcc/d/dmd/arrayop.d                           |   3 +-
 gcc/d/dmd/arraytypes.d                        |   2 +-
 gcc/d/dmd/arraytypes.h                        |   2 +-
 gcc/d/dmd/ast_node.d                          |   2 +-
 gcc/d/dmd/ast_node.h                          |   2 +-
 gcc/d/dmd/astenums.d                          |   2 +-
 gcc/d/dmd/attrib.d                            |   3 +-
 gcc/d/dmd/attrib.h                            |   2 +-
 gcc/d/dmd/blockexit.d                         |   3 +-
 gcc/d/dmd/builtin.d                           |   4 +-
 gcc/d/dmd/canthrow.d                          |   2 +-
 gcc/d/dmd/chkformat.d                         |   3 +-
 gcc/d/dmd/clone.d                             |   3 +-
 gcc/d/dmd/common/bitfields.d                  |   2 +-
 gcc/d/dmd/common/file.d                       |   2 +-
 gcc/d/dmd/common/outbuffer.d                  |   2 +-
 gcc/d/dmd/common/outbuffer.h                  |   2 +-
 gcc/d/dmd/common/string.d                     |   2 +-
 gcc/d/dmd/compiler.d                          |   2 +-
 gcc/d/dmd/compiler.h                          |   2 +-
 gcc/d/dmd/cond.d                              |  17 +-
 gcc/d/dmd/cond.h                              |   2 +-
 gcc/d/dmd/constfold.d                         |  12 +-
 gcc/d/dmd/cparse.d                            |   3 +-
 gcc/d/dmd/cppmangle.d                         |   3 +-
 gcc/d/dmd/ctfe.h                              |   2 +-
 gcc/d/dmd/ctfeexpr.d                          |   3 +-
 gcc/d/dmd/ctorflow.d                          |   4 +-
 gcc/d/dmd/dcast.d                             |  38 +-
 gcc/d/dmd/dclass.d                            |   5 +-
 gcc/d/dmd/declaration.d                       |   8 +-
 gcc/d/dmd/declaration.h                       |   2 +-
 gcc/d/dmd/delegatize.d                        |   3 +-
 gcc/d/dmd/denum.d                             |   3 +-
 gcc/d/dmd/dimport.d                           |   3 +-
 gcc/d/dmd/dinterpret.d                        |  62 ++-
 gcc/d/dmd/dmacro.d                            |   2 +-
 gcc/d/dmd/dmangle.d                           |   2 +-
 gcc/d/dmd/dmodule.d                           |  97 ++++-
 gcc/d/dmd/doc.d                               |   6 +-
 gcc/d/dmd/doc.h                               |   2 +-
 gcc/d/dmd/dscope.d                            |   3 +-
 gcc/d/dmd/dstruct.d                           |   3 +-
 gcc/d/dmd/dsymbol.d                           |   3 +-
 gcc/d/dmd/dsymbol.h                           |   9 +-
 gcc/d/dmd/dsymbolsem.d                        |  49 +--
 gcc/d/dmd/dtemplate.d                         |  69 +--
 gcc/d/dmd/dtoh.d                              |   3 +-
 gcc/d/dmd/dversion.d                          |   3 +-
 gcc/d/dmd/entity.d                            |   2 +-
 gcc/d/dmd/enum.h                              |   2 +-
 gcc/d/dmd/errors.d                            |   3 +-
 gcc/d/dmd/errors.h                            |   2 +-
 gcc/d/dmd/escape.d                            |   5 +-
 gcc/d/dmd/expression.d                        |   9 +-
 gcc/d/dmd/expression.h                        |   2 +-
 gcc/d/dmd/expressionsem.d                     | 108 ++---
 gcc/d/dmd/file_manager.d                      |  55 +--
 gcc/d/dmd/foreachvar.d                        |   2 +-
 gcc/d/dmd/func.d                              | 138 +++---
 gcc/d/dmd/globals.d                           | 132 +-----
 gcc/d/dmd/globals.h                           |  18 +-
 gcc/d/dmd/gluelayer.d                         |   2 +-
 gcc/d/dmd/hdrgen.d                            |  11 +-
 gcc/d/dmd/hdrgen.h                            |   2 +-
 gcc/d/dmd/iasm.d                              |   2 +-
 gcc/d/dmd/iasmgcc.d                           |   3 +-
 gcc/d/dmd/id.d                                |   2 +-
 gcc/d/dmd/id.h                                |   2 +-
 gcc/d/dmd/identifier.d                        |   4 +-
 gcc/d/dmd/identifier.h                        |   2 +-
 gcc/d/dmd/impcnvtab.d                         |   2 +-
 gcc/d/dmd/imphint.d                           |   2 +-
 gcc/d/dmd/import.h                            |   2 +-
 gcc/d/dmd/importc.d                           |   2 +-
 gcc/d/dmd/init.d                              |   3 +-
 gcc/d/dmd/init.h                              |   2 +-
 gcc/d/dmd/initsem.d                           |   3 +-
 gcc/d/dmd/inline.d                            |   2 +-
 gcc/d/dmd/intrange.d                          |   2 +-
 gcc/d/dmd/json.d                              |   3 +-
 gcc/d/dmd/json.h                              |   2 +-
 gcc/d/dmd/lambdacomp.d                        |   2 +-
 gcc/d/dmd/lexer.d                             |  69 +--
 gcc/d/dmd/location.d                          | 158 +++++++
 gcc/d/dmd/mangle.h                            |   2 +-
 gcc/d/dmd/module.h                            |   8 +-
 gcc/d/dmd/mtype.d                             |  51 ++-
 gcc/d/dmd/mtype.h                             |   2 +-
 gcc/d/dmd/mustuse.d                           |   5 +-
 gcc/d/dmd/nogc.d                              |   2 +-
 gcc/d/dmd/nspace.d                            |   3 +-
 gcc/d/dmd/nspace.h                            |   2 +-
 gcc/d/dmd/ob.d                                |   3 +-
 gcc/d/dmd/objc.d                              |   3 +-
 gcc/d/dmd/objc.h                              |   2 +-
 gcc/d/dmd/opover.d                            |   9 +-
 gcc/d/dmd/optimize.d                          |   8 +-
 gcc/d/dmd/parse.d                             |  26 +-
 gcc/d/dmd/printast.d                          |   2 +-
 gcc/d/dmd/root/aav.d                          |   2 +-
 gcc/d/dmd/root/array.d                        |   2 +-
 gcc/d/dmd/root/array.h                        |   2 +-
 gcc/d/dmd/root/bitarray.d                     |   2 +-
 gcc/d/dmd/root/bitarray.h                     |   2 +-
 gcc/d/dmd/root/complex.d                      |   2 +-
 gcc/d/dmd/root/complex_t.h                    |   2 +-
 gcc/d/dmd/root/ctfloat.d                      |   2 +-
 gcc/d/dmd/root/ctfloat.h                      |   2 +-
 gcc/d/dmd/root/dcompat.h                      |   2 +-
 gcc/d/dmd/root/file.d                         |   2 +-
 gcc/d/dmd/root/filename.d                     |   2 +-
 gcc/d/dmd/root/filename.h                     |   2 +-
 gcc/d/dmd/root/hash.d                         |   2 +-
 gcc/d/dmd/root/object.h                       |   2 +-
 gcc/d/dmd/root/optional.d                     |   2 +-
 gcc/d/dmd/root/optional.h                     |   2 +-
 gcc/d/dmd/root/port.d                         |   2 +-
 gcc/d/dmd/root/port.h                         |   2 +-
 gcc/d/dmd/root/region.d                       |   2 +-
 gcc/d/dmd/root/rmem.d                         |   2 +-
 gcc/d/dmd/root/rmem.h                         |   2 +-
 gcc/d/dmd/root/rootobject.d                   |   2 +-
 gcc/d/dmd/root/speller.d                      |   2 +-
 gcc/d/dmd/root/string.d                       |   2 +-
 gcc/d/dmd/root/stringtable.d                  |   2 +-
 gcc/d/dmd/root/utf.d                          |   2 +-
 gcc/d/dmd/safe.d                              |   2 +-
 gcc/d/dmd/sapply.d                            |   2 +-
 gcc/d/dmd/scope.h                             |   2 +-
 gcc/d/dmd/semantic2.d                         |  41 +-
 gcc/d/dmd/semantic3.d                         |   3 +-
 gcc/d/dmd/sideeffect.d                        |   2 +-
 gcc/d/dmd/statement.d                         |   7 +-
 gcc/d/dmd/statement.h                         |   2 +-
 gcc/d/dmd/statement_rewrite_walker.d          |   2 +-
 gcc/d/dmd/statementsem.d                      |   3 +-
 gcc/d/dmd/staticassert.d                      |  18 +-
 gcc/d/dmd/staticassert.h                      |   4 +-
 gcc/d/dmd/staticcond.d                        |   2 +-
 gcc/d/dmd/stmtstate.d                         |   2 +-
 gcc/d/dmd/target.d                            |   4 +-
 gcc/d/dmd/target.h                            |   2 +-
 gcc/d/dmd/template.h                          |   3 +-
 gcc/d/dmd/templateparamsem.d                  |   3 +-
 gcc/d/dmd/tokens.d                            |   8 +-
 gcc/d/dmd/tokens.h                            |   2 +-
 gcc/d/dmd/traits.d                            | 201 +++++----
 gcc/d/dmd/transitivevisitor.d                 |   5 +-
 gcc/d/dmd/typesem.d                           |  25 +-
 gcc/d/dmd/typinf.d                            |   3 +-
 gcc/d/dmd/utils.d                             |   4 +-
 gcc/d/dmd/version.h                           |   2 +-
 gcc/d/dmd/visitor.d                           |   2 +-
 gcc/d/dmd/visitor.h                           |   2 +-
 gcc/testsuite/gdc.dg/simd2a.d                 |  12 +-
 gcc/testsuite/gdc.dg/simd2b.d                 |  12 +-
 gcc/testsuite/gdc.dg/simd2c.d                 |  12 +-
 gcc/testsuite/gdc.dg/simd2d.d                 |  12 +-
 gcc/testsuite/gdc.dg/simd2e.d                 |  12 +-
 gcc/testsuite/gdc.dg/simd2f.d                 |  12 +-
 gcc/testsuite/gdc.dg/simd2g.d                 |  12 +-
 gcc/testsuite/gdc.dg/simd2h.d                 |  12 +-
 gcc/testsuite/gdc.dg/simd2i.d                 |  12 +-
 gcc/testsuite/gdc.dg/simd2j.d                 |  12 +-
 .../compilable/extra-files/build23499.d       |   7 +
 .../gdc.test/compilable/imports/file23499.d   |  19 +
 .../compilable/imports/test23490frop.d        |   7 +
 .../compilable/imports/test23490pop.d         |   7 +
 .../compilable/imports/test23490zoo.d         |  17 +
 .../gdc.test/compilable/isexpalias.d          |   9 +
 .../gdc.test/compilable/issue20618.d          |  10 +
 .../gdc.test/compilable/issue22646.d          |  67 +++
 .../gdc.test/compilable/issue22854.d          |  20 +
 .../gdc.test/compilable/issue22975.d          |  12 +
 .../gdc.test/compilable/issue23391.d          |  31 ++
 .../gdc.test/compilable/issue23567.d          |   9 +
 gcc/testsuite/gdc.test/compilable/noreturn1.d |  11 +
 gcc/testsuite/gdc.test/compilable/noreturn3.d |  10 -
 gcc/testsuite/gdc.test/compilable/test18646.d |  14 +
 gcc/testsuite/gdc.test/compilable/test19585.d |  10 +
 gcc/testsuite/gdc.test/compilable/test22638.d |  15 +
 gcc/testsuite/gdc.test/compilable/test22813.d |   9 +
 gcc/testsuite/gdc.test/compilable/test23481.d |  28 ++
 gcc/testsuite/gdc.test/compilable/test23490.d |   3 +
 gcc/testsuite/gdc.test/compilable/test23497.d |  19 +
 gcc/testsuite/gdc.test/compilable/test23499.d |   6 +
 gcc/testsuite/gdc.test/compilable/test23529.d |   6 +
 gcc/testsuite/gdc.test/compilable/test23532.d |  67 +++
 gcc/testsuite/gdc.test/compilable/test23533.d |  10 +
 gcc/testsuite/gdc.test/compilable/test23586.d |  34 ++
 gcc/testsuite/gdc.test/compilable/test23587.d |  18 +
 gcc/testsuite/gdc.test/compilable/test23589.d |  30 ++
 .../gdc.test/fail_compilation/fail109.d       |  16 +
 .../gdc.test/fail_compilation/fail20618.d     |  16 -
 .../gdc.test/fail_compilation/fail23151.d     |  41 ++
 .../gdc.test/fail_compilation/fail23574.d     |  41 ++
 .../gdc.test/fail_compilation/fail23591.d     |  16 +
 .../gdc.test/fail_compilation/failattr.d      |  17 +-
 .../gdc.test/fail_compilation/ice23564.d      |  25 ++
 .../gdc.test/fail_compilation/ice23569.d      |  19 +
 .../fail_compilation/staticassertargs.d       |   9 +
 .../fail_compilation/staticassertargsfail.d   |  10 +
 .../gdc.test/fail_compilation/test12228.d     |   5 +-
 .../gdc.test/fail_compilation/test21008.d     |   1 -
 .../gdc.test/fail_compilation/test23552.d     |  24 ++
 gcc/testsuite/gdc.test/runnable/issue22854.d  |  27 ++
 gcc/testsuite/gdc.test/runnable/test16098.d   |  14 +
 gcc/testsuite/gdc.test/runnable/test20811.d   |  34 ++
 gcc/testsuite/gdc.test/runnable/test23307.d   |  93 ++++
 gcc/testsuite/gdc.test/runnable/test34.d      |   2 +
 gcc/testsuite/gdc.test/runnable/xtest46.d     |   2 +-
 gcc/testsuite/gdc.test/runnable/xtest46_gc.d  |   2 +-
 libphobos/libdruntime/MERGE                   |   2 +-
 libphobos/libdruntime/core/demangle.d         |   6 +-
 libphobos/libdruntime/core/exception.d        |   2 -
 .../core/internal/gc/impl/conservative/gc.d   |  14 +-
 .../core/internal/gc/impl/manual/gc.d         |   7 +-
 libphobos/libdruntime/core/runtime.d          |  89 +++-
 libphobos/libdruntime/core/stdc/config.d      |  16 +
 .../core/sys/darwin/mach/getsect.d            |   2 +-
 .../libdruntime/core/sys/posix/sys/wait.d     |  12 +-
 .../libdruntime/core/sys/windows/dbghelp.d    |   4 +-
 .../libdruntime/core/sys/windows/stacktrace.d |  60 ++-
 libphobos/libdruntime/core/thread/osthread.d  |  12 +-
 libphobos/libdruntime/core/time.d             |   2 +-
 libphobos/libdruntime/object.d                |  19 +-
 libphobos/libdruntime/rt/deh.d                |   2 +
 libphobos/libdruntime/rt/dmain2.d             |  10 +-
 libphobos/src/MERGE                           |   2 +-
 libphobos/src/std/algorithm/iteration.d       |   5 +-
 libphobos/src/std/conv.d                      |   6 +-
 libphobos/src/std/math/exponential.d          | 399 ++++++++++++++----
 libphobos/src/std/math/operations.d           |   2 +-
 libphobos/src/std/numeric.d                   |   2 +-
 libphobos/src/std/parallelism.d               |  13 +-
 libphobos/src/std/random.d                    |  14 +-
 libphobos/src/std/regex/package.d             |   2 +-
 libphobos/src/std/typecons.d                  |  26 +-
 .../libphobos.exceptions/refcounted.d         |  34 +-
 libphobos/testsuite/libphobos.gc/issue22843.d |  12 +
 .../testsuite/libphobos.shared/finalize.d     |   4 +-
 253 files changed, 2627 insertions(+), 999 deletions(-)
 create mode 100644 gcc/d/dmd/location.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/extra-files/build23499.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/imports/file23499.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/imports/test23490frop.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/imports/test23490pop.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/imports/test23490zoo.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/isexpalias.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/issue20618.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/issue22646.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/issue22854.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/issue22975.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/issue23391.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/issue23567.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test18646.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test19585.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test22638.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test22813.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test23481.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test23490.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test23497.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test23499.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test23529.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test23532.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test23533.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test23586.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test23587.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test23589.d
 delete mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail20618.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23151.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23574.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23591.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/ice23564.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/ice23569.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/staticassertargs.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/staticassertargsfail.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test23552.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/issue22854.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/test16098.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/test20811.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/test23307.d
 create mode 100644 libphobos/testsuite/libphobos.gc/issue22843.d
diff mbox series

Patch

diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in
index bf295a9f183..4feebac982b 100644
--- a/gcc/d/Make-lang.in
+++ b/gcc/d/Make-lang.in
@@ -147,6 +147,7 @@  D_FRONTEND_OBJS = \
 	d/json.o \
 	d/lambdacomp.o \
 	d/lexer.o \
+	d/location.o \
 	d/mtype.o \
 	d/mustuse.o \
 	d/nogc.o \
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index d9b4946470a..449c69296a7 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -303,7 +303,7 @@  d_init_options (unsigned int, cl_decoded_option *decoded_options)
   /* Warnings and deprecations are disabled by default.  */
   global.params.useDeprecated = DIAGNOSTICinform;
   global.params.warnings = DIAGNOSTICoff;
-  global.params.messageStyle = MESSAGESTYLEgnu;
+  global.params.messageStyle = MessageStyle::gnu;
 
   global.params.imppath = d_gc_malloc<Strings> ();
   global.params.fileImppath = d_gc_malloc<Strings> ();
@@ -940,6 +940,9 @@  d_post_options (const char ** fn)
   global.params.showColumns = flag_show_column;
   global.params.printErrorContext = flag_diagnostics_show_caret;
 
+  /* Keep the front-end location type in sync with params.  */
+  Loc::set (global.params.showColumns, global.params.messageStyle);
+
   if (global.params.useInline)
     global.params.dihdr.fullOutput = true;
 
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 5ee6f624836..ac3dd129268 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@ 
-c8ae4adb2eda515b09b326948e3a4aa9f489af45
+09faa4eacd4fb147107e94eeebf56b3a73fdcc05
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/README.md b/gcc/d/dmd/README.md
index 1c7e1dd027d..43eb187c735 100644
--- a/gcc/d/dmd/README.md
+++ b/gcc/d/dmd/README.md
@@ -47,6 +47,7 @@ 
 | File                                                                  | Purpose                                                              |
 |-----------------------------------------------------------------------|----------------------------------------------------------------------|
 | [lexer.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/lexer.d)   | Convert source code into tokens for the D and ImportC parsers        |
+| [location.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/location.d)| Encapsulate file/line/column info for error messages, etc.        |
 | [entity.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/entity.d) | Define "\\&Entity;" escape sequence for strings / character literals |
 | [tokens.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/tokens.d) | Define lexical tokens.                                               |
 | [parse.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/parse.d)   | D parser, converting tokens into an Abstract Syntax Tree (AST)       |
diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION
index 50adf9c67bd..177c41dd63b 100644
--- a/gcc/d/dmd/VERSION
+++ b/gcc/d/dmd/VERSION
@@ -1 +1 @@ 
-v2.101.0-beta.1
+v2.102.0-beta.1
diff --git a/gcc/d/dmd/access.d b/gcc/d/dmd/access.d
index 59c77adf45c..f2d68d53d75 100644
--- a/gcc/d/dmd/access.d
+++ b/gcc/d/dmd/access.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/attribute.html#visibility_attributes, Visibility Attributes)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/access.d, _access.d)
@@ -25,6 +25,7 @@  import dmd.errors;
 import dmd.expression;
 import dmd.func;
 import dmd.globals;
+import dmd.location;
 import dmd.mtype;
 import dmd.tokens;
 
diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d
index 50fdc3b7da7..1306a104fff 100644
--- a/gcc/d/dmd/aggregate.d
+++ b/gcc/d/dmd/aggregate.d
@@ -4,7 +4,7 @@ 
  * Specification: $(LINK2 https://dlang.org/spec/struct.html, Structs, Unions),
  *                $(LINK2 https://dlang.org/spec/class.html, Class).
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/aggregate.d, _aggregate.d)
@@ -34,6 +34,7 @@  import dmd.func;
 import dmd.globals;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.tokens;
 import dmd.typesem : defaultInit;
@@ -206,7 +207,7 @@  extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
         //printf("AggregateDeclaration::determineSize() %s, sizeok = %d\n", toChars(), sizeok);
 
         // The previous instance size finalizing had:
-        if (type.ty == Terror)
+        if (type.ty == Terror || errors)
             return false;   // failed already
         if (sizeok == Sizeok.done)
             return true;    // succeeded
diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h
index d4432b513c4..9f9098f7f2b 100644
--- a/gcc/d/dmd/aggregate.h
+++ b/gcc/d/dmd/aggregate.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
@@ -41,13 +41,6 @@  enum class Baseok : uint8_t
     semanticdone  // all base classes semantic done
 };
 
-enum class ThreeState : uint8_t
-{
-    none,         // value not yet computed
-    no,           // value is false
-    yes,          // value is true
-};
-
 FuncDeclaration *search_toString(StructDeclaration *sd);
 
 enum class ClassKind : uint8_t
diff --git a/gcc/d/dmd/aliasthis.d b/gcc/d/dmd/aliasthis.d
index 2771071baa7..ef839fae536 100644
--- a/gcc/d/dmd/aliasthis.d
+++ b/gcc/d/dmd/aliasthis.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/class.html#alias-this, Alias This)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/aliasthis.d, _aliasthis.d)
@@ -21,6 +21,7 @@  import dmd.expression;
 import dmd.expressionsem;
 import dmd.globals;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.opover;
 import dmd.tokens;
@@ -94,7 +95,7 @@  Expression resolveAliasThis(Scope* sc, Expression e, bool gag = false, bool find
             Type tthis = (e.op == EXP.type ? e.type : null);
             const flags = DotExpFlag.noAliasThis | (gag ? DotExpFlag.gag : 0);
             uint olderrors = gag ? global.startGagging() : 0;
-            e = dotExp(e.type, sc, e, ad.aliasthis.ident, flags);
+            e = dotExp(ad.type, sc, e, ad.aliasthis.ident, flags);
             if (!e || findOnly)
                 return gag && global.endGagging(olderrors) ? null : e;
 
diff --git a/gcc/d/dmd/aliasthis.h b/gcc/d/dmd/aliasthis.h
index c63d717a7bd..389cff40054 100644
--- a/gcc/d/dmd/aliasthis.h
+++ b/gcc/d/dmd/aliasthis.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 2009-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 2009-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/apply.d b/gcc/d/dmd/apply.d
index 3b73771ef22..f5855c4758a 100644
--- a/gcc/d/dmd/apply.d
+++ b/gcc/d/dmd/apply.d
@@ -1,7 +1,7 @@ 
 /**
  * A depth-first visitor for expressions.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/apply.d, _apply.d)
diff --git a/gcc/d/dmd/arrayop.d b/gcc/d/dmd/arrayop.d
index f07a6f44d2b..da2f8000fc1 100644
--- a/gcc/d/dmd/arrayop.d
+++ b/gcc/d/dmd/arrayop.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/arrays.html#array-operations, Array Operations)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/arrayop.d, _arrayop.d)
@@ -26,6 +26,7 @@  import dmd.globals;
 import dmd.hdrgen;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.common.outbuffer;
 import dmd.statement;
diff --git a/gcc/d/dmd/arraytypes.d b/gcc/d/dmd/arraytypes.d
index 29b3a3ddc33..34ffa6eb8fd 100644
--- a/gcc/d/dmd/arraytypes.d
+++ b/gcc/d/dmd/arraytypes.d
@@ -1,7 +1,7 @@ 
 /**
  * Provide aliases for arrays of certain declarations or statements.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/arraytypes.d, _arraytypes.d)
diff --git a/gcc/d/dmd/arraytypes.h b/gcc/d/dmd/arraytypes.h
index ca2051cf5f4..05126a53d7e 100644
--- a/gcc/d/dmd/arraytypes.h
+++ b/gcc/d/dmd/arraytypes.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 2006-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 2006-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/ast_node.d b/gcc/d/dmd/ast_node.d
index 843cc023735..c0dd186628a 100644
--- a/gcc/d/dmd/ast_node.d
+++ b/gcc/d/dmd/ast_node.d
@@ -1,7 +1,7 @@ 
 /**
  * Defines the base class for all nodes which are part of the AST.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/ast_node.d, _ast_node.d)
diff --git a/gcc/d/dmd/ast_node.h b/gcc/d/dmd/ast_node.h
index 0e04e38f728..6154c6d1b3a 100644
--- a/gcc/d/dmd/ast_node.h
+++ b/gcc/d/dmd/ast_node.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/astenums.d b/gcc/d/dmd/astenums.d
index 091e96a82c1..6e882082bed 100644
--- a/gcc/d/dmd/astenums.d
+++ b/gcc/d/dmd/astenums.d
@@ -1,7 +1,7 @@ 
 /**
  * Defines enums common to dmd and dmd as parse library.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/astenums.d, _astenums.d)
  * Documentation:  https://dlang.org/phobos/dmd_astenums.html
diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d
index 55d69b555f8..712099ed333 100644
--- a/gcc/d/dmd/attrib.d
+++ b/gcc/d/dmd/attrib.d
@@ -14,7 +14,7 @@ 
  * - Protection (`private`, `public`)
  * - Deprecated declarations (`@deprecated`)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/attrib.d, _attrib.d)
@@ -40,6 +40,7 @@  import dmd.globals;
 import dmd.hdrgen : visibilityToBuffer;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.objc; // for objc.addSymbols
 import dmd.common.outbuffer;
diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h
index b153229ccaa..96c46e8f718 100644
--- a/gcc/d/dmd/attrib.h
+++ b/gcc/d/dmd/attrib.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/blockexit.d b/gcc/d/dmd/blockexit.d
index 64568763a87..6369b5ab04b 100644
--- a/gcc/d/dmd/blockexit.d
+++ b/gcc/d/dmd/blockexit.d
@@ -1,7 +1,7 @@ 
 /**
  * Find out in what ways control flow can exit a statement block.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/blockexit.d, _blockexit.d)
@@ -23,6 +23,7 @@  import dmd.func;
 import dmd.globals;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.statement;
 import dmd.tokens;
diff --git a/gcc/d/dmd/builtin.d b/gcc/d/dmd/builtin.d
index 06db97bf8f4..27ba1e03454 100644
--- a/gcc/d/dmd/builtin.d
+++ b/gcc/d/dmd/builtin.d
@@ -3,7 +3,7 @@ 
  *
  * Currently includes functions from `std.math`, `core.math` and `core.bitop`.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/builtin.d, _builtin.d)
@@ -16,7 +16,7 @@  module dmd.builtin;
 import dmd.arraytypes;
 import dmd.expression;
 import dmd.func;
-import dmd.globals;
+import dmd.location;
 
 /**********************************
  * Determine if function is a builtin one that we can
diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d
index cb9289fd773..7c18040eb02 100644
--- a/gcc/d/dmd/canthrow.d
+++ b/gcc/d/dmd/canthrow.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/function.html#nothrow-functions, Nothrow Functions)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/canthrow.d, _canthrow.d)
diff --git a/gcc/d/dmd/chkformat.d b/gcc/d/dmd/chkformat.d
index 8204961fd29..21a1b5e6def 100644
--- a/gcc/d/dmd/chkformat.d
+++ b/gcc/d/dmd/chkformat.d
@@ -1,7 +1,7 @@ 
 /**
  * Check the arguments to `printf` and `scanf` against the `format` string.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/chkformat.d, _chkformat.d)
@@ -19,6 +19,7 @@  import dmd.errors;
 import dmd.expression;
 import dmd.globals;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.target;
 
diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d
index c030d353c18..ef5464d75e0 100644
--- a/gcc/d/dmd/clone.d
+++ b/gcc/d/dmd/clone.d
@@ -2,7 +2,7 @@ 
  * Builds struct member functions if needed and not defined by the user.
  * Includes `opEquals`, `opAssign`, post blit, copy constructor and destructor.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/clone.d, _clone.d)
@@ -31,6 +31,7 @@  import dmd.globals;
 import dmd.id;
 import dmd.identifier;
 import dmd.init;
+import dmd.location;
 import dmd.mtype;
 import dmd.opover;
 import dmd.semantic2;
diff --git a/gcc/d/dmd/common/bitfields.d b/gcc/d/dmd/common/bitfields.d
index bba61ad3715..b9fcb0995c9 100644
--- a/gcc/d/dmd/common/bitfields.d
+++ b/gcc/d/dmd/common/bitfields.d
@@ -1,7 +1,7 @@ 
 /**
  * A library bitfields utility
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:   Dennis Korpel
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/common/bitfields.d, common/bitfields.d)
diff --git a/gcc/d/dmd/common/file.d b/gcc/d/dmd/common/file.d
index 89e702703e6..ae13c41d310 100644
--- a/gcc/d/dmd/common/file.d
+++ b/gcc/d/dmd/common/file.d
@@ -4,7 +4,7 @@ 
  * Functions and objects dedicated to file I/O and management. TODO: Move here artifacts
  * from places such as root/ so both the frontend and the backend have access to them.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:   Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/common/file.d, common/_file.d)
diff --git a/gcc/d/dmd/common/outbuffer.d b/gcc/d/dmd/common/outbuffer.d
index 9d544a400fe..276928a6bd8 100644
--- a/gcc/d/dmd/common/outbuffer.d
+++ b/gcc/d/dmd/common/outbuffer.d
@@ -1,7 +1,7 @@ 
 /**
  * An expandable buffer in which you can write text or binary data.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:   Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/outbuffer.d, root/_outbuffer.d)
diff --git a/gcc/d/dmd/common/outbuffer.h b/gcc/d/dmd/common/outbuffer.h
index fed25c0d030..b672842e74d 100644
--- a/gcc/d/dmd/common/outbuffer.h
+++ b/gcc/d/dmd/common/outbuffer.h
@@ -1,5 +1,5 @@ 
 
-/* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+/* Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/common/string.d b/gcc/d/dmd/common/string.d
index 48bf9bb5b55..1111cec2cf1 100644
--- a/gcc/d/dmd/common/string.d
+++ b/gcc/d/dmd/common/string.d
@@ -1,7 +1,7 @@ 
 /**
  * Common string functions including filename manipulation.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:   Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/common/string.d, common/_string.d)
diff --git a/gcc/d/dmd/compiler.d b/gcc/d/dmd/compiler.d
index dd26d40ff39..68ec1d3848d 100644
--- a/gcc/d/dmd/compiler.d
+++ b/gcc/d/dmd/compiler.d
@@ -1,7 +1,7 @@ 
 /**
  * Describes a back-end compiler and implements compiler-specific actions.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/compiler.d, _compiler.d)
diff --git a/gcc/d/dmd/compiler.h b/gcc/d/dmd/compiler.h
index e8b7704b043..c7cbce3bd7f 100644
--- a/gcc/d/dmd/compiler.h
+++ b/gcc/d/dmd/compiler.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d
index c1e1e4d8d24..c0c4cf1ce82 100644
--- a/gcc/d/dmd/cond.d
+++ b/gcc/d/dmd/cond.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/version.html, Conditional Compilation)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/cond.d, _cond.d)
@@ -26,6 +26,7 @@  import dmd.expression;
 import dmd.expressionsem;
 import dmd.globals;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.typesem;
 import dmd.common.outbuffer;
@@ -80,6 +81,11 @@  extern (C++) abstract class Condition : ASTNode
         return null;
     }
 
+    inout(StaticIfCondition) isStaticIfCondition() inout
+    {
+        return null;
+    }
+
     override void accept(Visitor v)
     {
         v.visit(this);
@@ -218,12 +224,12 @@  extern (C++) final class StaticForeach : RootObject
     {
         if (aggrfe)
         {
-            return new ForeachStatement(loc, aggrfe.op, parameters, aggrfe.aggr.syntaxCopy(), s, loc);
+            return new ForeachStatement(loc, aggrfe.op, parameters, aggrfe.aggr, s, loc);
         }
         else
         {
             assert(rangefe && parameters.length == 1);
-            return new ForeachRangeStatement(loc, rangefe.op, (*parameters)[0], rangefe.lwr.syntaxCopy(), rangefe.upr.syntaxCopy(), s, loc);
+            return new ForeachRangeStatement(loc, rangefe.op, (*parameters)[0], rangefe.lwr, rangefe.upr, s, loc);
         }
     }
 
@@ -953,6 +959,11 @@  extern (C++) final class StaticIfCondition : Condition
         v.visit(this);
     }
 
+    override inout(StaticIfCondition) isStaticIfCondition() inout
+    {
+        return this;
+    }
+
     override const(char)* toChars() const
     {
         return exp ? exp.toChars() : "static if".ptr;
diff --git a/gcc/d/dmd/cond.h b/gcc/d/dmd/cond.h
index b33f288f9df..422a715bdba 100644
--- a/gcc/d/dmd/cond.h
+++ b/gcc/d/dmd/cond.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/constfold.d b/gcc/d/dmd/constfold.d
index ef684ba745f..79bbd5dead5 100644
--- a/gcc/d/dmd/constfold.d
+++ b/gcc/d/dmd/constfold.d
@@ -5,7 +5,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/float.html#fp_const_folding, Floating Point Constant Folding)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/constfold.d, _constfold.d)
@@ -25,6 +25,7 @@  import dmd.dstruct;
 import dmd.errors;
 import dmd.expression;
 import dmd.globals;
+import dmd.location;
 import dmd.mtype;
 import dmd.root.complex;
 import dmd.root.ctfloat;
@@ -1249,7 +1250,14 @@  UnionExp Slice(Type type, Expression e1, Expression lwr, Expression upr)
         }
     }
 
-    if (e1.op == EXP.string_ && lwr.op == EXP.int64 && upr.op == EXP.int64)
+    if (!lwr)
+    {
+        if (e1.op == EXP.string_)
+            emplaceExp(&ue, e1);
+        else
+            cantExp(ue);
+    }
+    else if (e1.op == EXP.string_ && lwr.op == EXP.int64 && upr.op == EXP.int64)
     {
         StringExp es1 = e1.isStringExp();
         const uinteger_t ilwr = lwr.toInteger();
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index d4416abe097..a6bc42b1014 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: C11
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/cparse.d, _cparse.d)
@@ -20,6 +20,7 @@  import dmd.globals;
 import dmd.id;
 import dmd.identifier;
 import dmd.lexer;
+import dmd.location;
 import dmd.parse;
 import dmd.errors;
 import dmd.root.array;
diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d
index fbe9f0181d4..d3effa99ddd 100644
--- a/gcc/d/dmd/cppmangle.d
+++ b/gcc/d/dmd/cppmangle.d
@@ -4,7 +4,7 @@ 
  * This is the POSIX side of the implementation.
  * It exports two functions to C++, `toCppMangleItanium` and `cppTypeInfoMangleItanium`.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors: Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/cppmangle.d, _cppmangle.d)
@@ -38,6 +38,7 @@  import dmd.func;
 import dmd.globals;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.nspace;
 import dmd.root.array;
diff --git a/gcc/d/dmd/ctfe.h b/gcc/d/dmd/ctfe.h
index ab022ff505e..1071edf7c93 100644
--- a/gcc/d/dmd/ctfe.h
+++ b/gcc/d/dmd/ctfe.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/ctfeexpr.d b/gcc/d/dmd/ctfeexpr.d
index 1dc1f7d1784..c902149e2b5 100644
--- a/gcc/d/dmd/ctfeexpr.d
+++ b/gcc/d/dmd/ctfeexpr.d
@@ -1,7 +1,7 @@ 
 /**
  * CTFE for expressions involving pointers, slices, array concatenation etc.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/ctfeexpr.d, _ctfeexpr.d)
@@ -27,6 +27,7 @@  import dmd.errors;
 import dmd.expression;
 import dmd.func;
 import dmd.globals;
+import dmd.location;
 import dmd.mtype;
 import dmd.root.complex;
 import dmd.root.ctfloat;
diff --git a/gcc/d/dmd/ctorflow.d b/gcc/d/dmd/ctorflow.d
index c04793dfb18..a3953af6ce8 100644
--- a/gcc/d/dmd/ctorflow.d
+++ b/gcc/d/dmd/ctorflow.d
@@ -1,7 +1,7 @@ 
 /**
  * Manage flow analysis for constructors.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/ctorflow.d, _ctorflow.d)
@@ -14,7 +14,7 @@  module dmd.ctorflow;
 import core.stdc.stdio;
 
 import dmd.root.rmem;
-import dmd.globals : Loc;
+import dmd.location;
 
 enum CSX : ushort
 {
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index 02bf6cf3495..b305360a3ab 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -1,7 +1,7 @@ 
 /**
  * Semantic analysis for cast-expressions.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dcast.d, _dcast.d)
@@ -30,6 +30,7 @@  import dmd.expressionsem;
 import dmd.func;
 import dmd.globals;
 import dmd.hdrgen;
+import dmd.location;
 import dmd.impcnvtab;
 import dmd.id;
 import dmd.importc;
@@ -66,10 +67,14 @@  Expression implicitCastTo(Expression e, Scope* sc, Type t)
 {
     Expression visit(Expression e)
     {
-        //printf("Expression.implicitCastTo(%s of type %s) => %s\n", e.toChars(), e.type.toChars(), t.toChars());
+        // printf("Expression.implicitCastTo(%s of type %s) => %s\n", e.toChars(), e.type.toChars(), t.toChars());
 
         if (const match = (sc && sc.flags & SCOPE.Cfile) ? e.cimplicitConvTo(t) : e.implicitConvTo(t))
         {
+            if (match == MATCH.convert && e.type.isTypeNoreturn())
+            {
+                return specialNoreturnCast(e, t);
+            }
             if (match == MATCH.constant && (e.type.constConv(t) || !e.isLvalue() && e.type.equivalent(t)))
             {
                 /* Do not emit CastExp for const conversions and
@@ -1526,6 +1531,10 @@  Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
         {
             return e;
         }
+        if (e.type.isTypeNoreturn())
+        {
+            return specialNoreturnCast(e, t);
+        }
         if (auto ve = e.isVarExp())
         {
             VarDeclaration v = ve.var.isVarDeclaration();
@@ -2539,7 +2548,12 @@  Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
 
         // Handle the cast from Tarray to Tsarray with CT-known slicing
 
-        TypeSArray tsa = toStaticArrayType(e).isTypeSArray();
+        TypeSArray tsa;
+        {
+            Type t = toStaticArrayType(e);
+            tsa = t ? t.isTypeSArray() : null;
+        }
+
         if (tsa && tsa.size(e.loc) == tb.size(e.loc))
         {
             /* Match if the sarray sizes are equal:
@@ -3858,3 +3872,21 @@  IntRange getIntRange(Expression e)
         case EXP.negate             : return visitNeg(e.isNegExp());
     }
 }
+/**
+ * A helper function to "cast" from expressions of type noreturn to
+ * any other type - noreturn is implicitly convertible to any other type.
+ * However, the dmd backend does not like a naive cast from a noreturn expression
+ * (particularly an `assert(0)`) so this function generates:
+ *
+ * `(assert(0), value)` instead of `cast(to)(assert(0))`.
+ *
+ * `value` is currently `to.init` however it cannot be read so could be made simpler.
+ * Params:
+ *   toBeCasted = Expression of type noreturn to cast
+ *   to = Type to cast the expression to.
+ * Returns: A CommaExp, upon any failure ErrorExp will be returned.
+ */
+Expression specialNoreturnCast(Expression toBeCasted, Type to)
+{
+    return Expression.combine(toBeCasted, to.defaultInitLiteral(toBeCasted.loc));
+}
diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d
index fc49b210480..1fdd0730fcf 100644
--- a/gcc/d/dmd/dclass.d
+++ b/gcc/d/dmd/dclass.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/class.html, Classes)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dclass.d, _dclass.d)
@@ -30,6 +30,7 @@  import dmd.func;
 import dmd.globals;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.objc;
 import dmd.root.rmem;
@@ -468,7 +469,7 @@  extern (C++) class ClassDeclaration : AggregateDeclaration
     {
         //printf("%s.ClassDeclaration.search('%s', flags=x%x)\n", toChars(), ident.toChars(), flags);
         //if (_scope) printf("%s baseok = %d\n", toChars(), baseok);
-        if (_scope && baseok < Baseok.done)
+        if (_scope && baseok < Baseok.semanticdone)
         {
             if (!inuse)
             {
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index 3d0752c1d8b..51737cef2c6 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -2,7 +2,7 @@ 
  * Miscellaneous declarations, including typedef, alias, variable declarations including the
  * implicit this declaration, type tuples, ClassInfo, ModuleInfo and various TypeInfos.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/declaration.d, _declaration.d)
@@ -35,6 +35,7 @@  import dmd.identifier;
 import dmd.init;
 import dmd.initsem;
 import dmd.intrange;
+import dmd.location;
 import dmd.mtype;
 import dmd.common.outbuffer;
 import dmd.root.rootobject;
@@ -81,6 +82,9 @@  bool checkFrameAccess(Loc loc, Scope* sc, AggregateDeclaration ad, size_t iStart
 /***********************************************
  * Mark variable v 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.
+ * Returns:
+ *    true if it's an initialization of v
  */
 bool modifyFieldVar(Loc loc, Scope* sc, VarDeclaration var, Expression e1)
 {
@@ -93,7 +97,7 @@  bool modifyFieldVar(Loc loc, Scope* sc, VarDeclaration var, Expression e1)
             fd = s.isFuncDeclaration();
         if (fd &&
             ((fd.isCtorDeclaration() && var.isField()) ||
-             (fd.isStaticCtorDeclaration() && !var.isField())) &&
+             ((fd.isStaticCtorDeclaration() || fd.isCrtCtor) && !var.isField())) &&
             fd.toParentDecl() == var.toParent2() &&
             (!e1 || e1.op == EXP.this_))
         {
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index 2668b6ec05e..5d5c4234b74 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/delegatize.d b/gcc/d/dmd/delegatize.d
index 461f44131c3..3f982b3faf7 100644
--- a/gcc/d/dmd/delegatize.d
+++ b/gcc/d/dmd/delegatize.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/function.html#lazy-params, Lazy Parameters)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/delegatize.d, _delegatize.d)
@@ -25,6 +25,7 @@  import dmd.func;
 import dmd.globals;
 import dmd.init;
 import dmd.initsem;
+import dmd.location;
 import dmd.mtype;
 import dmd.statement;
 import dmd.tokens;
diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d
index 926186bc4a8..221250b27e0 100644
--- a/gcc/d/dmd/denum.d
+++ b/gcc/d/dmd/denum.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/enum.html, Enums)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/denum.d, _denum.d)
@@ -28,6 +28,7 @@  import dmd.globals;
 import dmd.id;
 import dmd.identifier;
 import dmd.init;
+import dmd.location;
 import dmd.mtype;
 import dmd.tokens;
 import dmd.typesem;
diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d
index 1104005b1ac..b653d9bbf89 100644
--- a/gcc/d/dmd/dimport.d
+++ b/gcc/d/dmd/dimport.d
@@ -1,7 +1,7 @@ 
 /**
  * A `Dsymbol` representing a renamed import.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dimport.d, _dimport.d)
@@ -22,6 +22,7 @@  import dmd.errors;
 import dmd.expression;
 import dmd.globals;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.visitor;
 
diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d
index e504cb4879f..7920df79991 100644
--- a/gcc/d/dmd/dinterpret.d
+++ b/gcc/d/dmd/dinterpret.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: ($LINK2 https://dlang.org/spec/function.html#interpretation, Compile Time Function Execution (CTFE))
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dinterpret.d, _dinterpret.d)
@@ -39,6 +39,7 @@  import dmd.id;
 import dmd.identifier;
 import dmd.init;
 import dmd.initsem;
+import dmd.location;
 import dmd.mtype;
 import dmd.printast;
 import dmd.root.rmem;
@@ -165,7 +166,7 @@  public Expression ctfeInterpretForPragmaMsg(Expression e)
     return e;
 }
 
-public extern (C++) Expression getValue(VarDeclaration vd)
+public Expression getValue(VarDeclaration vd)
 {
     return ctfeGlobals.stack.getValue(vd);
 }
@@ -280,25 +281,25 @@  private:
     Expression localThis;       // value of 'this', or NULL if none
 
 public:
-    extern (C++) size_t stackPointer()
+    size_t stackPointer()
     {
         return values.length;
     }
 
     // The current value of 'this', or NULL if none
-    extern (C++) Expression getThis()
+    Expression getThis()
     {
         return localThis;
     }
 
     // Largest number of stack positions we've used
-    extern (C++) size_t maxStackUsage()
+    size_t maxStackUsage()
     {
         return maxStackPointer;
     }
 
     // Start a new stack frame, using the provided 'this'.
-    extern (C++) void startFrame(Expression thisexp)
+    void startFrame(Expression thisexp)
     {
         frames.push(cast(void*)cast(size_t)framepointer);
         savedThis.push(localThis);
@@ -306,7 +307,7 @@  public:
         localThis = thisexp;
     }
 
-    extern (C++) void endFrame()
+    void endFrame()
     {
         size_t oldframe = cast(size_t)frames[frames.length - 1];
         localThis = savedThis[savedThis.length - 1];
@@ -316,14 +317,14 @@  public:
         savedThis.setDim(savedThis.length - 1);
     }
 
-    extern (C++) bool isInCurrentFrame(VarDeclaration v)
+    bool isInCurrentFrame(VarDeclaration v)
     {
         if (v.isDataseg() && !v.isCTFE())
             return false; // It's a global
         return v.ctfeAdrOnStack >= framepointer;
     }
 
-    extern (C++) Expression getValue(VarDeclaration v)
+    Expression getValue(VarDeclaration v)
     {
         //printf("getValue() %s\n", v.toChars());
         if ((v.isDataseg() || v.storage_class & STC.manifest) && !v.isCTFE())
@@ -335,7 +336,7 @@  public:
         return values[v.ctfeAdrOnStack];
     }
 
-    extern (C++) void setValue(VarDeclaration v, Expression e)
+    void setValue(VarDeclaration v, Expression e)
     {
         //printf("setValue() %s : %s\n", v.toChars(), e.toChars());
         assert(!v.isDataseg() || v.isCTFE());
@@ -343,7 +344,7 @@  public:
         values[v.ctfeAdrOnStack] = e;
     }
 
-    extern (C++) void push(VarDeclaration v)
+    void push(VarDeclaration v)
     {
         //printf("push() %s\n", v.toChars());
         assert(!v.isDataseg() || v.isCTFE());
@@ -359,7 +360,7 @@  public:
         values.push(null);
     }
 
-    extern (C++) void pop(VarDeclaration v)
+    void pop(VarDeclaration v)
     {
         assert(!v.isDataseg() || v.isCTFE());
         assert(!v.isReference());
@@ -373,7 +374,7 @@  public:
         }
     }
 
-    extern (C++) void popAll(size_t stackpointer)
+    void popAll(size_t stackpointer)
     {
         if (stackPointer() > maxStackPointer)
             maxStackPointer = stackPointer();
@@ -388,7 +389,7 @@  public:
         savedId.setDim(stackpointer);
     }
 
-    extern (C++) void saveGlobalConstant(VarDeclaration v, Expression e)
+    void saveGlobalConstant(VarDeclaration v, Expression e)
     {
         assert(v._init && (v.isConst() || v.isImmutable() || v.storage_class & STC.manifest) && !v.isCTFE());
         v.ctfeAdrOnStack = cast(uint)globalValues.length;
@@ -1529,7 +1530,7 @@  public:
         }
         // Little sanity check to make sure it's really a Throwable
         ClassReferenceExp boss = oldest.thrown;
-        const next = 4;                         // index of Throwable.next
+        const next = 5;                         // index of Throwable.next
         assert((*boss.value.elements)[next].type.ty == Tclass); // Throwable.next
         ClassReferenceExp collateral = newest.thrown;
         if (collateral.originalClass().isErrorException() && !boss.originalClass().isErrorException())
@@ -1849,10 +1850,27 @@  public:
         {
             printf("%s StringExp::interpret() %s\n", e.loc.toChars(), e.toChars());
         }
-        /* Attempts to modify string literals are prevented
-         * in BinExp::interpretAssignCommon.
-         */
-        result = e;
+        if (e.ownedByCtfe >= OwnedBy.ctfe) // We've already interpreted the string
+        {
+            result = e;
+            return;
+        }
+
+        if (e.type.ty != Tsarray ||
+            (cast(TypeNext)e.type).next.mod & (MODFlags.const_ | MODFlags.immutable_))
+        {
+            // If it's immutable, we don't need to dup it. Attempts to modify
+            // string literals are prevented in BinExp::interpretAssignCommon.
+            result = e;
+        }
+        else
+        {
+            // https://issues.dlang.org/show_bug.cgi?id=20811
+            // Create a copy of mutable string literals, so that any change in
+            // value via an index or slice will not survive CTFE.
+            *pue = copyLiteral(e);
+            result = pue.exp();
+        }
     }
 
     override void visit(FuncExp e)
@@ -4287,12 +4305,12 @@  public:
                 bool needsPostblit;
                 bool needsDtor;
 
-                extern (C++) Expression assignTo(ArrayLiteralExp ae)
+                Expression assignTo(ArrayLiteralExp ae)
                 {
                     return assignTo(ae, 0, ae.elements.length);
                 }
 
-                extern (C++) Expression assignTo(ArrayLiteralExp ae, size_t lwr, size_t upr)
+                Expression assignTo(ArrayLiteralExp ae, size_t lwr, size_t upr)
                 {
                     Expressions* w = ae.elements;
                     assert(ae.type.ty == Tsarray || ae.type.ty == Tarray);
@@ -6178,7 +6196,7 @@  public:
     {
         debug (LOG)
         {
-            printf("%s ThrowExpression::interpret()\n", e.loc.toChars());
+            printf("%s ThrowExpression::interpret()\n", te.loc.toChars());
         }
         interpretThrow(te.e1, te.loc);
     }
diff --git a/gcc/d/dmd/dmacro.d b/gcc/d/dmd/dmacro.d
index 358712b884c..6fc23e99e86 100644
--- a/gcc/d/dmd/dmacro.d
+++ b/gcc/d/dmd/dmacro.d
@@ -1,7 +1,7 @@ 
 /**
  * Text macro processor for Ddoc.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dmacro.d, _dmacro.d)
diff --git a/gcc/d/dmd/dmangle.d b/gcc/d/dmd/dmangle.d
index 6ecaa5235f2..867d3cacb2f 100644
--- a/gcc/d/dmd/dmangle.d
+++ b/gcc/d/dmd/dmangle.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/abi.html#name_mangling, Name Mangling)
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors: Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dmangle.d, _dmangle.d)
diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d
index 616080566d8..e1234e5bde9 100644
--- a/gcc/d/dmd/dmodule.d
+++ b/gcc/d/dmd/dmodule.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/module.html, Modules)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dmodule.d, _dmodule.d)
@@ -35,6 +35,7 @@  import dmd.file_manager;
 import dmd.globals;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.parse;
 import dmd.cparse;
 import dmd.root.array;
@@ -359,7 +360,8 @@  extern (C++) final class Module : Package
     Package pkg;                // if isPackageFile is true, the Package that contains this package.d
     Strings contentImportedFiles; // array of files whose content was imported
     int needmoduleinfo;
-    int selfimports;            // 0: don't know, 1: does not, 2: does
+    private ThreeState selfimports;
+    private ThreeState rootimports;
     Dsymbol[void*] tagSymTab;   /// ImportC: tag symbols that conflict with other symbols used as the index
 
     private OutBuffer defines;  // collect all the #define lines here
@@ -371,48 +373,46 @@  extern (C++) final class Module : Package
     bool selfImports()
     {
         //printf("Module::selfImports() %s\n", toChars());
-        if (selfimports == 0)
+        if (selfimports == ThreeState.none)
         {
             foreach (Module m; amodules)
-                m.insearch = 0;
-            selfimports = imports(this) + 1;
+                m.insearch = false;
+            selfimports = imports(this) ? ThreeState.yes : ThreeState.no;
             foreach (Module m; amodules)
-                m.insearch = 0;
+                m.insearch = false;
         }
-        return selfimports == 2;
+        return selfimports == ThreeState.yes;
     }
 
-    int rootimports;            // 0: don't know, 1: does not, 2: does
-
     /*************************************
      * Return true if module imports root module.
      */
     bool rootImports()
     {
         //printf("Module::rootImports() %s\n", toChars());
-        if (rootimports == 0)
+        if (rootimports == ThreeState.none)
         {
             foreach (Module m; amodules)
-                m.insearch = 0;
-            rootimports = 1;
+                m.insearch = false;
+            rootimports = ThreeState.no;
             foreach (Module m; amodules)
             {
                 if (m.isRoot() && imports(m))
                 {
-                    rootimports = 2;
+                    rootimports = ThreeState.yes;
                     break;
                 }
             }
             foreach (Module m; amodules)
-                m.insearch = 0;
+                m.insearch = false;
         }
-        return rootimports == 2;
+        return rootimports == ThreeState.yes;
     }
 
-    int insearch;
-    Identifier searchCacheIdent;
-    Dsymbol searchCacheSymbol;  // cached value of search
-    int searchCacheFlags;       // cached flags
+    private Identifier searchCacheIdent;
+    private Dsymbol searchCacheSymbol;  // cached value of search
+    private int searchCacheFlags;       // cached flags
+    private bool insearch;
 
     /**
      * A root module is one that will be compiled all the way to
@@ -1041,9 +1041,9 @@  extern (C++) final class Module : Package
 
         uint errors = global.errors;
 
-        insearch = 1;
+        insearch = true;
         Dsymbol s = ScopeDsymbol.search(loc, ident, flags);
-        insearch = 0;
+        insearch = false;
 
         if (errors == global.errors)
         {
@@ -1214,7 +1214,7 @@  extern (C++) final class Module : Package
                 return true;
             if (!mi.insearch)
             {
-                mi.insearch = 1;
+                mi.insearch = true;
                 int r = mi.imports(m);
                 if (r)
                     return r;
@@ -1284,6 +1284,59 @@  extern (C++) final class Module : Package
             _escapetable = new Escape();
         return _escapetable;
     }
+
+    /****************************
+     * A Singleton that loads core.atomic
+     * Returns:
+     *  Module of core.atomic, null if couldn't find it
+     */
+    extern (D) static Module loadCoreAtomic()
+    {
+        __gshared Module core_atomic;
+        return loadModuleFromLibrary(core_atomic, Id.core, Id.atomic);
+    }
+
+    /****************************
+     * A Singleton that loads std.math
+     * Returns:
+     *  Module of std.math, null if couldn't find it
+     */
+    extern (D) static Module loadStdMath()
+    {
+        __gshared Module std_math;
+        return loadModuleFromLibrary(std_math, Id.std, Id.math);
+    }
+
+    /**********************************
+     * Load a Module from the library.
+     * Params:
+     *  mod = cached return value of this call
+     *  pkgid = package id
+     *  modid = module id
+     * Returns:
+     *  Module loaded, null if cannot load it
+     */
+    private static Module loadModuleFromLibrary(ref Module mod, Identifier pkgid, Identifier modid)
+    {
+        if (mod)
+            return mod;
+
+        auto ids = new Identifier[1];
+        ids[0] = pkgid;
+        auto imp = new Import(Loc.initial, ids[], modid, null, true);
+        // Module.load will call fatal() if there's no module available.
+        // Gag the error here, pushing the error handling to the caller.
+        const errors = global.startGagging();
+        imp.load(null);
+        if (imp.mod)
+        {
+            imp.mod.importAll(null);
+            imp.mod.dsymbolSemantic(null);
+        }
+        global.endGagging(errors);
+        mod = imp.mod;
+        return mod;
+    }
 }
 
 /***********************************************************
diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d
index c04409c4d3f..732a7370a77 100644
--- a/gcc/d/dmd/doc.d
+++ b/gcc/d/dmd/doc.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/ddoc.html, Documentation Generator)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/doc.d, _doc.d)
@@ -41,6 +41,7 @@  import dmd.hdrgen;
 import dmd.id;
 import dmd.identifier;
 import dmd.lexer;
+import dmd.location;
 import dmd.mtype;
 import dmd.root.array;
 import dmd.root.file;
@@ -5181,7 +5182,8 @@  private void highlightCode2(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t of
 {
     uint errorsave = global.startGagging();
 
-    scope Lexer lex = new Lexer(null, cast(char*)buf[].ptr, 0, buf.length - 1, 0, 1);
+    scope Lexer lex = new Lexer(null, cast(char*)buf[].ptr, 0, buf.length - 1, 0, 1,
+        global.vendor, global.versionNumber());
     OutBuffer res;
     const(char)* lastp = cast(char*)buf[].ptr;
     //printf("highlightCode2('%.*s')\n", cast(int)(buf.length - 1), buf[].ptr);
diff --git a/gcc/d/dmd/doc.h b/gcc/d/dmd/doc.h
index 8dc2d9f659c..d16806beda2 100644
--- a/gcc/d/dmd/doc.h
+++ b/gcc/d/dmd/doc.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d
index 362e7f27993..8f196266c79 100644
--- a/gcc/d/dmd/dscope.d
+++ b/gcc/d/dmd/dscope.d
@@ -3,7 +3,7 @@ 
  *
  * Not to be confused with the `scope` storage class.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dscope.d, _dscope.d)
@@ -33,6 +33,7 @@  import dmd.func;
 import dmd.globals;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.common.outbuffer;
 import dmd.root.rmem;
 import dmd.root.speller;
diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d
index 2115fda2f55..6ab93d4c39c 100644
--- a/gcc/d/dmd/dstruct.d
+++ b/gcc/d/dmd/dstruct.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/struct.html, Structs, Unions)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dstruct.d, _dstruct.d)
@@ -29,6 +29,7 @@  import dmd.func;
 import dmd.globals;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.opover;
 import dmd.target;
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index 2cf5500bf5a..3611e09c286 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -1,7 +1,7 @@ 
 /**
  * The base class for a D symbol, which can be a module, variable, function, enum, etc.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dsymbol.d, _dsymbol.d)
@@ -42,6 +42,7 @@  import dmd.id;
 import dmd.identifier;
 import dmd.init;
 import dmd.lexer;
+import dmd.location;
 import dmd.mtype;
 import dmd.nspace;
 import dmd.opover;
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index 3e9b634307f..88110e1f5d2 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
@@ -87,6 +87,13 @@  struct Ungag
     ~Ungag() { global.gag = oldgag; }
 };
 
+enum class ThreeState : uint8_t
+{
+    none,         // value not yet computed
+    no,           // value is false
+    yes,          // value is true
+};
+
 void dsymbolSemantic(Dsymbol *dsym, Scope *sc);
 void semantic2(Dsymbol *dsym, Scope *sc);
 void semantic3(Dsymbol *dsym, Scope* sc);
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index b842dc850d1..49e1c597879 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -2,7 +2,7 @@ 
  * Does the semantic 1 pass on the AST, which looks at symbol declarations but not initializers
  * or function bodies.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dsymbolsem.d, _dsymbolsem.d)
@@ -51,6 +51,7 @@  import dmd.init;
 import dmd.initsem;
 import dmd.intrange;
 import dmd.hdrgen;
+import dmd.location;
 import dmd.mtype;
 import dmd.mustuse;
 import dmd.nogc;
@@ -1594,6 +1595,7 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
                 if (pd.ident == Id.printf || pd.ident == Id.scanf)
                 {
                     s.setPragmaPrintf(pd.ident == Id.printf);
+                    s.dsymbolSemantic(sc2);
                     continue;
                 }
 
@@ -2310,6 +2312,7 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
             auto inneruda = em.userAttribDecl.userAttribDecl;
             em.userAttribDecl.setScope(sc);
             em.userAttribDecl.userAttribDecl = inneruda;
+            em.userAttribDecl.dsymbolSemantic(sc);
         }
 
         // The first enum member is special
@@ -2464,8 +2467,11 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
             e = e.ctfeInterpret();
             if (e.toInteger())
             {
+                auto mt = em.ed.memtype;
+                if (!mt)
+                    mt = eprev.type;
                 em.error("initialization with `%s.%s+1` causes overflow for type `%s`",
-                    emprev.ed.toChars(), emprev.toChars(), em.ed.memtype.toChars());
+                    emprev.ed.toChars(), emprev.toChars(), mt.toChars());
                 return errorReturn();
             }
 
@@ -5165,6 +5171,7 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
                 }
 
                 // Copy vtbl[] from base class
+                assert(cldec.vtbl.length == 0);
                 cldec.vtbl.setDim(cldec.baseClass.vtbl.length);
                 memcpy(cldec.vtbl.tdata(), cldec.baseClass.vtbl.tdata(), (void*).sizeof * cldec.vtbl.length);
 
@@ -5205,7 +5212,6 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
                             cldec.baseClass.toChars(),
                             cldec.baseClass.toParentLocal().toChars());
                     }
-                    cldec.enclosing = null;
                 }
                 if (cldec.vthis2)
                 {
@@ -5378,10 +5384,11 @@  private extern(C++) final class DsymbolSemanticVisitor : Visitor
             cldec.error("already exists at %s. Perhaps in another function with the same name?", cd.loc.toChars());
         }
 
-        if (global.errors != errors)
+        if (global.errors != errors || (cldec.baseClass && cldec.baseClass.errors))
         {
-            // The type is no good.
-            cldec.type = Type.terror;
+            // The type is no good, but we should keep the
+            // the type so that we have more accurate error messages
+            // See: https://issues.dlang.org/show_bug.cgi?id=23552
             cldec.errors = true;
             if (cldec.deferred)
                 cldec.deferred.errors = true;
@@ -7073,33 +7080,13 @@  bool determineFields(AggregateDeclaration ad)
 /// Do an atomic operation (currently tailored to [shared] static ctors|dtors) needs
 private CallExp doAtomicOp (string op, Identifier var, Expression arg)
 {
-    __gshared Import imp = null;
-    __gshared Identifier[1] id;
-
     assert(op == "-=" || op == "+=");
 
-    const loc = Loc.initial;
+    Module mod = Module.loadCoreAtomic();
+    if (!mod)
+        return null;    // core.atomic couldn't be loaded
 
-    // Below code is similar to `loadStdMath` (used for `^^` operator)
-    if (!imp)
-    {
-        id[0] = Id.core;
-        auto s = new Import(Loc.initial, id[], Id.atomic, null, true);
-        // Module.load will call fatal() if there's no std.math available.
-        // Gag the error here, pushing the error handling to the caller.
-        uint errors = global.startGagging();
-        s.load(null);
-        if (s.mod)
-        {
-            s.mod.importAll(null);
-            s.mod.dsymbolSemantic(null);
-        }
-        global.endGagging(errors);
-        imp = s;
-    }
-    // Module couldn't be loaded
-    if (imp.mod is null)
-        return null;
+    const loc = Loc.initial;
 
     Objects* tiargs = new Objects(1);
     (*tiargs)[0] = new StringExp(loc, op);
@@ -7108,7 +7095,7 @@  private CallExp doAtomicOp (string op, Identifier var, Expression arg)
     (*args)[0] = new IdentifierExp(loc, var);
     (*args)[1] = arg;
 
-    auto sc = new ScopeExp(loc, imp.mod);
+    auto sc = new ScopeExp(loc, mod);
     auto dti = new DotTemplateInstanceExp(
         loc, sc, Id.atomicOp, tiargs);
 
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index 6095dcc9a1e..32799aa04e3 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -28,7 +28,7 @@ 
  *   arguments, and uses it if found.
  * - Otherwise, the rest of semantic is run on the `TemplateInstance`.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dtemplate.d, _dtemplate.d)
@@ -64,6 +64,7 @@  import dmd.identifier;
 import dmd.impcnvtab;
 import dmd.init;
 import dmd.initsem;
+import dmd.location;
 import dmd.mtype;
 import dmd.opover;
 import dmd.root.array;
@@ -567,7 +568,6 @@  extern (C++) final class TemplateDeclaration : ScopeDsymbol
     bool isTrivialAlias;    /// matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
     bool deprecated_;       /// this template declaration is deprecated
     Visibility visibility;
-    int inuse;              /// for recursive expansion detection
 
     // threaded list of previous instantiation attempts on stack
     TemplatePrevious* previous;
@@ -1117,9 +1117,7 @@  extern (C++) final class TemplateDeclaration : ScopeDsymbol
                     printf("\tparameter[%d] is %s : %s\n", i, tp.ident.toChars(), ttp.specType ? ttp.specType.toChars() : "");
             }
 
-            inuse++;
             m2 = tp.matchArg(ti.loc, paramscope, ti.tiargs, i, parameters, dedtypes, &sparam);
-            inuse--;
             //printf("\tm2 = %d\n", m2);
             if (m2 == MATCH.nomatch)
             {
@@ -1783,9 +1781,7 @@  extern (C++) final class TemplateDeclaration : ScopeDsymbol
                             }
                             else
                             {
-                                inuse++;
                                 oded = tparam.defaultArg(instLoc, paramscope);
-                                inuse--;
                                 if (oded)
                                     (*dedargs)[i] = declareParameter(paramscope, tparam, oded);
                             }
@@ -2166,9 +2162,7 @@  extern (C++) final class TemplateDeclaration : ScopeDsymbol
             }
             else
             {
-                inuse++;
                 oded = tparam.defaultArg(instLoc, paramscope);
-                inuse--;
                 if (!oded)
                 {
                     // if tuple parameter and
@@ -2813,11 +2807,6 @@  void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
     int applyTemplate(TemplateDeclaration td)
     {
         //printf("applyTemplate()\n");
-        if (td.inuse)
-        {
-            td.error(loc, "recursive template expansion");
-            return 1;
-        }
         if (td == td_best)   // skip duplicates
             return 0;
 
@@ -3613,8 +3602,29 @@  MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                 }
 
                 // Found the corresponding parameter tp
+                /+
+                    https://issues.dlang.org/show_bug.cgi?id=23578
+                    To pattern match:
+                    static if (is(S!int == S!av, alias av))
+
+                    We eventually need to deduce `int` (Tint32 [0]) and `av` (Tident).
+                    Previously this would not get pattern matched at all, but now we check if the
+                    template parameter `av` came from.
+
+                    This note has been left to serve as a hint for further explorers into
+                    how IsExp matching works.
+                +/
+                if (auto ta = tp.isTemplateAliasParameter())
+                {
+                    (*dedtypes)[i] = t;
+                    goto Lexact;
+                }
+                // (23578) - ensure previous behaviour for non-alias template params
                 if (!tp.isTemplateTypeParameter())
+                {
                     goto Lnomatch;
+                }
+
                 Type at = cast(Type)(*dedtypes)[i];
                 Type tt;
                 if (ubyte wx = wm ? deduceWildHelper(t, &tt, tparam) : 0)
@@ -4100,6 +4110,7 @@  MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                         }
                         goto Lnomatch;
                     }
+
                     TemplateParameter tpx = (*parameters)[i];
                     if (!tpx.matchArg(sc, tempdecl, i, parameters, dedtypes, null))
                         goto Lnomatch;
@@ -4110,7 +4121,7 @@  MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
             L2:
                 for (size_t i = 0; 1; i++)
                 {
-                    //printf("\ttest: tempinst.tiargs[%d]\n", i);
+                    //printf("\ttest: tempinst.tiargs[%zu]\n", i);
                     RootObject o1 = null;
                     if (i < t.tempinst.tiargs.length)
                         o1 = (*t.tempinst.tiargs)[i];
@@ -4121,7 +4132,7 @@  MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
                     }
                     else if (i >= tp.tempinst.tiargs.length)
                         break;
-
+                    //printf("\ttest: o1 = %s\n", o1.toChars());
                     if (i >= tp.tempinst.tiargs.length)
                     {
                         size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0);
@@ -4136,7 +4147,7 @@  MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
 
                     RootObject o2 = (*tp.tempinst.tiargs)[i];
                     Type t2 = isType(o2);
-
+                    //printf("\ttest: o2 = %s\n", o2.toChars());
                     size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1)
                         ? templateParameterLookup(t2, parameters) : IDX_NOTFOUND;
                     if (j != IDX_NOTFOUND && j == parameters.length - 1 &&
@@ -5571,15 +5582,25 @@  extern (C++) final class TemplateValueParameter : TemplateParameter
         if (e)
         {
             e = e.syntaxCopy();
-            uint olderrs = global.errors;
             if ((e = e.expressionSemantic(sc)) is null)
                 return null;
+            if (auto te = e.isTemplateExp())
+            {
+                assert(sc && sc.tinst);
+                if (te.td == sc.tinst.tempdecl)
+                {
+                    // defaultValue is a reference to its template declaration
+                    // i.e: `template T(int arg = T)`
+                    // Raise error now before calling resolveProperties otherwise we'll
+                    // start looping on the expansion of the template instance.
+                    sc.tinst.tempdecl.error("recursive template expansion");
+                    return ErrorExp.get();
+                }
+            }
             if ((e = resolveProperties(sc, e)) is null)
                 return null;
             e = e.resolveLoc(instLoc, sc); // use the instantiated loc
             e = e.optimize(WANTvalue);
-            if (global.errors != olderrs)
-                e = ErrorExp.get();
         }
         return e;
     }
@@ -6910,11 +6931,6 @@  extern (C++) class TemplateInstance : ScopeDsymbol
                 auto td = s.isTemplateDeclaration();
                 if (!td)
                     return 0;
-                if (td.inuse)
-                {
-                    td.error(loc, "recursive template expansion");
-                    return 1;
-                }
                 if (td == td_best)   // skip duplicates
                     return 0;
 
@@ -7133,11 +7149,6 @@  extern (C++) class TemplateInstance : ScopeDsymbol
                 auto td = s.isTemplateDeclaration();
                 if (!td)
                     return 0;
-                if (td.inuse)
-                {
-                    td.error(loc, "recursive template expansion");
-                    return 1;
-                }
 
                 /* If any of the overloaded template declarations need inference,
                  * then return true
diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d
index 432e88da307..30ca3d1f8c6 100644
--- a/gcc/d/dmd/dtoh.d
+++ b/gcc/d/dmd/dtoh.d
@@ -2,7 +2,7 @@ 
  * This module contains the implementation of the C++ header generation available through
  * the command line switch -Hc.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dtohd, _dtoh.d)
@@ -24,6 +24,7 @@  import dmd.errors;
 import dmd.globals;
 import dmd.hdrgen;
 import dmd.identifier;
+import dmd.location;
 import dmd.root.filename;
 import dmd.visitor;
 import dmd.tokens;
diff --git a/gcc/d/dmd/dversion.d b/gcc/d/dmd/dversion.d
index 94753bb8a82..259f85c5128 100644
--- a/gcc/d/dmd/dversion.d
+++ b/gcc/d/dmd/dversion.d
@@ -4,7 +4,7 @@ 
  * Specification: $(LINK2 https://dlang.org/spec/version.html#version-specification, Version Specification),
  *                $(LINK2 https://dlang.org/spec/version.html#debug_specification, Debug Specification).
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dversion.d, _dversion.d)
@@ -22,6 +22,7 @@  import dmd.dsymbol;
 import dmd.dsymbolsem;
 import dmd.globals;
 import dmd.identifier;
+import dmd.location;
 import dmd.common.outbuffer;
 import dmd.visitor;
 
diff --git a/gcc/d/dmd/entity.d b/gcc/d/dmd/entity.d
index 2b499c14fcc..c31883f11d9 100644
--- a/gcc/d/dmd/entity.d
+++ b/gcc/d/dmd/entity.d
@@ -3,7 +3,7 @@ 
  *
  * Specification $(LINK2 https://dlang.org/spec/entity.html, Named Character Entities)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/entity.d, _entity.d)
diff --git a/gcc/d/dmd/enum.h b/gcc/d/dmd/enum.h
index 723cebc7e0a..be12c65e6d6 100644
--- a/gcc/d/dmd/enum.h
+++ b/gcc/d/dmd/enum.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/errors.d b/gcc/d/dmd/errors.d
index 62e86a1163c..03c78a5acdc 100644
--- a/gcc/d/dmd/errors.d
+++ b/gcc/d/dmd/errors.d
@@ -1,7 +1,7 @@ 
 /**
  * Functions for raising errors.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/errors.d, _errors.d)
@@ -13,6 +13,7 @@  module dmd.errors;
 
 import core.stdc.stdarg;
 import dmd.globals;
+import dmd.location;
 
 nothrow:
 
diff --git a/gcc/d/dmd/errors.h b/gcc/d/dmd/errors.h
index 000242ce49f..cc72811b112 100644
--- a/gcc/d/dmd/errors.h
+++ b/gcc/d/dmd/errors.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index 24a428b6ce6..7bc018e1e32 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -1,7 +1,7 @@ 
 /**
  * Most of the logic to implement scoped pointers and scoped references is here.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/escape.d, _escape.d)
@@ -29,6 +29,7 @@  import dmd.globals;
 import dmd.id;
 import dmd.identifier;
 import dmd.init;
+import dmd.location;
 import dmd.mtype;
 import dmd.printast;
 import dmd.root.rootobject;
@@ -1788,7 +1789,7 @@  void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re
                         if (tf.isreturn)
                             stc |= STC.return_;
                         if (tf.isreturnscope)
-                            stc |= STC.returnScope;
+                            stc |= STC.returnScope | STC.scope_;
                         auto ad = fd.isThis();
                         if (ad.isClassDeclaration() || tf.isScopeQual)
                             stc |= STC.scope_;
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 4f14d66d39f..e0f258c5a57 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: ($LINK2 https://dlang.org/spec/expression.html, Expressions)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/expression.d, _expression.d)
@@ -50,6 +50,7 @@  import dmd.id;
 import dmd.identifier;
 import dmd.init;
 import dmd.inline;
+import dmd.location;
 import dmd.mtype;
 import dmd.nspace;
 import dmd.objc;
@@ -1291,12 +1292,16 @@  extern (C++) abstract class Expression : ASTNode
             return false; // ...or manifest constants
 
         // accessing empty structs is pure
+        // https://issues.dlang.org/show_bug.cgi?id=18694
+        // https://issues.dlang.org/show_bug.cgi?id=21464
+        // https://issues.dlang.org/show_bug.cgi?id=23589
         if (v.type.ty == Tstruct)
         {
             StructDeclaration sd = (cast(TypeStruct)v.type).sym;
             if (sd.members) // not opaque
             {
-                sd.determineSize(v.loc);
+                if (sd.semanticRun >= PASS.semanticdone)
+                    sd.determineSize(v.loc);
                 if (sd.hasNoFields)
                     return false;
             }
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index 79bc5288577..7202960af63 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index 60b51cbc44e..63236cdb882 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: ($LINK2 https://dlang.org/spec/expression.html, Expressions)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/expressionsem.d, _expressionsem.d)
@@ -55,6 +55,7 @@  import dmd.init;
 import dmd.initsem;
 import dmd.inline;
 import dmd.intrange;
+import dmd.location;
 import dmd.mtype;
 import dmd.mustuse;
 import dmd.nspace;
@@ -512,7 +513,7 @@  private Expression resolveUFCS(Scope* sc, CallExp ce)
     {
         Identifier ident = die.ident;
 
-        Expression ex = die.semanticX(sc);
+        Expression ex = die.dotIdSemanticPropX(sc);
         if (ex != die)
         {
             ce.e1 = ex;
@@ -561,7 +562,7 @@  private Expression resolveUFCS(Scope* sc, CallExp ce)
         }
         else
         {
-            if (Expression ey = die.semanticY(sc, 1))
+            if (Expression ey = die.dotIdSemanticProp(sc, 1))
             {
                 if (ey.op == EXP.error)
                     return ey;
@@ -632,7 +633,7 @@  private Expression resolveUFCS(Scope* sc, CallExp ce)
     }
     else if (auto dti = ce.e1.isDotTemplateInstanceExp())
     {
-        if (Expression ey = dti.semanticY(sc, 1))
+        if (Expression ey = dti.dotTemplateSemanticProp(sc, 1))
         {
             ce.e1 = ey;
             return null;
@@ -2536,28 +2537,6 @@  Package resolveIsPackage(Dsymbol sym)
     return pkg;
 }
 
-private Module loadStdMath()
-{
-    __gshared Import impStdMath = null;
-    __gshared Identifier[1] stdID;
-    if (!impStdMath)
-    {
-        stdID[0] = Id.std;
-        auto s = new Import(Loc.initial, stdID[], Id.math, null, false);
-        // Module.load will call fatal() if there's no std.math available.
-        // Gag the error here, pushing the error handling to the caller.
-        uint errors = global.startGagging();
-        s.load(null);
-        if (s.mod)
-        {
-            s.mod.importAll(null);
-            s.mod.dsymbolSemantic(null);
-        }
-        global.endGagging(errors);
-        impStdMath = s;
-    }
-    return impStdMath.mod;
-}
 
 private extern (C++) final class ExpressionSemanticVisitor : Visitor
 {
@@ -3585,6 +3564,8 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
         if (auto tc = tb.isTypeClass())
         {
             auto cd = tc.sym;
+            if (cd.errors)
+                return setError();
             cd.size(exp.loc);
             if (cd.sizeok != Sizeok.done)
                 return setError();
@@ -3630,21 +3611,25 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 {
                     if (!cdthis)
                     {
-                        if (!sc.hasThis)
+                        void noReferenceToOuterClass()
                         {
-                            string msg = "cannot construct " ~
-                            (cd.isAnonymous ? "anonymous nested class" : "nested class `%s`") ~
-                            " because no implicit `this` reference to outer class" ~
-                            (cdn.isAnonymous ? "" : " `%s`") ~ " is available\0";
-
-                            exp.error(msg.ptr, cd.toChars, cdn.toChars);
+                            if (cd.isAnonymous)
+                                exp.error("cannot construct anonymous nested class because no implicit `this` reference to outer class is available");
+                            else
+                                exp.error("cannot construct nested class `%s` because no implicit `this` reference to outer class `%s` is available",
+                                    cd.toChars(), cdn.toChars());
                             return setError();
                         }
 
+                        if (!sc.hasThis)
+                            return noReferenceToOuterClass();
+
                         // Supply an implicit 'this' and try again
                         exp.thisexp = new ThisExp(exp.loc);
                         for (Dsymbol sp = sc.parent; 1; sp = sp.toParentLocal())
                         {
+                            if (!sp)
+                                return noReferenceToOuterClass();
                             ClassDeclaration cdp = sp.isClassDeclaration();
                             if (!cdp)
                                 continue;
@@ -4671,8 +4656,8 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 else if (exp.arguments.length == 1)
                 {
                     e = (*exp.arguments)[0];
-                    if (!e.type.isTypeNoreturn())
-                        e = e.implicitCastTo(sc, t1);
+                    e = e.implicitCastTo(sc, t1);
+                    e = new CastExp(exp.loc, e, t1);
                 }
                 else
                 {
@@ -5851,8 +5836,7 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
             dedtypes.zero();
 
             MATCH m = deduceType(e.targ, sc, e.tspec, e.parameters, &dedtypes, null, 0, e.tok == TOK.equal);
-            //printf("targ: %s\n", targ.toChars());
-            //printf("tspec: %s\n", tspec.toChars());
+
             if (m == MATCH.nomatch || (m != MATCH.exact && e.tok == TOK.equal))
             {
                 return no();
@@ -6557,7 +6541,7 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
             }
         }
 
-        Expression e = exp.semanticY(sc, 1);
+        Expression e = exp.dotIdSemanticProp(sc, 1);
 
         if (e && isDotOpDispatch(e))
         {
@@ -6786,7 +6770,7 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
             return;
         }
         // Indicate we need to resolve by UFCS.
-        Expression e = exp.semanticY(sc, 1);
+        Expression e = exp.dotTemplateSemanticProp(sc, 1);
         if (!e)
             e = resolveUFCSProperties(sc, exp);
         if (e is exp)
@@ -7528,11 +7512,6 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
             return;
         }
 
-        if (exp.e1.type.isTypeNoreturn() && (!exp.to || !exp.to.isTypeNoreturn()))
-        {
-            result = exp.e1;
-            return;
-        }
         if (exp.to && !exp.to.isTypeSArray() && !exp.to.isTypeFunction())
             exp.e1 = exp.e1.arrayFuncConv(sc);
 
@@ -8069,22 +8048,12 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
                 Expression el = new ArrayLengthExp(exp.loc, exp.e1);
                 el = el.expressionSemantic(sc);
                 el = el.optimize(WANTvalue);
-                if (el.op == EXP.int64 && t1b.ty == Tsarray)
+                if (el.op == EXP.int64)
                 {
                     // Array length is known at compile-time. Upper is in bounds if it fits length.
                     dinteger_t length = el.toInteger();
                     auto bounds = IntRange(SignExtendedNumber(0), SignExtendedNumber(length));
                     exp.upperIsInBounds = bounds.contains(uprRange);
-                    if (exp.lwr.op == EXP.int64 && exp.upr.op == EXP.int64 && exp.lwr.toInteger() > exp.upr.toInteger())
-                    {
-                        exp.error("in slice `%s[%llu .. %llu]`, lower bound is greater than upper bound", exp.e1.toChars, exp.lwr.toInteger(), exp.upr.toInteger());
-                        return setError();
-                    }
-                    if (exp.upr.op == EXP.int64 && exp.upr.toInteger() > length)
-                    {
-                        exp.error("in slice `%s[%llu .. %llu]`, upper bound is greater than array length `%llu`", exp.e1.toChars, exp.lwr.toInteger(), exp.upr.toInteger(), length);
-                        return setError();
-                    }
                 }
                 else if (exp.upr.op == EXP.int64 && exp.upr.toInteger() == 0)
                 {
@@ -8884,7 +8853,7 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
              */
             if (auto dti = e1x.isDotTemplateInstanceExp())
             {
-                Expression e = dti.semanticY(sc, 1);
+                Expression e = dti.dotTemplateSemanticProp(sc, 1);
                 if (!e)
                 {
                     return setResult(resolveUFCSProperties(sc, e1x, exp.e2));
@@ -8899,7 +8868,7 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
             }
             else if (auto die = e1x.isDotIdExp())
             {
-                Expression e = die.semanticY(sc, 1);
+                Expression e = die.dotIdSemanticProp(sc, 1);
                 if (e && isDotOpDispatch(e))
                 {
                     /* https://issues.dlang.org/show_bug.cgi?id=19687
@@ -11275,7 +11244,7 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
             return;
         }
 
-        Module mmath = loadStdMath();
+        Module mmath = Module.loadStdMath();
         if (!mmath)
         {
             e.error("`%s` requires `std.math` for `^^` operators", e.toChars());
@@ -11823,8 +11792,8 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
             return;
         }
 
-        if (t1.isTypeVector())
-            exp.type = t1;
+        if (auto tv = t1.isTypeVector())
+            exp.type = tv.toBooleanVector();
 
         result = exp;
         return;
@@ -12105,8 +12074,8 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
             return;
         }
 
-        if (t1.isTypeVector())
-            exp.type = t1;
+        if (auto tv = t1.isTypeVector())
+            exp.type = tv.toBooleanVector();
 
         result = exp;
     }
@@ -12244,10 +12213,12 @@  private extern (C++) final class ExpressionSemanticVisitor : Visitor
         if (t1.ty == Tnoreturn)
         {
             exp.type = t2;
+            exp.e1 = specialNoreturnCast(exp.e1, exp.type);
         }
         else if (t2.ty == Tnoreturn)
         {
             exp.type = t1;
+            exp.e2 = specialNoreturnCast(exp.e2, exp.type);
         }
         // If either operand is void the result is void, we have to cast both
         // the expression to void so that we explicitly discard the expression
@@ -12541,7 +12512,7 @@  extern (C++) Expression expressionSemantic(Expression e, Scope* sc)
     return v.result;
 }
 
-Expression semanticX(DotIdExp exp, Scope* sc)
+private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc)
 {
     //printf("DotIdExp::semanticX(this = %p, '%s')\n", this, toChars());
     if (Expression ex = unaSemantic(exp, sc))
@@ -12649,7 +12620,7 @@  Expression semanticX(DotIdExp exp, Scope* sc)
  * Returns:
  *      resolved expression, null if error
  */
-Expression semanticY(DotIdExp exp, Scope* sc, int flag)
+Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, int flag)
 {
     //printf("DotIdExp::semanticY(this = %p, '%s')\n", exp, exp.toChars());
 
@@ -12681,7 +12652,7 @@  Expression semanticY(DotIdExp exp, Scope* sc, int flag)
     }
 
     {
-        Expression e = semanticX(exp, sc);
+        Expression e = dotIdSemanticPropX(exp, sc);
         if (e != exp)
             return e;
     }
@@ -12983,7 +12954,7 @@  Expression semanticY(DotIdExp exp, Scope* sc, int flag)
 
 // Resolve e1.ident!tiargs without seeing UFCS.
 // If flag == 1, stop "not a property" error and return NULL.
-Expression semanticY(DotTemplateInstanceExp exp, Scope* sc, int flag)
+Expression dotTemplateSemanticProp(DotTemplateInstanceExp exp, Scope* sc, int flag)
 {
     static if (LOGSEMANTIC)
     {
@@ -13007,7 +12978,7 @@  Expression semanticY(DotTemplateInstanceExp exp, Scope* sc, int flag)
 
     auto die = new DotIdExp(exp.loc, e1, exp.ti.name);
 
-    Expression e = die.semanticX(sc);
+    Expression e = die.dotIdSemanticPropX(sc);
     if (e == die)
     {
         exp.e1 = die.e1; // take back
@@ -13020,7 +12991,7 @@  Expression semanticY(DotTemplateInstanceExp exp, Scope* sc, int flag)
             if (flag)
                 return null;
         }
-        e = die.semanticY(sc, flag);
+        e = die.dotIdSemanticProp(sc, flag);
         if (flag)
         {
             if (!e ||
@@ -13169,6 +13140,7 @@  Lerr:
 bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)
 {
     if (global.params.noSharedAccess != FeatureState.enabled ||
+        !sc ||
         sc.intypeof ||
         sc.flags & SCOPE.ctfe)
     {
diff --git a/gcc/d/dmd/file_manager.d b/gcc/d/dmd/file_manager.d
index a941115acc4..a0e5d0519c8 100644
--- a/gcc/d/dmd/file_manager.d
+++ b/gcc/d/dmd/file_manager.d
@@ -1,7 +1,7 @@ 
 /**
  * Read a file from disk and store it in memory.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/file_manager.d, _file_manager.d)
  * Documentation:  https://dlang.org/phobos/dmd_file_manager.html
@@ -16,6 +16,7 @@  import dmd.root.filename : FileName, isDirSeparator;
 import dmd.root.string : toDString;
 import dmd.globals;
 import dmd.identifier;
+import dmd.location;
 
 enum package_d  = "package." ~ mars_ext;
 enum package_di = "package." ~ hdr_ext;
@@ -123,7 +124,7 @@  nothrow:
     const(char)[] lookForSourceFile(const char[] filename, const char*[] path)
     {
         //printf("lookForSourceFile(`%.*s`)\n", cast(int)filename.length, filename.ptr);
-        /* Search along path[] for .di file, then .d file, then .i file, then .c file.
+        /* Search along path[] for .di file, then .d file.
         */
         // see if we should check for the module locally.
         bool checkLocal = packageExists(filename);
@@ -140,16 +141,6 @@  nothrow:
             return sd;
         scope(exit) FileName.free(sd.ptr);
 
-        const si = FileName.forceExt(filename, i_ext);
-        if (checkLocal && FileName.exists(si) == 1)
-            return si;
-        scope(exit) FileName.free(si.ptr);
-
-        const sc = FileName.forceExt(filename, c_ext);
-        if (checkLocal && FileName.exists(sc) == 1)
-            return sc;
-        scope(exit) FileName.free(sc.ptr);
-
         if (checkLocal)
         {
             auto cached = packageStatus.lookup(filename);
@@ -198,18 +189,6 @@  nothrow:
             }
             FileName.free(n.ptr);
 
-            n = FileName.combine(p, si);
-            if (FileName.exists(n) == 1) {
-                return n;
-            }
-            FileName.free(n.ptr);
-
-            n = FileName.combine(p, sc);
-            if (FileName.exists(n) == 1) {
-                return n;
-            }
-            FileName.free(n.ptr);
-
             const b = FileName.removeExt(filename);
             n = FileName.combine(p, b);
             FileName.free(b.ptr);
@@ -235,6 +214,34 @@  nothrow:
                 FileName.free(n2.ptr);
             }
         }
+
+        /* ImportC: No D modules found, now search along path[] for .i file, then .c file.
+         */
+        const si = FileName.forceExt(filename, i_ext);
+        if (FileName.exists(si) == 1)
+            return si;
+        scope(exit) FileName.free(si.ptr);
+
+        const sc = FileName.forceExt(filename, c_ext);
+        if (FileName.exists(sc) == 1)
+            return sc;
+        scope(exit) FileName.free(sc.ptr);
+        foreach (entry; path)
+        {
+            const p = entry.toDString();
+
+            const(char)[] n = FileName.combine(p, si);
+            if (FileName.exists(n) == 1) {
+                return n;
+            }
+            FileName.free(n.ptr);
+
+            n = FileName.combine(p, sc);
+            if (FileName.exists(n) == 1) {
+                return n;
+            }
+            FileName.free(n.ptr);
+        }
         return null;
     }
 
diff --git a/gcc/d/dmd/foreachvar.d b/gcc/d/dmd/foreachvar.d
index 63281b5760c..7c4df0deca8 100644
--- a/gcc/d/dmd/foreachvar.d
+++ b/gcc/d/dmd/foreachvar.d
@@ -1,7 +1,7 @@ 
 /**
  * Utility to visit every variable in an expression.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/foreachvar.d, _foreachvar.d)
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index 93e36343721..3a85679626c 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -8,7 +8,7 @@ 
  * - `invariant`
  * - `unittest`
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/func.d, _func.d)
@@ -43,6 +43,7 @@  import dmd.hdrgen;
 import dmd.id;
 import dmd.identifier;
 import dmd.init;
+import dmd.location;
 import dmd.mtype;
 import dmd.objc;
 import dmd.root.aav;
@@ -2924,89 +2925,100 @@  Expression addInvariant(AggregateDeclaration ad, VarDeclaration vthis)
  */
 extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg, Scope* sc = null)
 {
-    Dsymbol next;
-    for (auto d = fstart; d; d = next)
+    Dsymbols visited;
+
+    int overloadApplyRecurse(Dsymbol fstart, scope int delegate(Dsymbol) dg, Scope* sc)
     {
-        import dmd.access : checkSymbolAccess;
-        if (auto od = d.isOverDeclaration())
+        // Detect cyclic calls.
+        if (visited.contains(fstart))
+            return 0;
+        visited.push(fstart);
+
+        Dsymbol next;
+        for (auto d = fstart; d; d = next)
         {
-            /* The scope is needed here to check whether a function in
-               an overload set was added by means of a private alias (or a
-               selective import). If the scope where the alias is created
-               is imported somewhere, the overload set is visible, but the private
-               alias is not.
-            */
-            if (sc)
+            import dmd.access : checkSymbolAccess;
+            if (auto od = d.isOverDeclaration())
             {
-                if (checkSymbolAccess(sc, od))
+                /* The scope is needed here to check whether a function in
+                   an overload set was added by means of a private alias (or a
+                   selective import). If the scope where the alias is created
+                   is imported somewhere, the overload set is visible, but the private
+                   alias is not.
+                */
+                if (sc)
                 {
-                    if (int r = overloadApply(od.aliassym, dg, sc))
+                    if (checkSymbolAccess(sc, od))
+                    {
+                        if (int r = overloadApplyRecurse(od.aliassym, dg, sc))
+                            return r;
+                    }
+                }
+                else if (int r = overloadApplyRecurse(od.aliassym, dg, sc))
+                    return r;
+                next = od.overnext;
+            }
+            else if (auto fa = d.isFuncAliasDeclaration())
+            {
+                if (fa.hasOverloads)
+                {
+                    if (int r = overloadApplyRecurse(fa.funcalias, dg, sc))
                         return r;
                 }
+                else if (auto fd = fa.toAliasFunc())
+                {
+                    if (int r = dg(fd))
+                        return r;
+                }
+                else
+                {
+                    d.error("is aliased to a function");
+                    break;
+                }
+                next = fa.overnext;
             }
-            else if (int r = overloadApply(od.aliassym, dg, sc))
-                return r;
-            next = od.overnext;
-        }
-        else if (auto fa = d.isFuncAliasDeclaration())
-        {
-            if (fa.hasOverloads)
+            else if (auto ad = d.isAliasDeclaration())
             {
-                if (int r = overloadApply(fa.funcalias, dg, sc))
+                if (sc)
+                {
+                    if (checkSymbolAccess(sc, ad))
+                        next = ad.toAlias();
+                }
+                else
+                   next = ad.toAlias();
+                if (next == ad)
+                    break;
+                if (next == fstart)
+                    break;
+            }
+            else if (auto td = d.isTemplateDeclaration())
+            {
+                if (int r = dg(td))
                     return r;
+                next = td.overnext;
             }
-            else if (auto fd = fa.toAliasFunc())
+            else if (auto fd = d.isFuncDeclaration())
             {
                 if (int r = dg(fd))
                     return r;
+                next = fd.overnext;
+            }
+            else if (auto os = d.isOverloadSet())
+            {
+                foreach (ds; os.a)
+                    if (int r = dg(ds))
+                        return r;
             }
             else
             {
                 d.error("is aliased to a function");
                 break;
+                // BUG: should print error message?
             }
-            next = fa.overnext;
-        }
-        else if (auto ad = d.isAliasDeclaration())
-        {
-            if (sc)
-            {
-                if (checkSymbolAccess(sc, ad))
-                    next = ad.toAlias();
-            }
-            else
-               next = ad.toAlias();
-            if (next == ad)
-                break;
-            if (next == fstart)
-                break;
-        }
-        else if (auto td = d.isTemplateDeclaration())
-        {
-            if (int r = dg(td))
-                return r;
-            next = td.overnext;
-        }
-        else if (auto fd = d.isFuncDeclaration())
-        {
-            if (int r = dg(fd))
-                return r;
-            next = fd.overnext;
-        }
-        else if (auto os = d.isOverloadSet())
-        {
-            foreach (ds; os.a)
-                if (int r = dg(ds))
-                    return r;
-        }
-        else
-        {
-            d.error("is aliased to a function");
-            break;
-            // BUG: should print error message?
         }
+        return 0;
     }
-    return 0;
+    return overloadApplyRecurse(fstart, dg, sc);
 }
 
 /**
diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d
index 2770f5a91ca..80c183e5a77 100644
--- a/gcc/d/dmd/globals.d
+++ b/gcc/d/dmd/globals.d
@@ -1,7 +1,7 @@ 
 /**
  * Stores command line options and contains other miscellaneous declarations.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/globals.d, _globals.d)
@@ -17,6 +17,7 @@  import dmd.root.filename;
 import dmd.common.outbuffer;
 import dmd.file_manager;
 import dmd.identifier;
+import dmd.location;
 
 /// Defines a setting for how compiler warnings and deprecations are handled
 enum DiagnosticReporting : ubyte
@@ -26,13 +27,6 @@  enum DiagnosticReporting : ubyte
     off,          /// disable diagnostic
 }
 
-/// How code locations are formatted for diagnostic reporting
-enum MessageStyle : ubyte
-{
-    digitalmars,  /// filename.d(line): message
-    gnu,          /// filename.d:line: message, see https://www.gnu.org/prep/standards/html_node/Errors.html
-}
-
 /// In which context checks for assertions, contracts, bounds checks etc. are enabled
 enum CHECKENABLE : ubyte
 {
@@ -266,7 +260,7 @@  extern (C++) struct Global
 {
     const(char)[] inifilename; /// filename of configuration file as given by `-conf=`, or default value
 
-    string copyright = "Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved";
+    string copyright = "Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved";
     string written = "written by Walter Bright";
 
     Array!(const(char)*)* path;         /// Array of char*'s which form the import lookup path
@@ -446,125 +440,5 @@  alias dinteger_t = ulong;
 alias sinteger_t = long;
 alias uinteger_t = ulong;
 
-version (DMDLIB)
-{
-    version = LocOffset;
-}
-
-/**
-A source code location
-
-Used for error messages, `__FILE__` and `__LINE__` tokens, `__traits(getLocation, XXX)`,
-debug info etc.
-*/
-struct Loc
-{
-    /// zero-terminated filename string, either absolute or relative to cwd
-    const(char)* filename;
-    uint linnum; /// line number, starting from 1
-    uint charnum; /// utf8 code unit index relative to start of line, starting from 1
-    version (LocOffset)
-        uint fileOffset; /// utf8 code unit index relative to start of file, starting from 0
-
-    static immutable Loc initial; /// use for default initialization of const ref Loc's
-
-nothrow:
-    extern (D) this(const(char)* filename, uint linnum, uint charnum) pure
-    {
-        this.linnum = linnum;
-        this.charnum = charnum;
-        this.filename = filename;
-    }
-
-    extern (C++) const(char)* toChars(
-        bool showColumns = global.params.showColumns,
-        ubyte messageStyle = global.params.messageStyle) const pure nothrow
-    {
-        OutBuffer buf;
-        if (filename)
-        {
-            buf.writestring(filename);
-        }
-        if (linnum)
-        {
-            final switch (messageStyle)
-            {
-                case MessageStyle.digitalmars:
-                    buf.writeByte('(');
-                    buf.print(linnum);
-                    if (showColumns && charnum)
-                    {
-                        buf.writeByte(',');
-                        buf.print(charnum);
-                    }
-                    buf.writeByte(')');
-                    break;
-                case MessageStyle.gnu: // https://www.gnu.org/prep/standards/html_node/Errors.html
-                    buf.writeByte(':');
-                    buf.print(linnum);
-                    if (showColumns && charnum)
-                    {
-                        buf.writeByte(':');
-                        buf.print(charnum);
-                    }
-                    break;
-            }
-        }
-        return buf.extractChars();
-    }
-
-    /**
-     * Checks for equivalence by comparing the filename contents (not the pointer) and character location.
-     *
-     * Note:
-     *  - Uses case-insensitive comparison on Windows
-     *  - Ignores `charnum` if `global.params.showColumns` is false.
-     */
-    extern (C++) bool equals(ref const(Loc) loc) const
-    {
-        return (!global.params.showColumns || charnum == loc.charnum) &&
-               linnum == loc.linnum &&
-               FileName.equals(filename, loc.filename);
-    }
-
-    /**
-     * `opEquals()` / `toHash()` for AA key usage
-     *
-     * Compare filename contents (case-sensitively on Windows too), not
-     * the pointer - a static foreach loop repeatedly mixing in a mixin
-     * may lead to multiple equivalent filenames (`foo.d-mixin-<line>`),
-     * e.g., for test/runnable/test18880.d.
-     */
-    extern (D) bool opEquals(ref const(Loc) loc) const @trusted pure nothrow @nogc
-    {
-        import core.stdc.string : strcmp;
-
-        return charnum == loc.charnum &&
-               linnum == loc.linnum &&
-               (filename == loc.filename ||
-                (filename && loc.filename && strcmp(filename, loc.filename) == 0));
-    }
-
-    /// ditto
-    extern (D) size_t toHash() const @trusted pure nothrow
-    {
-        import dmd.root.string : toDString;
-
-        auto hash = hashOf(linnum);
-        hash = hashOf(charnum, hash);
-        hash = hashOf(filename.toDString, hash);
-        return hash;
-    }
-
-    /******************
-     * Returns:
-     *   true if Loc has been set to other than the default initialization
-     */
-    bool isValid() const pure
-    {
-        return filename !is null;
-    }
-}
-
 /// Collection of global state
 extern (C++) __gshared Global global;
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index d9cb76c707c..45c5624b19c 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
@@ -30,11 +30,10 @@  enum
     DIAGNOSTICoff     // disable diagnostic
 };
 
-typedef unsigned char MessageStyle;
-enum
+enum class MessageStyle : unsigned char
 {
-    MESSAGESTYLEdigitalmars, // file(line,column): message
-    MESSAGESTYLEgnu          // file:line:column: message
+    digitalmars, // file(line,column): message
+    gnu          // file:line:column: message
 };
 
 // The state of array bounds checking
@@ -342,6 +341,11 @@  struct Loc
     unsigned linnum;
     unsigned charnum;
 
+    static void set(bool showColumns, MessageStyle messageStyle);
+
+    static bool showColumns;
+    static MessageStyle messageStyle;
+
     Loc()
     {
         linnum = 0;
@@ -357,8 +361,8 @@  struct Loc
     }
 
     const char *toChars(
-        bool showColumns = global.params.showColumns,
-        MessageStyle messageStyle = global.params.messageStyle) const;
+        bool showColumns = Loc::showColumns,
+        MessageStyle messageStyle = Loc::messageStyle) const;
     bool equals(const Loc& loc) const;
 };
 
diff --git a/gcc/d/dmd/gluelayer.d b/gcc/d/dmd/gluelayer.d
index 73a1f00f776..7b52eff663d 100644
--- a/gcc/d/dmd/gluelayer.d
+++ b/gcc/d/dmd/gluelayer.d
@@ -3,7 +3,7 @@ 
  *
  * This 'glues' either the DMC or GCC back-end to the front-end.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/gluelayer.d, _gluelayer.d)
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index 6b51a81acc5..68670d929e5 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -3,7 +3,7 @@ 
  *
  * Also used to convert AST nodes to D code in general, e.g. for error messages or `printf` debugging.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/hdrgen.d, _hdrgen.d)
@@ -823,10 +823,13 @@  public:
         buf.writestring(s.kind());
         buf.writeByte('(');
         s.exp.expressionToBuffer(buf, hgs);
-        if (s.msg)
+        if (s.msgs)
         {
-            buf.writestring(", ");
-            s.msg.expressionToBuffer(buf, hgs);
+            foreach (m; (*s.msgs)[])
+            {
+                buf.writestring(", ");
+                m.expressionToBuffer(buf, hgs);
+            }
         }
         buf.writestring(");");
         buf.writenl();
diff --git a/gcc/d/dmd/hdrgen.h b/gcc/d/dmd/hdrgen.h
index 0488c51b9e6..43fea34255f 100644
--- a/gcc/d/dmd/hdrgen.h
+++ b/gcc/d/dmd/hdrgen.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Dave Fladebo
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/iasm.d b/gcc/d/dmd/iasm.d
index 29aca3ef34e..4d780b302b0 100644
--- a/gcc/d/dmd/iasm.d
+++ b/gcc/d/dmd/iasm.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/iasm.html, Inline Assembler)
  *
- *              Copyright (C) 2018-2022 by The D Language Foundation, All Rights Reserved
+ *              Copyright (C) 2018-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/iasm.d, _iasm.d)
diff --git a/gcc/d/dmd/iasmgcc.d b/gcc/d/dmd/iasmgcc.d
index f85e1ab2518..baf6b14b97d 100644
--- a/gcc/d/dmd/iasmgcc.d
+++ b/gcc/d/dmd/iasmgcc.d
@@ -1,7 +1,7 @@ 
 /**
  * Inline assembler for the GCC D compiler.
  *
- *              Copyright (C) 2018-2022 by The D Language Foundation, All Rights Reserved
+ *              Copyright (C) 2018-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     Iain Buclaw
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/iasmgcc.d, _iasmgcc.d)
@@ -21,6 +21,7 @@  import dmd.expression;
 import dmd.expressionsem;
 import dmd.identifier;
 import dmd.globals;
+import dmd.location;
 import dmd.parse;
 import dmd.tokens;
 import dmd.statement;
diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d
index 48ca7665eae..40a5c6e47f6 100644
--- a/gcc/d/dmd/id.d
+++ b/gcc/d/dmd/id.d
@@ -1,7 +1,7 @@ 
 /**
  * Contains the `Id` struct with a list of predefined symbols the compiler knows about.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/id.d, _id.d)
diff --git a/gcc/d/dmd/id.h b/gcc/d/dmd/id.h
index 984c20313ce..f6cf6e59c34 100644
--- a/gcc/d/dmd/id.h
+++ b/gcc/d/dmd/id.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 2017-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 2017-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/identifier.d b/gcc/d/dmd/identifier.d
index 7f922981181..2233d777770 100644
--- a/gcc/d/dmd/identifier.d
+++ b/gcc/d/dmd/identifier.d
@@ -1,7 +1,7 @@ 
 /**
  * Defines an identifier, which is the name of a `Dsymbol`.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/identifier.d, _identifier.d)
@@ -14,8 +14,8 @@  module dmd.identifier;
 import core.stdc.ctype;
 import core.stdc.stdio;
 import core.stdc.string;
-import dmd.globals;
 import dmd.id;
+import dmd.location;
 import dmd.common.outbuffer;
 import dmd.root.rootobject;
 import dmd.root.string;
diff --git a/gcc/d/dmd/identifier.h b/gcc/d/dmd/identifier.h
index fa7a25aaaa1..c12c3554c1b 100644
--- a/gcc/d/dmd/identifier.h
+++ b/gcc/d/dmd/identifier.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/impcnvtab.d b/gcc/d/dmd/impcnvtab.d
index 832c331c314..b45880a2887 100644
--- a/gcc/d/dmd/impcnvtab.d
+++ b/gcc/d/dmd/impcnvtab.d
@@ -6,7 +6,7 @@ 
  * Specification: $(LINK2 https://dlang.org/spec/type.html#integer-promotions, Integer Promotions),
  *   $(LINK2 https://dlang.org/spec/type.html#usual-arithmetic-conversions, Usual Arithmetic Conversions).
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/impcnvtab.d, _impcnvtab.d)
diff --git a/gcc/d/dmd/imphint.d b/gcc/d/dmd/imphint.d
index f03113dc657..913de9fa61c 100644
--- a/gcc/d/dmd/imphint.d
+++ b/gcc/d/dmd/imphint.d
@@ -3,7 +3,7 @@ 
  *
  * For example, prompt to `import std.stdio` when using `writeln`.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/imphint.d, _imphint.d)
diff --git a/gcc/d/dmd/import.h b/gcc/d/dmd/import.h
index f749ef5b5f6..ff25ba2045d 100644
--- a/gcc/d/dmd/import.h
+++ b/gcc/d/dmd/import.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/importc.d b/gcc/d/dmd/importc.d
index afec5ef1ead..97710b88199 100644
--- a/gcc/d/dmd/importc.d
+++ b/gcc/d/dmd/importc.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: C11
  *
- * Copyright:   Copyright (C) 2021-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 2021-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/importc.d, _importc.d)
diff --git a/gcc/d/dmd/init.d b/gcc/d/dmd/init.d
index f57b4e644a3..f646d0382eb 100644
--- a/gcc/d/dmd/init.d
+++ b/gcc/d/dmd/init.d
@@ -1,7 +1,7 @@ 
 /**
  * Defines initializers of variables, e.g. the array literal in `int[3] x = [0, 1, 2]`.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/init.d, _init.d)
@@ -22,6 +22,7 @@  import dmd.expression;
 import dmd.globals;
 import dmd.hdrgen;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.common.outbuffer;
 import dmd.root.rootobject;
diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h
index 977157f5c41..66b874c91b5 100644
--- a/gcc/d/dmd/init.h
+++ b/gcc/d/dmd/init.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index ecaa5e8f710..572753b2dd8 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -1,7 +1,7 @@ 
 /**
  * Semantic analysis of initializers.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/initsem.d, _initsem.d)
@@ -33,6 +33,7 @@  import dmd.id;
 import dmd.identifier;
 import dmd.importc;
 import dmd.init;
+import dmd.location;
 import dmd.mtype;
 import dmd.opover;
 import dmd.statement;
diff --git a/gcc/d/dmd/inline.d b/gcc/d/dmd/inline.d
index 25982a696c2..8e63122f4cb 100644
--- a/gcc/d/dmd/inline.d
+++ b/gcc/d/dmd/inline.d
@@ -4,7 +4,7 @@ 
  * The AST is traversed, and every function call is considered for inlining using `inlinecost.d`.
  * The function call is then inlined if this cost is below a threshold.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/inline.d, _inline.d)
diff --git a/gcc/d/dmd/intrange.d b/gcc/d/dmd/intrange.d
index d0206b6ff97..d67e0f5958d 100644
--- a/gcc/d/dmd/intrange.d
+++ b/gcc/d/dmd/intrange.d
@@ -1,7 +1,7 @@ 
 /**
  * Implement $(LINK2 https://digitalmars.com/articles/b62.html, Value Range Propagation).
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/intrange.d, _intrange.d)
diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d
index b7719d8439f..38e03e7d20d 100644
--- a/gcc/d/dmd/json.d
+++ b/gcc/d/dmd/json.d
@@ -1,7 +1,7 @@ 
 /**
  * Code for generating .json descriptions of the module when passing the `-X` flag to dmd.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/json.d, _json.d)
@@ -32,6 +32,7 @@  import dmd.globals;
 import dmd.hdrgen;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.common.outbuffer;
 import dmd.root.rootobject;
diff --git a/gcc/d/dmd/json.h b/gcc/d/dmd/json.h
index 979440cd308..7a238979e20 100644
--- a/gcc/d/dmd/json.h
+++ b/gcc/d/dmd/json.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/lambdacomp.d b/gcc/d/dmd/lambdacomp.d
index e1ed717ab85..c800273e2d4 100644
--- a/gcc/d/dmd/lambdacomp.d
+++ b/gcc/d/dmd/lambdacomp.d
@@ -5,7 +5,7 @@ 
  * The serialization is a string which contains the type of the parameters and the string
  * represantation of the lambda expression.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/lamdbacomp.d, _lambdacomp.d)
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index 200d74f3aad..bd53433d6c8 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/lex.html, Lexical)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/lexer.d, _lexer.d)
@@ -26,6 +26,7 @@  import dmd.errors;
 import dmd.globals;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.root.array;
 import dmd.root.ctfloat;
 import dmd.common.outbuffer;
@@ -79,15 +80,14 @@  class Lexer
         bool commentToken;      // comments are TOK.comment's
         bool tokenizeNewlines;  // newlines are turned into TOK.endOfLine's
 
-        version (DMDLIB)
-        {
-            bool whitespaceToken;   // tokenize whitespaces
-        }
+        bool whitespaceToken;   // tokenize whitespaces (only for DMDLIB)
 
         int inTokenStringConstant; // can be larger than 1 when in nested q{} strings
         int lastDocLine;        // last line of previous doc comment
 
         Token* tokenFreelist;
+        uint versionNumber;
+        const(char)[] vendor;
     }
 
   nothrow:
@@ -103,9 +103,12 @@  class Lexer
      *  endoffset = the last offset to read into base[]
      *  doDocComment = handle documentation comments
      *  commentToken = comments become TOK.comment's
+     *  vendor = name of the vendor
+     *  versionNumber = version of the caller
      */
     this(const(char)* filename, const(char)* base, size_t begoffset,
-        size_t endoffset, bool doDocComment, bool commentToken) pure
+        size_t endoffset, bool doDocComment, bool commentToken,
+        const(char)[] vendor = "DLF", uint versionNumber = 1) pure
     {
         scanloc = Loc(filename, 1, 1);
         // debug printf("Lexer::Lexer(%p)\n", base);
@@ -120,6 +123,8 @@  class Lexer
         this.tokenizeNewlines = false;
         this.inTokenStringConstant = 0;
         this.lastDocLine = 0;
+        this.versionNumber = versionNumber;
+        this.vendor = vendor;
         //initKeywords();
         /* If first line starts with '#!', ignore the line
          */
@@ -154,6 +159,16 @@  class Lexer
         }
     }
 
+    /***********************
+     * Alternative entry point for DMDLIB, adds `whitespaceToken`
+     */
+    this(const(char)* filename, const(char)* base, size_t begoffset, size_t endoffset,
+        bool doDocComment, bool commentToken, bool whitespaceToken)
+    {
+        this(filename, base, begoffset, endoffset, doDocComment, commentToken);
+        this.whitespaceToken = whitespaceToken;
+    }
+
     /******************
      * Used for unittests for a mock Lexer
      */
@@ -184,29 +199,23 @@  class Lexer
         tokenizeNewlines = true;
     }
 
-    version (DMDLIB)
-    {
-        this(const(char)* filename, const(char)* base, size_t begoffset, size_t endoffset,
-            bool doDocComment, bool commentToken, bool whitespaceToken)
-        {
-            this(filename, base, begoffset, endoffset, doDocComment, commentToken);
-            this.whitespaceToken = whitespaceToken;
-        }
+    /***************
+     * Range interface
+     */
 
-        bool empty() const pure @property @nogc @safe
-        {
-            return front() == TOK.endOfFile;
-        }
+    final bool empty() const pure @property @nogc @safe
+    {
+        return front() == TOK.endOfFile;
+    }
 
-        TOK front() const pure @property @nogc @safe
-        {
-            return token.value;
-        }
+    final TOK front() const pure @property @nogc @safe
+    {
+        return token.value;
+    }
 
-        void popFront()
-        {
-            nextToken();
-        }
+    final void popFront()
+    {
+        nextToken();
     }
 
     /// Returns: a newly allocated `Token`.
@@ -570,7 +579,7 @@  class Lexer
                         }
                         else if (id == Id.VENDOR)
                         {
-                            t.ustring = global.vendor.xarraydup.ptr;
+                            t.ustring = vendor.xarraydup.ptr;
                             goto Lstr;
                         }
                         else if (id == Id.TIMESTAMP)
@@ -584,7 +593,7 @@  class Lexer
                         else if (id == Id.VERSIONX)
                         {
                             t.value = TOK.int64Literal;
-                            t.unsvalue = global.versionNumber();
+                            t.unsvalue = versionNumber;
                         }
                         else if (id == Id.EOFX)
                         {
@@ -1965,7 +1974,7 @@  class Lexer
     {
         int base = 10;
         const start = p;
-        uinteger_t n = 0; // unsigned >=64 bit integer type
+        ulong n = 0; // unsigned >=64 bit integer type
         int d;
         bool err = false;
         bool overflow = false;
@@ -2274,7 +2283,7 @@  class Lexer
      * Returns:
      *  token value
      */
-    private TOK cnumber(int base, uinteger_t n)
+    private TOK cnumber(int base, ulong n)
     {
         /* C11 6.4.4.1
          * Parse trailing suffixes:
diff --git a/gcc/d/dmd/location.d b/gcc/d/dmd/location.d
new file mode 100644
index 00000000000..020d297b06d
--- /dev/null
+++ b/gcc/d/dmd/location.d
@@ -0,0 +1,158 @@ 
+/**
+ * Encapsulates file/line/column locations.
+ *
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
+ * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
+ * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
+ * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/location.d, _location.d)
+ * Documentation:  https://dlang.org/phobos/dmd_location.html
+ * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/location.d
+ */
+
+module dmd.location;
+
+import dmd.common.outbuffer;
+import dmd.root.filename;
+
+version (DMDLIB)
+{
+    version = LocOffset;
+}
+
+/// How code locations are formatted for diagnostic reporting
+enum MessageStyle : ubyte
+{
+    digitalmars,  /// filename.d(line): message
+    gnu,          /// filename.d:line: message, see https://www.gnu.org/prep/standards/html_node/Errors.html
+}
+
+/**
+A source code location
+
+Used for error messages, `__FILE__` and `__LINE__` tokens, `__traits(getLocation, XXX)`,
+debug info etc.
+*/
+struct Loc
+{
+    /// zero-terminated filename string, either absolute or relative to cwd
+    const(char)* filename;
+    uint linnum; /// line number, starting from 1
+    uint charnum; /// utf8 code unit index relative to start of line, starting from 1
+    version (LocOffset)
+        uint fileOffset; /// utf8 code unit index relative to start of file, starting from 0
+
+    static immutable Loc initial; /// use for default initialization of const ref Loc's
+
+    extern (C++) __gshared bool showColumns;
+    extern (C++) __gshared MessageStyle messageStyle;
+
+nothrow:
+
+    /*******************************
+     * Configure how display is done
+     * Params:
+     *  showColumns = when to display columns
+     *  messageStyle = digitalmars or gnu style messages
+     */
+    extern (C++) static void set(bool showColumns, MessageStyle messageStyle)
+    {
+        this.showColumns = showColumns;
+        this.messageStyle = messageStyle;
+    }
+
+    extern (D) this(const(char)* filename, uint linnum, uint charnum) pure
+    {
+        this.linnum = linnum;
+        this.charnum = charnum;
+        this.filename = filename;
+    }
+
+    extern (C++) const(char)* toChars(
+        bool showColumns = Loc.showColumns,
+        MessageStyle messageStyle = Loc.messageStyle) const pure nothrow
+    {
+        OutBuffer buf;
+        if (filename)
+        {
+            buf.writestring(filename);
+        }
+        if (linnum)
+        {
+            final switch (messageStyle)
+            {
+                case MessageStyle.digitalmars:
+                    buf.writeByte('(');
+                    buf.print(linnum);
+                    if (showColumns && charnum)
+                    {
+                        buf.writeByte(',');
+                        buf.print(charnum);
+                    }
+                    buf.writeByte(')');
+                    break;
+                case MessageStyle.gnu: // https://www.gnu.org/prep/standards/html_node/Errors.html
+                    buf.writeByte(':');
+                    buf.print(linnum);
+                    if (showColumns && charnum)
+                    {
+                        buf.writeByte(':');
+                        buf.print(charnum);
+                    }
+                    break;
+            }
+        }
+        return buf.extractChars();
+    }
+
+    /**
+     * Checks for equivalence by comparing the filename contents (not the pointer) and character location.
+     *
+     * Note:
+     *  - Uses case-insensitive comparison on Windows
+     *  - Ignores `charnum` if `Columns` is false.
+     */
+    extern (C++) bool equals(ref const(Loc) loc) const
+    {
+        return (!showColumns || charnum == loc.charnum) &&
+               linnum == loc.linnum &&
+               FileName.equals(filename, loc.filename);
+    }
+
+    /**
+     * `opEquals()` / `toHash()` for AA key usage
+     *
+     * Compare filename contents (case-sensitively on Windows too), not
+     * the pointer - a static foreach loop repeatedly mixing in a mixin
+     * may lead to multiple equivalent filenames (`foo.d-mixin-<line>`),
+     * e.g., for test/runnable/test18880.d.
+     */
+    extern (D) bool opEquals(ref const(Loc) loc) const @trusted pure nothrow @nogc
+    {
+        import core.stdc.string : strcmp;
+
+        return charnum == loc.charnum &&
+               linnum == loc.linnum &&
+               (filename == loc.filename ||
+                (filename && loc.filename && strcmp(filename, loc.filename) == 0));
+    }
+
+    /// ditto
+    extern (D) size_t toHash() const @trusted pure nothrow
+    {
+        import dmd.root.string : toDString;
+
+        auto hash = hashOf(linnum);
+        hash = hashOf(charnum, hash);
+        hash = hashOf(filename.toDString, hash);
+        return hash;
+    }
+
+    /******************
+     * Returns:
+     *   true if Loc has been set to other than the default initialization
+     */
+    bool isValid() const pure
+    {
+        return filename !is null;
+    }
+}
diff --git a/gcc/d/dmd/mangle.h b/gcc/d/dmd/mangle.h
index 512184ae9aa..37953c2ca4a 100644
--- a/gcc/d/dmd/mangle.h
+++ b/gcc/d/dmd/mangle.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h
index 48046def130..bc89ac4677e 100644
--- a/gcc/d/dmd/module.h
+++ b/gcc/d/dmd/module.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
@@ -79,18 +79,18 @@  public:
     Package *pkg;       // if isPackageFile is true, the Package that contains this package.d
     Strings contentImportedFiles;  // array of files whose content was imported
     int needmoduleinfo;
-    int selfimports;            // 0: don't know, 1: does not, 2: does
+    ThreeState selfimports;
+    ThreeState rootimports;
     void* tagSymTab;            // ImportC: tag symbols that conflict with other symbols used as the index
     OutBuffer defines;          // collect all the #define lines here
     bool selfImports();         // returns true if module imports itself
 
-    int rootimports;            // 0: don't know, 1: does not, 2: does
     bool rootImports();         // returns true if module imports root module
 
-    int insearch;
     Identifier *searchCacheIdent;
     Dsymbol *searchCacheSymbol; // cached value of search
     int searchCacheFlags;       // cached flags
+    bool insearch;
 
     // module from command line we're imported from,
     // i.e. a module that will be taken all the
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index 2c0a5718421..232042d9f4f 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -1,7 +1,7 @@ 
 /**
  * Defines a D type.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/mtype.d, _mtype.d)
@@ -41,6 +41,7 @@  import dmd.hdrgen;
 import dmd.id;
 import dmd.identifier;
 import dmd.init;
+import dmd.location;
 import dmd.opover;
 import dmd.root.ctfloat;
 import dmd.common.outbuffer;
@@ -7384,3 +7385,51 @@  private extern(D) MATCH matchTypeSafeVarArgs(TypeFunction tf, Parameter p,
         return MATCH.nomatch;
     }
 }
+
+/**
+ * Creates an appropriate vector type for `tv` that will hold one boolean
+ * result for each element of the vector type. The result of vector comparisons
+ * is a single or doubleword mask of all 1s (comparison true) or all 0s
+ * (comparison false). This SIMD mask type does not have an equivalent D type,
+ * however its closest equivalent would be an integer vector of the same unit
+ * size and length.
+ *
+ * Params:
+ *   tv = The `TypeVector` to build a vector from.
+ * Returns:
+ *   A vector type suitable for the result of a vector comparison operation.
+ */
+TypeVector toBooleanVector(TypeVector tv)
+{
+    Type telem = tv.elementType();
+    switch (telem.ty)
+    {
+        case Tvoid:
+        case Tint8:
+        case Tuns8:
+        case Tint16:
+        case Tuns16:
+        case Tint32:
+        case Tuns32:
+        case Tint64:
+        case Tuns64:
+            // No need to build an equivalent mask type.
+            return tv;
+
+        case Tfloat32:
+            telem = Type.tuns32;
+            break;
+
+        case Tfloat64:
+            telem = Type.tuns64;
+            break;
+
+        default:
+            assert(0);
+    }
+
+    TypeSArray tsa = tv.basetype.isTypeSArray();
+    assert(tsa !is null);
+
+    return new TypeVector(new TypeSArray(telem, tsa.dim));
+}
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index c81c25a0d79..d0775f2f5fb 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/mustuse.d b/gcc/d/dmd/mustuse.d
index 369d60e208a..11cc3b8d6d8 100644
--- a/gcc/d/dmd/mustuse.d
+++ b/gcc/d/dmd/mustuse.d
@@ -1,7 +1,7 @@ 
 /**
  * Compile-time checks associated with the @mustuse attribute.
  *
- * Copyright: Copyright (C) 2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 2022-2023 by The D Language Foundation, All Rights Reserved
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/mustuse.d, _mustuse.d)
  * Documentation:  https://dlang.org/phobos/dmd_mustuse.html
@@ -15,6 +15,7 @@  import dmd.dsymbol;
 import dmd.expression;
 import dmd.globals;
 import dmd.identifier;
+import dmd.location;
 
 // Used in isIncrementOrDecrement
 private static const StringExp plusPlus, minusMinus;
@@ -147,7 +148,7 @@  private bool isAssignmentOpId(Identifier id)
 private bool isIncrementOrDecrement(Expression e)
 {
     import dmd.dtemplate : isExpression;
-    import dmd.globals : Loc;
+    import dmd.location;
     import dmd.id : Id;
     import dmd.tokens : EXP;
 
diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d
index 3329c14afbf..370e3b81d20 100644
--- a/gcc/d/dmd/nogc.d
+++ b/gcc/d/dmd/nogc.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/function.html#nogc-functions, No-GC Functions)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/nogc.d, _nogc.d)
diff --git a/gcc/d/dmd/nspace.d b/gcc/d/dmd/nspace.d
index 40f2676d88f..551db5b7475 100644
--- a/gcc/d/dmd/nspace.d
+++ b/gcc/d/dmd/nspace.d
@@ -36,7 +36,7 @@ 
  * are valid D identifier.
  *
  * See_Also:    https://github.com/dlang/dmd/pull/10031
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/nspace.d, _nspace.d)
@@ -55,6 +55,7 @@  import dmd.dsymbolsem;
 import dmd.expression;
 import dmd.globals;
 import dmd.identifier;
+import dmd.location;
 import dmd.visitor;
 import core.stdc.stdio;
 
diff --git a/gcc/d/dmd/nspace.h b/gcc/d/dmd/nspace.h
index 9dbbdf2fd0a..e9fb7bdc777 100644
--- a/gcc/d/dmd/nspace.h
+++ b/gcc/d/dmd/nspace.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/ob.d b/gcc/d/dmd/ob.d
index 59f34e1c1de..31e93a7637f 100644
--- a/gcc/d/dmd/ob.d
+++ b/gcc/d/dmd/ob.d
@@ -1,7 +1,7 @@ 
 /**
  * Flow analysis for Ownership/Borrowing
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/ob.d, _ob.d)
@@ -35,6 +35,7 @@  import dmd.func;
 import dmd.globals;
 import dmd.identifier;
 import dmd.init;
+import dmd.location;
 import dmd.mtype;
 import dmd.printast;
 import dmd.statement;
diff --git a/gcc/d/dmd/objc.d b/gcc/d/dmd/objc.d
index 2bb5eabe4eb..c493323e238 100644
--- a/gcc/d/dmd/objc.d
+++ b/gcc/d/dmd/objc.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/objc_interface.html, Interfacing to Objective-C)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/objc.d, _objc.d)
@@ -36,6 +36,7 @@  import dmd.gluelayer;
 import dmd.hdrgen;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.root.array;
 import dmd.common.outbuffer;
diff --git a/gcc/d/dmd/objc.h b/gcc/d/dmd/objc.h
index a03015489a4..305ce812487 100644
--- a/gcc/d/dmd/objc.h
+++ b/gcc/d/dmd/objc.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 2015-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 2015-2023 by The D Language Foundation, All Rights Reserved
  * written by Michel Fortin
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d
index de417274a66..4d7fe9fcea3 100644
--- a/gcc/d/dmd/opover.d
+++ b/gcc/d/dmd/opover.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/operatoroverloading.html, Operator Overloading)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/opover.d, _opover.d)
@@ -32,6 +32,7 @@  import dmd.globals;
 import dmd.hdrgen;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.statement;
 import dmd.tokens;
@@ -931,6 +932,12 @@  Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
                     /* Rewrite as:
                      *      .object.opEquals(e1, e2)
                      */
+                    if (!ClassDeclaration.object)
+                    {
+                        e.error("cannot compare classes for equality because `object.Object` was not declared");
+                        return null;
+                    }
+
                     Expression e1x = e.e1;
                     Expression e2x = e.e2;
 
diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d
index a9c542579ad..b5d32b2932d 100644
--- a/gcc/d/dmd/optimize.d
+++ b/gcc/d/dmd/optimize.d
@@ -1,7 +1,7 @@ 
 /**
  * Perform constant folding.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/optimize.d, _optimize.d)
@@ -25,6 +25,7 @@  import dmd.expression;
 import dmd.expressionsem;
 import dmd.globals;
 import dmd.init;
+import dmd.location;
 import dmd.mtype;
 import dmd.printast;
 import dmd.root.ctfloat;
@@ -586,7 +587,7 @@  Expression Expression_optimize(Expression e, int result, bool keepLvalue)
                     Expression ex = new AddrExp(ae1.loc, ae1);  // &a[i]
                     ex.type = ae1.type.pointerTo();
 
-                    Expression add = new AddExp(ae.loc, ex, new IntegerExp(ae.loc, offset, e.type));
+                    Expression add = new AddExp(ae.loc, ex, new IntegerExp(ae.e2.loc, offset, ae.e2.type));
                     add.type = e.type;
                     ret = Expression_optimize(add, result, keepLvalue);
                     return;
@@ -862,7 +863,8 @@  Expression Expression_optimize(Expression e, int result, bool keepLvalue)
                 return returnE_e1();    // can always convert a class to Object
             // Need to determine correct offset before optimizing away the cast.
             // https://issues.dlang.org/show_bug.cgi?id=16980
-            cdfrom.size(e.loc);
+            if (cdfrom.size(e.loc) == SIZE_INVALID)
+                return error();
             assert(cdfrom.sizeok == Sizeok.done);
             assert(cdto.sizeok == Sizeok.done || !cdto.isBaseOf(cdfrom, null));
             int offset;
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index 93c7ea0eea0..6eb3021dd82 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/grammar.html, D Grammar)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/parse.d, _parse.d)
@@ -20,6 +20,7 @@  import dmd.globals;
 import dmd.id;
 import dmd.identifier;
 import dmd.lexer;
+import dmd.location;
 import dmd.errors;
 import dmd.root.filename;
 import dmd.common.outbuffer;
@@ -52,7 +53,8 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
      */
     extern (D) this(const ref Loc loc, AST.Module _module, const(char)[] input, bool doDocComment)
     {
-        super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false);
+        super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false,
+                global.vendor, global.versionNumber());
 
         //printf("Parser::Parser()\n");
         scanloc = loc;
@@ -74,7 +76,8 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
     extern (D) this(AST.Module _module, const(char)[] input, bool doDocComment)
     {
-        super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false);
+        super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false,
+              global.vendor, global.versionNumber());
 
         //printf("Parser::Parser()\n");
         mod = _module;
@@ -1982,7 +1985,7 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
     {
         const loc = token.loc;
         AST.Expression exp;
-        AST.Expression msg = null;
+        AST.Expressions* msg = null;
 
         //printf("parseStaticAssert()\n");
         nextToken();
@@ -1991,15 +1994,16 @@  class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
         exp = parseAssignExp();
         if (token.value == TOK.comma)
         {
-            nextToken();
-            if (token.value != TOK.rightParenthesis)
+            if (peekNext() == TOK.rightParenthesis)
             {
-                msg = parseAssignExp();
-                if (token.value == TOK.comma)
-                    nextToken();
+                nextToken(); // consume `,`
+                nextToken(); // consume `)`
             }
+            else
+                msg = parseArguments();
         }
-        check(TOK.rightParenthesis);
+        else
+            check(TOK.rightParenthesis);
         check(TOK.semicolon, "static assert");
         return new AST.StaticAssert(loc, exp, msg);
     }
@@ -5719,6 +5723,8 @@  LagainStc:
                         s = null;
                     else if (token.value == TOK.leftCurly)
                         s = parseStatement(ParseStatementFlags.curly | ParseStatementFlags.scope_);
+                    else if (flags & ParseStatementFlags.curlyScope)
+                        s = parseStatement(ParseStatementFlags.semiOk | ParseStatementFlags.curlyScope);
                     else
                         s = parseStatement(ParseStatementFlags.semiOk);
                     s = new AST.LabelStatement(loc, ident, s);
diff --git a/gcc/d/dmd/printast.d b/gcc/d/dmd/printast.d
index 8c71a1a36aa..9975c9c1f1e 100644
--- a/gcc/d/dmd/printast.d
+++ b/gcc/d/dmd/printast.d
@@ -1,7 +1,7 @@ 
 /**
  * Provides an AST printer for debugging.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/printast.d, _printast.d)
diff --git a/gcc/d/dmd/root/aav.d b/gcc/d/dmd/root/aav.d
index beceb0f0707..42d13994126 100644
--- a/gcc/d/dmd/root/aav.d
+++ b/gcc/d/dmd/root/aav.d
@@ -1,7 +1,7 @@ 
 /**
  * Associative array implementation.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:   Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/aav.d, root/_aav.d)
diff --git a/gcc/d/dmd/root/array.d b/gcc/d/dmd/root/array.d
index 5c01940dadb..e352c61ce6b 100644
--- a/gcc/d/dmd/root/array.d
+++ b/gcc/d/dmd/root/array.d
@@ -2,7 +2,7 @@ 
 /**
  * Dynamic array implementation.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/array.d, root/_array.d)
diff --git a/gcc/d/dmd/root/array.h b/gcc/d/dmd/root/array.h
index 52bed5e9d7f..ebe2c47d0a0 100644
--- a/gcc/d/dmd/root/array.h
+++ b/gcc/d/dmd/root/array.h
@@ -1,4 +1,4 @@ 
-/* Copyright (C) 2011-2022 by The D Language Foundation, All Rights Reserved
+/* Copyright (C) 2011-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/root/bitarray.d b/gcc/d/dmd/root/bitarray.d
index 90cbaed4981..66adab65877 100644
--- a/gcc/d/dmd/root/bitarray.d
+++ b/gcc/d/dmd/root/bitarray.d
@@ -1,7 +1,7 @@ 
 /**
  * Implementation of a bit array.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/bitarray.d, root/_bitarray.d)
diff --git a/gcc/d/dmd/root/bitarray.h b/gcc/d/dmd/root/bitarray.h
index c5c5d3a94bb..617cc9e2cfa 100644
--- a/gcc/d/dmd/root/bitarray.h
+++ b/gcc/d/dmd/root/bitarray.h
@@ -1,4 +1,4 @@ 
-/* Copyright (C) 2011-2022 by The D Language Foundation, All Rights Reserved
+/* Copyright (C) 2011-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/root/complex.d b/gcc/d/dmd/root/complex.d
index a7a74381ef9..fc93bd7d404 100644
--- a/gcc/d/dmd/root/complex.d
+++ b/gcc/d/dmd/root/complex.d
@@ -1,7 +1,7 @@ 
 /**
  * Implements a complex number type.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/complex.d, _complex.d)
diff --git a/gcc/d/dmd/root/complex_t.h b/gcc/d/dmd/root/complex_t.h
index c384848e9ec..de2040b88f7 100644
--- a/gcc/d/dmd/root/complex_t.h
+++ b/gcc/d/dmd/root/complex_t.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/root/ctfloat.d b/gcc/d/dmd/root/ctfloat.d
index 8c2fe46eebe..cd336e63f72 100644
--- a/gcc/d/dmd/root/ctfloat.d
+++ b/gcc/d/dmd/root/ctfloat.d
@@ -1,7 +1,7 @@ 
 /**
  * Collects functions for compile-time floating-point calculations.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/ctfloat.d, root/_ctfloat.d)
diff --git a/gcc/d/dmd/root/ctfloat.h b/gcc/d/dmd/root/ctfloat.h
index 5a6cf258ed8..44bd959edd9 100644
--- a/gcc/d/dmd/root/ctfloat.h
+++ b/gcc/d/dmd/root/ctfloat.h
@@ -1,5 +1,5 @@ 
 
-/* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+/* Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/root/dcompat.h b/gcc/d/dmd/root/dcompat.h
index 5823e7c4886..0bc23b7a8b3 100644
--- a/gcc/d/dmd/root/dcompat.h
+++ b/gcc/d/dmd/root/dcompat.h
@@ -1,5 +1,5 @@ 
 
-/* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+/* Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/root/file.d b/gcc/d/dmd/root/file.d
index b40413c9ef1..1fb105682ea 100644
--- a/gcc/d/dmd/root/file.d
+++ b/gcc/d/dmd/root/file.d
@@ -1,7 +1,7 @@ 
 /**
  * Read a file from disk and store it in memory.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:   Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/file.d, root/_file.d)
diff --git a/gcc/d/dmd/root/filename.d b/gcc/d/dmd/root/filename.d
index f6a451596bb..33f4a7aa4b1 100644
--- a/gcc/d/dmd/root/filename.d
+++ b/gcc/d/dmd/root/filename.d
@@ -1,7 +1,7 @@ 
 /**
  * Encapsulate path and file names.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:   Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/filename.d, root/_filename.d)
diff --git a/gcc/d/dmd/root/filename.h b/gcc/d/dmd/root/filename.h
index 419a4c9ae68..89774119d4d 100644
--- a/gcc/d/dmd/root/filename.h
+++ b/gcc/d/dmd/root/filename.h
@@ -1,5 +1,5 @@ 
 
-/* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+/* Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/root/hash.d b/gcc/d/dmd/root/hash.d
index fe97c421ab6..2acee35c4f3 100644
--- a/gcc/d/dmd/root/hash.d
+++ b/gcc/d/dmd/root/hash.d
@@ -1,7 +1,7 @@ 
 /**
  * Hash functions for arbitrary binary data.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:   Martin Nowak, Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/hash.d, root/_hash.d)
diff --git a/gcc/d/dmd/root/object.h b/gcc/d/dmd/root/object.h
index b735dd98728..8e505f036c7 100644
--- a/gcc/d/dmd/root/object.h
+++ b/gcc/d/dmd/root/object.h
@@ -1,5 +1,5 @@ 
 
-/* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+/* Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/root/optional.d b/gcc/d/dmd/root/optional.d
index 266846bcb0b..bc1016b102a 100644
--- a/gcc/d/dmd/root/optional.d
+++ b/gcc/d/dmd/root/optional.d
@@ -1,7 +1,7 @@ 
 /**
  * Implementation of an 'Optional' type
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/optional.d, root/_optional.d)
diff --git a/gcc/d/dmd/root/optional.h b/gcc/d/dmd/root/optional.h
index e4a41a06100..cc2ee79edeb 100644
--- a/gcc/d/dmd/root/optional.h
+++ b/gcc/d/dmd/root/optional.h
@@ -3,7 +3,7 @@ 
 /**
  * Optional implementation.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/optional.h, root/_optional.h)
diff --git a/gcc/d/dmd/root/port.d b/gcc/d/dmd/root/port.d
index 0c8088cdd77..290280f619c 100644
--- a/gcc/d/dmd/root/port.d
+++ b/gcc/d/dmd/root/port.d
@@ -1,7 +1,7 @@ 
 /**
  * Portable routines for functions that have different implementations on different platforms.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:   Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/port.d, root/_port.d)
diff --git a/gcc/d/dmd/root/port.h b/gcc/d/dmd/root/port.h
index 66a67605b5c..6fa3c000e5a 100644
--- a/gcc/d/dmd/root/port.h
+++ b/gcc/d/dmd/root/port.h
@@ -1,5 +1,5 @@ 
 
-/* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+/* Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/root/region.d b/gcc/d/dmd/root/region.d
index 1e86f32fa60..9fc57f1e3a8 100644
--- a/gcc/d/dmd/root/region.d
+++ b/gcc/d/dmd/root/region.d
@@ -1,7 +1,7 @@ 
 /**
  * Region storage allocator implementation.
  *
- * Copyright:   Copyright (C) 2019-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 2019-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/region.d, root/_region.d)
diff --git a/gcc/d/dmd/root/rmem.d b/gcc/d/dmd/root/rmem.d
index ffe5ee10fef..9b1d9fba524 100644
--- a/gcc/d/dmd/root/rmem.d
+++ b/gcc/d/dmd/root/rmem.d
@@ -1,7 +1,7 @@ 
 /**
  * Allocate memory using `malloc` or the GC depending on the configuration.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:   Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/rmem.d, root/_rmem.d)
diff --git a/gcc/d/dmd/root/rmem.h b/gcc/d/dmd/root/rmem.h
index 1338d7c6e46..36aa2646fdc 100644
--- a/gcc/d/dmd/root/rmem.h
+++ b/gcc/d/dmd/root/rmem.h
@@ -1,5 +1,5 @@ 
 
-/* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+/* Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/root/rootobject.d b/gcc/d/dmd/root/rootobject.d
index 7390d07cacc..4437d1622e4 100644
--- a/gcc/d/dmd/root/rootobject.d
+++ b/gcc/d/dmd/root/rootobject.d
@@ -1,7 +1,7 @@ 
 /**
  * Provide the root object that classes in dmd inherit from.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:   Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/rootobject.d, root/_rootobject.d)
diff --git a/gcc/d/dmd/root/speller.d b/gcc/d/dmd/root/speller.d
index 9b9460d3269..b646bdda0cc 100644
--- a/gcc/d/dmd/root/speller.d
+++ b/gcc/d/dmd/root/speller.d
@@ -3,7 +3,7 @@ 
  *
  * Does not have any dependencies on the rest of DMD.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:   Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/speller.d, root/_speller.d)
diff --git a/gcc/d/dmd/root/string.d b/gcc/d/dmd/root/string.d
index 93c596ff0cd..8b204ab4cad 100644
--- a/gcc/d/dmd/root/string.d
+++ b/gcc/d/dmd/root/string.d
@@ -1,7 +1,7 @@ 
 /**
  * Contains various string related functions.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:   Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/string.d, root/_string.d)
diff --git a/gcc/d/dmd/root/stringtable.d b/gcc/d/dmd/root/stringtable.d
index 20316faeccf..de293eb9b55 100644
--- a/gcc/d/dmd/root/stringtable.d
+++ b/gcc/d/dmd/root/stringtable.d
@@ -1,7 +1,7 @@ 
 /**
  * A specialized associative array with string keys stored in a variable length structure.
  *
- * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:   Walter Bright, https://www.digitalmars.com
  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/stringtable.d, root/_stringtable.d)
diff --git a/gcc/d/dmd/root/utf.d b/gcc/d/dmd/root/utf.d
index 0d230e764c3..c9781a46bc6 100644
--- a/gcc/d/dmd/root/utf.d
+++ b/gcc/d/dmd/root/utf.d
@@ -1,7 +1,7 @@ 
 /**
  * Functions related to UTF encoding.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/utf.d, _utf.d)
diff --git a/gcc/d/dmd/safe.d b/gcc/d/dmd/safe.d
index 397fd2ef472..c3fa90d7f79 100644
--- a/gcc/d/dmd/safe.d
+++ b/gcc/d/dmd/safe.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/function.html#function-safety, Function Safety)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/safe.d, _safe.d)
diff --git a/gcc/d/dmd/sapply.d b/gcc/d/dmd/sapply.d
index adfae329e06..848602897b9 100644
--- a/gcc/d/dmd/sapply.d
+++ b/gcc/d/dmd/sapply.d
@@ -1,7 +1,7 @@ 
 /**
  * Provides a depth-first statement visitor.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/sparse.d, _sparse.d)
diff --git a/gcc/d/dmd/scope.h b/gcc/d/dmd/scope.h
index 8b9e59e3aae..b25c26afff2 100644
--- a/gcc/d/dmd/scope.h
+++ b/gcc/d/dmd/scope.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d
index 4795bcfcf6d..c103f60689b 100644
--- a/gcc/d/dmd/semantic2.d
+++ b/gcc/d/dmd/semantic2.d
@@ -1,7 +1,7 @@ 
 /**
  * Performs the semantic2 stage, which deals with initializer expressions.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/semantic2.d, _semantic2.d)
@@ -110,21 +110,36 @@  private extern(C++) final class Semantic2Visitor : Visitor
         else if (result)
             return;
 
-        if (sa.msg)
+        if (sa.msgs)
         {
-            sc = sc.startCTFE();
-            sa.msg = sa.msg.expressionSemantic(sc);
-            sa.msg = resolveProperties(sc, sa.msg);
-            sc = sc.endCTFE();
-            sa.msg = sa.msg.ctfeInterpret();
-            if (StringExp se = sa.msg.toStringExp())
+            OutBuffer msgbuf;
+            for (size_t i = 0; i < sa.msgs.length; i++)
             {
-                // same with pragma(msg)
-                const slice = se.toUTF8(sc).peekString();
-                error(sa.loc, "static assert:  \"%.*s\"", cast(int)slice.length, slice.ptr);
+                Expression e = (*sa.msgs)[i];
+                sc = sc.startCTFE();
+                e = e.expressionSemantic(sc);
+                e = resolveProperties(sc, e);
+                sc = sc.endCTFE();
+                e = ctfeInterpretForPragmaMsg(e);
+                if (e.op == EXP.error)
+                {
+                    errorSupplemental(sa.loc, "while evaluating `static assert` argument `%s`", (*sa.msgs)[i].toChars());
+                    return;
+                }
+                StringExp se = e.toStringExp();
+                if (se)
+                {
+                    const slice = se.toUTF8(sc).peekString();
+                    // Hack to keep old formatting to avoid changing error messages everywhere
+                    if (sa.msgs.length == 1)
+                        msgbuf.printf("\"%.*s\"", cast(int)slice.length, slice.ptr);
+                    else
+                        msgbuf.printf("%.*s", cast(int)slice.length, slice.ptr);
+                }
+                else
+                    msgbuf.printf("%s", e.toChars());
             }
-            else
-                error(sa.loc, "static assert:  %s", sa.msg.toChars());
+            error(sa.loc, "static assert:  %s", msgbuf.extractChars());
         }
         else
             error(sa.loc, "static assert:  `%s` is false", sa.exp.toChars());
diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d
index cc75aa51e5a..78da4a15a42 100644
--- a/gcc/d/dmd/semantic3.d
+++ b/gcc/d/dmd/semantic3.d
@@ -1,7 +1,7 @@ 
 /**
  * Performs the semantic3 stage, which deals with function bodies.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/semantic3.d, _semantic3.d)
@@ -47,6 +47,7 @@  import dmd.identifier;
 import dmd.init;
 import dmd.initsem;
 import dmd.hdrgen;
+import dmd.location;
 import dmd.mtype;
 import dmd.nogc;
 import dmd.nspace;
diff --git a/gcc/d/dmd/sideeffect.d b/gcc/d/dmd/sideeffect.d
index f7a3836961c..ed938762bab 100644
--- a/gcc/d/dmd/sideeffect.d
+++ b/gcc/d/dmd/sideeffect.d
@@ -1,7 +1,7 @@ 
 /**
  * Find side-effects of expressions.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/sideeffect.d, _sideeffect.d)
diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d
index 91a802ecdd7..96c59ba219c 100644
--- a/gcc/d/dmd/statement.d
+++ b/gcc/d/dmd/statement.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/statement.html, Statements)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/statement.d, _statement.d)
@@ -36,6 +36,7 @@  import dmd.globals;
 import dmd.hdrgen;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.dinterpret;
 import dmd.mtype;
 import dmd.common.outbuffer;
@@ -323,6 +324,10 @@  extern (C++) abstract class Statement : ASTNode
             override void visit(DefaultStatement s)
             {
             }
+
+            override void visit(LabelStatement s)
+            {
+            }
         }
 
         scope HasCode hc = new HasCode();
diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h
index 681b4816320..76a39912718 100644
--- a/gcc/d/dmd/statement.h
+++ b/gcc/d/dmd/statement.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/statement_rewrite_walker.d b/gcc/d/dmd/statement_rewrite_walker.d
index 7b3a13b40bc..dcdd9630002 100644
--- a/gcc/d/dmd/statement_rewrite_walker.d
+++ b/gcc/d/dmd/statement_rewrite_walker.d
@@ -1,7 +1,7 @@ 
 /**
  * Provides a visitor for statements that allows rewriting the currently visited node.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/statement_rewrite_walker.d, _statement_rewrite_walker.d)
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index b372fc2f5a9..5764efd60fd 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/statement.html, Statements)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/statementsem.d, _statementsem.d)
@@ -50,6 +50,7 @@  import dmd.identifier;
 import dmd.importc;
 import dmd.init;
 import dmd.intrange;
+import dmd.location;
 import dmd.mtype;
 import dmd.mustuse;
 import dmd.nogc;
diff --git a/gcc/d/dmd/staticassert.d b/gcc/d/dmd/staticassert.d
index c7d314808ef..15c46b304ba 100644
--- a/gcc/d/dmd/staticassert.d
+++ b/gcc/d/dmd/staticassert.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/version.html#static-assert, Static Assert)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/staticassert.d, _staticassert.d)
@@ -13,10 +13,12 @@ 
 
 module dmd.staticassert;
 
+import dmd.arraytypes;
 import dmd.dscope;
 import dmd.dsymbol;
 import dmd.expression;
 import dmd.globals;
+import dmd.location;
 import dmd.id;
 import dmd.identifier;
 import dmd.mtype;
@@ -27,19 +29,27 @@  import dmd.visitor;
 extern (C++) final class StaticAssert : Dsymbol
 {
     Expression exp;
-    Expression msg;
+    Expressions* msgs;
 
     extern (D) this(const ref Loc loc, Expression exp, Expression msg)
     {
         super(loc, Id.empty);
         this.exp = exp;
-        this.msg = msg;
+        this.msgs = new Expressions(1);
+        (*this.msgs)[0] = msg;
+    }
+
+    extern (D) this(const ref Loc loc, Expression exp, Expressions* msgs)
+    {
+        super(loc, Id.empty);
+        this.exp = exp;
+        this.msgs = msgs;
     }
 
     override StaticAssert syntaxCopy(Dsymbol s)
     {
         assert(!s);
-        return new StaticAssert(loc, exp.syntaxCopy(), msg ? msg.syntaxCopy() : null);
+        return new StaticAssert(loc, exp.syntaxCopy(), msgs ? Expression.arraySyntaxCopy(msgs) : null);
     }
 
     override void addMember(Scope* sc, ScopeDsymbol sds)
diff --git a/gcc/d/dmd/staticassert.h b/gcc/d/dmd/staticassert.h
index d9389901469..2b7d300f6af 100644
--- a/gcc/d/dmd/staticassert.h
+++ b/gcc/d/dmd/staticassert.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
@@ -18,7 +18,7 @@  class StaticAssert : public Dsymbol
 {
 public:
     Expression *exp;
-    Expression *msg;
+    Expressions *msg;
 
     StaticAssert *syntaxCopy(Dsymbol *s) override;
     void addMember(Scope *sc, ScopeDsymbol *sds) override;
diff --git a/gcc/d/dmd/staticcond.d b/gcc/d/dmd/staticcond.d
index 0cbdd963afa..aa6f37ca67b 100644
--- a/gcc/d/dmd/staticcond.d
+++ b/gcc/d/dmd/staticcond.d
@@ -1,7 +1,7 @@ 
 /**
  * Lazily evaluate static conditions for `static if`, `static assert` and template constraints.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/staticcond.d, _staticcond.d)
diff --git a/gcc/d/dmd/stmtstate.d b/gcc/d/dmd/stmtstate.d
index 3e26b8f9bd5..7b2ea972f0e 100644
--- a/gcc/d/dmd/stmtstate.d
+++ b/gcc/d/dmd/stmtstate.d
@@ -1,7 +1,7 @@ 
 /**
  * Used to help transform statement AST into flow graph.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/stmtstate.d, _stmtstate.d)
diff --git a/gcc/d/dmd/target.d b/gcc/d/dmd/target.d
index eb85c676a4b..fddfd546742 100644
--- a/gcc/d/dmd/target.d
+++ b/gcc/d/dmd/target.d
@@ -15,7 +15,7 @@ 
  * - $(LINK2 https://github.com/ldc-developers/ldc, LDC repository)
  * - $(LINK2 https://github.com/D-Programming-GDC/gcc, GDC repository)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/target.d, _target.d)
@@ -61,7 +61,7 @@  extern (C++) struct Target
     import dmd.dscope : Scope;
     import dmd.expression : Expression;
     import dmd.func : FuncDeclaration;
-    import dmd.globals : Loc;
+    import dmd.location;
     import dmd.astenums : LINK, TY;
     import dmd.mtype : Type, TypeFunction, TypeTuple;
     import dmd.root.ctfloat : real_t;
diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h
index 096c16fd610..ef2c09d4147 100644
--- a/gcc/d/dmd/target.h
+++ b/gcc/d/dmd/target.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 2013-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 2013-2023 by The D Language Foundation, All Rights Reserved
  * written by Iain Buclaw
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h
index 9ad027a8647..8e8ba16c0ab 100644
--- a/gcc/d/dmd/template.h
+++ b/gcc/d/dmd/template.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
@@ -70,7 +70,6 @@  public:
     bool isTrivialAlias;        // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
     bool deprecated_;           // this template declaration is deprecated
     Visibility visibility;
-    int inuse;                  // for recursive expansion detection
 
     TemplatePrevious *previous;         // threaded list of previous instantiation attempts on stack
 
diff --git a/gcc/d/dmd/templateparamsem.d b/gcc/d/dmd/templateparamsem.d
index e79a9ec957e..432daeea5c7 100644
--- a/gcc/d/dmd/templateparamsem.d
+++ b/gcc/d/dmd/templateparamsem.d
@@ -1,7 +1,7 @@ 
 /**
  * Semantic analysis of template parameters.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/templateparamsem.d, _templateparamsem.d)
@@ -16,6 +16,7 @@  import dmd.dsymbol;
 import dmd.dscope;
 import dmd.dtemplate;
 import dmd.globals;
+import dmd.location;
 import dmd.expression;
 import dmd.expressionsem;
 import dmd.root.rootobject;
diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d
index 86abedf7660..b3cd2d3c403 100644
--- a/gcc/d/dmd/tokens.d
+++ b/gcc/d/dmd/tokens.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/lex.html#tokens, Tokens)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/tokens.d, _tokens.d)
@@ -16,8 +16,8 @@  module dmd.tokens;
 import core.stdc.ctype;
 import core.stdc.stdio;
 import core.stdc.string;
-import dmd.globals;
 import dmd.identifier;
+import dmd.location;
 import dmd.root.ctfloat;
 import dmd.common.outbuffer;
 import dmd.root.rmem;
@@ -636,8 +636,8 @@  extern (C++) struct Token
     union
     {
         // Integers
-        sinteger_t intvalue;
-        uinteger_t unsvalue;
+        long intvalue;
+        ulong unsvalue;
         // Floats
         real_t floatvalue;
 
diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h
index 35fd68b0ba5..32ae5f437c4 100644
--- a/gcc/d/dmd/tokens.h
+++ b/gcc/d/dmd/tokens.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d
index a6d2304c38a..048c24f7b22 100644
--- a/gcc/d/dmd/traits.d
+++ b/gcc/d/dmd/traits.d
@@ -3,7 +3,7 @@ 
  *
  * Specification: $(LINK2 https://dlang.org/spec/traits.html, Traits)
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/traits.d, _traits.d)
@@ -38,6 +38,7 @@  import dmd.globals;
 import dmd.hdrgen;
 import dmd.id;
 import dmd.identifier;
+import dmd.location;
 import dmd.mtype;
 import dmd.nogc;
 import dmd.parse;
@@ -88,82 +89,6 @@  private Dsymbol getDsymbolWithoutExpCtx(RootObject oarg)
     return getDsymbol(oarg);
 }
 
-private const StringTable!bool traitsStringTable;
-
-shared static this()
-{
-    static immutable string[] names =
-    [
-        "isAbstractClass",
-        "isArithmetic",
-        "isAssociativeArray",
-        "isDisabled",
-        "isDeprecated",
-        "isFuture",
-        "isFinalClass",
-        "isPOD",
-        "isNested",
-        "isFloating",
-        "isIntegral",
-        "isScalar",
-        "isStaticArray",
-        "isUnsigned",
-        "isVirtualFunction",
-        "isVirtualMethod",
-        "isAbstractFunction",
-        "isFinalFunction",
-        "isOverrideFunction",
-        "isStaticFunction",
-        "isModule",
-        "isPackage",
-        "isRef",
-        "isOut",
-        "isLazy",
-        "isReturnOnStack",
-        "hasMember",
-        "identifier",
-        "getProtection",
-        "getVisibility",
-        "parent",
-        "child",
-        "getLinkage",
-        "getMember",
-        "getOverloads",
-        "getVirtualFunctions",
-        "getVirtualMethods",
-        "classInstanceSize",
-        "classInstanceAlignment",
-        "allMembers",
-        "derivedMembers",
-        "isSame",
-        "compiles",
-        "getAliasThis",
-        "getAttributes",
-        "getFunctionAttributes",
-        "getFunctionVariadicStyle",
-        "getParameterStorageClasses",
-        "getUnitTests",
-        "getVirtualIndex",
-        "getPointerBitmap",
-        "isZeroInit",
-        "getTargetInfo",
-        "getLocation",
-        "hasPostblit",
-        "hasCopyConstructor",
-        "isCopyable",
-        "parameters"
-    ];
-
-    StringTable!(bool)* stringTable = cast(StringTable!(bool)*) &traitsStringTable;
-    stringTable._init(names.length);
-
-    foreach (s; names)
-    {
-        auto sv = stringTable.insert(s, true);
-        assert(sv);
-    }
-}
-
 /**
  * get an array of size_t values that indicate possible pointer words in memory
  *  if interpreted as the type given as argument
@@ -2122,20 +2047,11 @@  Expression semanticTraits(TraitsExp e, Scope* sc)
         auto tup = new TupleExp(e.loc, exps);
         return tup.expressionSemantic(sc);
     }
-    static const(char)[] trait_search_fp(const(char)[] seed, out int cost)
-    {
-        //printf("trait_search_fp('%s')\n", seed);
-        if (!seed.length)
-            return null;
-        cost = 0;       // all the same cost
-        const sv = traitsStringTable.lookup(seed);
-        return sv ? sv.toString() : null;
-    }
 
-    if (auto sub = speller!trait_search_fp(e.ident.toString()))
-        e.error("unrecognized trait `%s`, did you mean `%.*s`?", e.ident.toChars(), cast(int) sub.length, sub.ptr);
-    else
-        e.error("unrecognized trait `%s`", e.ident.toChars());
+    /* Can't find the identifier. Try a spell check for a better error message
+     */
+    traitNotFound(e);
+
     return ErrorExp.get();
 }
 
@@ -2263,3 +2179,108 @@  Lnext:
     }
     return true;
 }
+
+
+/***********************************
+ * A trait was not found. Give a decent error message
+ * by trying a spell check.
+ * Params:
+ *      e = the offending trait
+ */
+private void traitNotFound(TraitsExp e)
+{
+    __gshared const StringTable!bool traitsStringTable;
+    __gshared bool initialized;
+
+    if (!initialized)
+    {
+        initialized = true;     // lazy initialization
+
+        // All possible traits
+        __gshared Identifier*[58] idents =
+        [
+            &Id.isAbstractClass,
+            &Id.isArithmetic,
+            &Id.isAssociativeArray,
+            &Id.isDisabled,
+            &Id.isDeprecated,
+            &Id.isFuture,
+            &Id.isFinalClass,
+            &Id.isPOD,
+            &Id.isNested,
+            &Id.isFloating,
+            &Id.isIntegral,
+            &Id.isScalar,
+            &Id.isStaticArray,
+            &Id.isUnsigned,
+            &Id.isVirtualFunction,
+            &Id.isVirtualMethod,
+            &Id.isAbstractFunction,
+            &Id.isFinalFunction,
+            &Id.isOverrideFunction,
+            &Id.isStaticFunction,
+            &Id.isModule,
+            &Id.isPackage,
+            &Id.isRef,
+            &Id.isOut,
+            &Id.isLazy,
+            &Id.isReturnOnStack,
+            &Id.hasMember,
+            &Id.identifier,
+            &Id.getProtection,
+            &Id.getVisibility,
+            &Id.parent,
+            &Id.child,
+            &Id.getLinkage,
+            &Id.getMember,
+            &Id.getOverloads,
+            &Id.getVirtualFunctions,
+            &Id.getVirtualMethods,
+            &Id.classInstanceSize,
+            &Id.classInstanceAlignment,
+            &Id.allMembers,
+            &Id.derivedMembers,
+            &Id.isSame,
+            &Id.compiles,
+            &Id.getAliasThis,
+            &Id.getAttributes,
+            &Id.getFunctionAttributes,
+            &Id.getFunctionVariadicStyle,
+            &Id.getParameterStorageClasses,
+            &Id.getUnitTests,
+            &Id.getVirtualIndex,
+            &Id.getPointerBitmap,
+            &Id.isZeroInit,
+            &Id.getTargetInfo,
+            &Id.getLocation,
+            &Id.hasPostblit,
+            &Id.hasCopyConstructor,
+            &Id.isCopyable,
+            &Id.parameters,
+        ];
+
+        StringTable!(bool)* stringTable = cast(StringTable!(bool)*) &traitsStringTable;
+        stringTable._init(idents.length);
+
+        foreach (id; idents)
+        {
+            auto sv = stringTable.insert((*id).toString(), true);
+            assert(sv);
+        }
+    }
+
+    static const(char)[] trait_search_fp(const(char)[] seed, out int cost)
+    {
+        //printf("trait_search_fp('%s')\n", seed);
+        if (!seed.length)
+            return null;
+        cost = 0;       // all the same cost
+        const sv = traitsStringTable.lookup(seed);
+        return sv ? sv.toString() : null;
+    }
+
+    if (auto sub = speller!trait_search_fp(e.ident.toString()))
+        e.error("unrecognized trait `%s`, did you mean `%.*s`?", e.ident.toChars(), cast(int) sub.length, sub.ptr);
+    else
+        e.error("unrecognized trait `%s`", e.ident.toChars());
+}
diff --git a/gcc/d/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d
index 7aaf0b87268..5844911bc6a 100644
--- a/gcc/d/dmd/transitivevisitor.d
+++ b/gcc/d/dmd/transitivevisitor.d
@@ -490,8 +490,9 @@  package mixin template ParseVisitMethods(AST)
     {
         //printf("Visiting StaticAssert\n");
         s.exp.accept(this);
-        if (s.msg)
-            s.msg.accept(this);
+        if (s.msgs)
+            foreach (m; (*s.msgs)[])
+                m.accept(this);
     }
 
     override void visit(AST.EnumMember em)
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index a75b4165cc3..0d64ba46a50 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -1,7 +1,7 @@ 
 /**
  * Semantic analysis for D types.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/typesem.d, _typesem.d)
@@ -46,6 +46,7 @@  import dmd.imphint;
 import dmd.importc;
 import dmd.init;
 import dmd.initsem;
+import dmd.location;
 import dmd.visitor;
 import dmd.mtype;
 import dmd.objc;
@@ -234,7 +235,7 @@  private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb
                 .error(loc, "`%s` is not visible from module `%s`", sm.toPrettyChars(), sc._module.toChars());
                 sm = null;
             }
-            // Same check as in Expression.semanticY(DotIdExp)
+            // Same check as in dotIdSemanticProp(DotIdExp)
             else if (sm.isPackage() && checkAccess(sc, sm.isPackage()))
             {
                 // @@@DEPRECATED_2.106@@@
@@ -3685,7 +3686,7 @@  Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag)
                  *  template opDispatch(name) if (isValid!name) { ... }
                  */
                 uint errors = gagError ? global.startGagging() : 0;
-                e = dti.semanticY(sc, 0);
+                e = dti.dotTemplateSemanticProp(sc, 0);
                 if (gagError && global.endGagging(errors))
                     e = null;
                 return returnExp(e);
@@ -3703,7 +3704,7 @@  Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag)
                 auto die = new DotIdExp(e.loc, alias_e, ident);
 
                 auto errors = gagError ? 0 : global.startGagging();
-                auto exp = die.semanticY(sc, gagError);
+                auto exp = die.dotIdSemanticProp(sc, gagError);
                 if (!gagError)
                 {
                     global.endGagging(errors);
@@ -3959,7 +3960,14 @@  Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag)
         Dsymbol s = mt.sym.search(e.loc, ident);
         if (!s)
         {
-            if (ident == Id.max || ident == Id.min || ident == Id._init)
+            if (ident == Id._init)
+            {
+                return mt.getProperty(sc, e.loc, ident, flag & 1);
+            }
+
+            /* Allow special enums to not need a member list
+             */
+            if ((ident == Id.max || ident == Id.min) && (mt.sym.members || !mt.sym.isSpecial()))
             {
                 return mt.getProperty(sc, e.loc, ident, flag & 1);
             }
@@ -4880,13 +4888,6 @@  Expression getMaxMinValue(EnumDeclaration ed, const ref Loc loc, Identifier id)
         return errorReturn();
     if (!ed.members)
     {
-        if (ed.isSpecial())
-        {
-            /* Allow these special enums to not need a member list
-             */
-            return ed.memtype.getProperty(ed._scope, loc, id, 0);
-        }
-
         ed.error(loc, "is opaque and has no `.%s`", id.toChars());
         return errorReturn();
     }
diff --git a/gcc/d/dmd/typinf.d b/gcc/d/dmd/typinf.d
index b701be38e42..b35e03de91f 100644
--- a/gcc/d/dmd/typinf.d
+++ b/gcc/d/dmd/typinf.d
@@ -1,7 +1,7 @@ 
 /**
  * Generate `TypeInfo` objects, which are needed for run-time introspection of types.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/typeinf.d, _typeinf.d)
@@ -21,6 +21,7 @@  import dmd.errors;
 import dmd.expression;
 import dmd.globals;
 import dmd.gluelayer;
+import dmd.location;
 import dmd.mtype;
 import dmd.visitor;
 import core.stdc.stdio;
diff --git a/gcc/d/dmd/utils.d b/gcc/d/dmd/utils.d
index 5be4a196345..dfb4cb5ee2d 100644
--- a/gcc/d/dmd/utils.d
+++ b/gcc/d/dmd/utils.d
@@ -1,7 +1,7 @@ 
 /**
  * This module defines some utility functions for DMD.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/utils.d, _utils.d)
@@ -13,7 +13,7 @@  module dmd.utils;
 
 import core.stdc.string;
 import dmd.errors;
-import dmd.globals;
+import dmd.location;
 import dmd.root.file;
 import dmd.root.filename;
 import dmd.common.outbuffer;
diff --git a/gcc/d/dmd/version.h b/gcc/d/dmd/version.h
index b76393bc1ec..697d46ee211 100644
--- a/gcc/d/dmd/version.h
+++ b/gcc/d/dmd/version.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * written by Walter Bright
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
diff --git a/gcc/d/dmd/visitor.d b/gcc/d/dmd/visitor.d
index e6dfa1173cf..e4c2a91e7f7 100644
--- a/gcc/d/dmd/visitor.d
+++ b/gcc/d/dmd/visitor.d
@@ -1,7 +1,7 @@ 
 /**
  * Provides a visitor class visiting all AST nodes present in the compiler.
  *
- * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/visitor.d, _visitor.d)
diff --git a/gcc/d/dmd/visitor.h b/gcc/d/dmd/visitor.h
index b45ef790de3..f8cbdb48c92 100644
--- a/gcc/d/dmd/visitor.h
+++ b/gcc/d/dmd/visitor.h
@@ -1,6 +1,6 @@ 
 
 /* Compiler implementation of the D programming language
- * Copyright (C) 2013-2022 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 2013-2023 by The D Language Foundation, All Rights Reserved
  * https://www.digitalmars.com
  * Distributed under the Boost Software License, Version 1.0.
  * https://www.boost.org/LICENSE_1_0.txt
diff --git a/gcc/testsuite/gdc.dg/simd2a.d b/gcc/testsuite/gdc.dg/simd2a.d
index d64f704683f..373d5d1e229 100644
--- a/gcc/testsuite/gdc.dg/simd2a.d
+++ b/gcc/testsuite/gdc.dg/simd2a.d
@@ -18,12 +18,12 @@  void test2a()
     static assert(!__traits(compiles, v1 ^^ v2));
     static assert(!__traits(compiles, v1 is v2));
     static assert(!__traits(compiles, v1 !is v2));
-    v1 = v1 == v2;
-    v1 = v1 != v2;
-    v1 = v1 < v2;
-    v1 = v1 > v2;
-    v1 = v1 <= v2;
-    v1 = v1 >= v2;
+    static assert( __traits(compiles, v1 == v2));
+    static assert( __traits(compiles, v1 != v2));
+    static assert( __traits(compiles, v1 < v2));
+    static assert( __traits(compiles, v1 > v2));
+    static assert( __traits(compiles, v1 <= v2));
+    static assert( __traits(compiles, v1 >= v2));
     v1 = v2 << 1;
     v1 = v2 >> 1;
     v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2b.d b/gcc/testsuite/gdc.dg/simd2b.d
index 71abd78b301..e72da0d9b77 100644
--- a/gcc/testsuite/gdc.dg/simd2b.d
+++ b/gcc/testsuite/gdc.dg/simd2b.d
@@ -18,12 +18,12 @@  void test2b()
     static assert(!__traits(compiles, v1 ^^ v2));
     static assert(!__traits(compiles, v1 is v2));
     static assert(!__traits(compiles, v1 !is v2));
-    v1 = v1 == v2;
-    v1 = v1 != v2;
-    v1 = v1 < v2;
-    v1 = v1 > v2;
-    v1 = v1 <= v2;
-    v1 = v1 >= v2;
+    static assert( __traits(compiles, v1 == v2));
+    static assert( __traits(compiles, v1 != v2));
+    static assert( __traits(compiles, v1 < v2));
+    static assert( __traits(compiles, v1 > v2));
+    static assert( __traits(compiles, v1 <= v2));
+    static assert( __traits(compiles, v1 >= v2));
     v1 = v2 << 1;
     v1 = v2 >> 1;
     v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2c.d b/gcc/testsuite/gdc.dg/simd2c.d
index 4806b48029f..dc4954e2194 100644
--- a/gcc/testsuite/gdc.dg/simd2c.d
+++ b/gcc/testsuite/gdc.dg/simd2c.d
@@ -18,12 +18,12 @@  void test2c()
     static assert(!__traits(compiles, v1 ^^ v2));
     static assert(!__traits(compiles, v1 is v2));
     static assert(!__traits(compiles, v1 !is v2));
-    v1 = v1 == v2;
-    v1 = v1 != v2;
-    v1 = v1 < v2;
-    v1 = v1 > v2;
-    v1 = v1 <= v2;
-    v1 = v1 >= v2;
+    static assert( __traits(compiles, v1 == v2));
+    static assert( __traits(compiles, v1 != v2));
+    static assert( __traits(compiles, v1 < v2));
+    static assert( __traits(compiles, v1 > v2));
+    static assert( __traits(compiles, v1 <= v2));
+    static assert( __traits(compiles, v1 >= v2));
     v1 = v2 << 1;
     v1 = v2 >> 1;
     v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2d.d b/gcc/testsuite/gdc.dg/simd2d.d
index ce447e180e8..2d782bac89c 100644
--- a/gcc/testsuite/gdc.dg/simd2d.d
+++ b/gcc/testsuite/gdc.dg/simd2d.d
@@ -18,12 +18,12 @@  void test2d()
     static assert(!__traits(compiles, v1 ^^ v2));
     static assert(!__traits(compiles, v1 is v2));
     static assert(!__traits(compiles, v1 !is v2));
-    v1 = v1 == v2;
-    v1 = v1 != v2;
-    v1 = v1 < v2;
-    v1 = v1 > v2;
-    v1 = v1 <= v2;
-    v1 = v1 >= v2;
+    static assert( __traits(compiles, v1 == v2));
+    static assert( __traits(compiles, v1 != v2));
+    static assert( __traits(compiles, v1 < v2));
+    static assert( __traits(compiles, v1 > v2));
+    static assert( __traits(compiles, v1 <= v2));
+    static assert( __traits(compiles, v1 >= v2));
     v1 = v2 << 1;
     v1 = v2 >> 1;
     v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2e.d b/gcc/testsuite/gdc.dg/simd2e.d
index 464d1a51a5e..b6d4ed6ef3a 100644
--- a/gcc/testsuite/gdc.dg/simd2e.d
+++ b/gcc/testsuite/gdc.dg/simd2e.d
@@ -18,12 +18,12 @@  void test2e()
     static assert(!__traits(compiles, v1 ^^ v2));
     static assert(!__traits(compiles, v1 is v2));
     static assert(!__traits(compiles, v1 !is v2));
-    v1 = v1 == v2;
-    v1 = v1 != v2;
-    v1 = v1 < v2;
-    v1 = v1 > v2;
-    v1 = v1 <= v2;
-    v1 = v1 >= v2;
+    static assert( __traits(compiles, v1 == v2));
+    static assert( __traits(compiles, v1 != v2));
+    static assert( __traits(compiles, v1 < v2));
+    static assert( __traits(compiles, v1 > v2));
+    static assert( __traits(compiles, v1 <= v2));
+    static assert( __traits(compiles, v1 >= v2));
     v1 = v2 << 1;
     v1 = v2 >> 1;
     v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2f.d b/gcc/testsuite/gdc.dg/simd2f.d
index d7e67fc4112..df8f13fddd1 100644
--- a/gcc/testsuite/gdc.dg/simd2f.d
+++ b/gcc/testsuite/gdc.dg/simd2f.d
@@ -18,12 +18,12 @@  void test2f()
     static assert(!__traits(compiles, v1 ^^ v2));
     static assert(!__traits(compiles, v1 is v2));
     static assert(!__traits(compiles, v1 !is v2));
-    v1 = v1 == v2;
-    v1 = v1 != v2;
-    v1 = v1 < v2;
-    v1 = v1 > v2;
-    v1 = v1 <= v2;
-    v1 = v1 >= v2;
+    static assert( __traits(compiles, v1 == v2));
+    static assert( __traits(compiles, v1 != v2));
+    static assert( __traits(compiles, v1 < v2));
+    static assert( __traits(compiles, v1 > v2));
+    static assert( __traits(compiles, v1 <= v2));
+    static assert( __traits(compiles, v1 >= v2));
     v1 = v2 << 1;
     v1 = v2 >> 1;
     v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2g.d b/gcc/testsuite/gdc.dg/simd2g.d
index 3d158691abb..028b25e7d17 100644
--- a/gcc/testsuite/gdc.dg/simd2g.d
+++ b/gcc/testsuite/gdc.dg/simd2g.d
@@ -18,12 +18,12 @@  void test2g()
     static assert(!__traits(compiles, v1 ^^ v2));
     static assert(!__traits(compiles, v1 is v2));
     static assert(!__traits(compiles, v1 !is v2));
-    v1 = v1 == v2;
-    v1 = v1 != v2;
-    v1 = v1 < v2;
-    v1 = v1 > v2;
-    v1 = v1 <= v2;
-    v1 = v1 >= v2;
+    static assert( __traits(compiles, v1 == v2));
+    static assert( __traits(compiles, v1 != v2));
+    static assert( __traits(compiles, v1 < v2));
+    static assert( __traits(compiles, v1 > v2));
+    static assert( __traits(compiles, v1 <= v2));
+    static assert( __traits(compiles, v1 >= v2));
     v1 = v2 << 1;
     v1 = v2 >> 1;
     v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2h.d b/gcc/testsuite/gdc.dg/simd2h.d
index 849b6adc626..6c3e91a8814 100644
--- a/gcc/testsuite/gdc.dg/simd2h.d
+++ b/gcc/testsuite/gdc.dg/simd2h.d
@@ -18,12 +18,12 @@  void test2h()
     static assert(!__traits(compiles, v1 ^^ v2));
     static assert(!__traits(compiles, v1 is v2));
     static assert(!__traits(compiles, v1 !is v2));
-    v1 = v1 == v2;
-    v1 = v1 != v2;
-    v1 = v1 < v2;
-    v1 = v1 > v2;
-    v1 = v1 <= v2;
-    v1 = v1 >= v2;
+    static assert( __traits(compiles, v1 == v2));
+    static assert( __traits(compiles, v1 != v2));
+    static assert( __traits(compiles, v1 < v2));
+    static assert( __traits(compiles, v1 > v2));
+    static assert( __traits(compiles, v1 <= v2));
+    static assert( __traits(compiles, v1 >= v2));
     v1 = v2 << 1;
     v1 = v2 >> 1;
     v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2i.d b/gcc/testsuite/gdc.dg/simd2i.d
index 03130b7a663..2fa7f3ad86e 100644
--- a/gcc/testsuite/gdc.dg/simd2i.d
+++ b/gcc/testsuite/gdc.dg/simd2i.d
@@ -18,12 +18,12 @@  void test2i()
     static assert(!__traits(compiles, v1 ^^ v2));
     static assert(!__traits(compiles, v1 is v2));
     static assert(!__traits(compiles, v1 !is v2));
-    v1 = v1 == v2;
-    v1 = v1 != v2;
-    v1 = v1 < v2;
-    v1 = v1 > v2;
-    v1 = v1 <= v2;
-    v1 = v1 >= v2;
+    static assert( __traits(compiles, v1 == v2));
+    static assert( __traits(compiles, v1 != v2));
+    static assert( __traits(compiles, v1 < v2));
+    static assert( __traits(compiles, v1 > v2));
+    static assert( __traits(compiles, v1 <= v2));
+    static assert( __traits(compiles, v1 >= v2));
     static assert(!__traits(compiles, v1 << 1));
     static assert(!__traits(compiles, v1 >> 1));
     static assert(!__traits(compiles, v1 >>> 1));
diff --git a/gcc/testsuite/gdc.dg/simd2j.d b/gcc/testsuite/gdc.dg/simd2j.d
index f86a448f138..7c2d12f33cf 100644
--- a/gcc/testsuite/gdc.dg/simd2j.d
+++ b/gcc/testsuite/gdc.dg/simd2j.d
@@ -18,12 +18,12 @@  void test2j()
     static assert(!__traits(compiles, v1 ^^ v2));
     static assert(!__traits(compiles, v1 is v2));
     static assert(!__traits(compiles, v1 !is v2));
-    v1 = v1 == v2;
-    v1 = v1 != v2;
-    v1 = v1 < v2;
-    v1 = v1 > v2;
-    v1 = v1 <= v2;
-    v1 = v1 >= v2;
+    static assert( __traits(compiles, v1 == v2));
+    static assert( __traits(compiles, v1 != v2));
+    static assert( __traits(compiles, v1 < v2));
+    static assert( __traits(compiles, v1 > v2));
+    static assert( __traits(compiles, v1 <= v2));
+    static assert( __traits(compiles, v1 >= v2));
     static assert(!__traits(compiles, v1 << 1));
     static assert(!__traits(compiles, v1 >> 1));
     static assert(!__traits(compiles, v1 >>> 1));
diff --git a/gcc/testsuite/gdc.test/compilable/extra-files/build23499.d b/gcc/testsuite/gdc.test/compilable/extra-files/build23499.d
new file mode 100644
index 00000000000..1983b4acdd2
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/extra-files/build23499.d
@@ -0,0 +1,7 @@ 
+import imports.file23499;
+
+bool do_build()
+{
+    string outdir ;
+    return (exists(outdir));
+}
diff --git a/gcc/testsuite/gdc.test/compilable/imports/file23499.d b/gcc/testsuite/gdc.test/compilable/imports/file23499.d
new file mode 100644
index 00000000000..76e1b781ac1
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/file23499.d
@@ -0,0 +1,19 @@ 
+
+///---- file.d
+struct TempCStringBuffer(To )
+{
+    ~this()
+    {
+    }
+    To* _ptr;
+}
+
+auto tempCString(To, From)(From)
+{
+    return TempCStringBuffer!To();
+}
+
+bool exists(R)(R name)
+{
+    return name.tempCString!wchar._ptr != null;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/imports/test23490frop.d b/gcc/testsuite/gdc.test/compilable/imports/test23490frop.d
new file mode 100644
index 00000000000..13fc78fc10e
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/test23490frop.d
@@ -0,0 +1,7 @@ 
+module imports.test23490frop;
+import imports.test23490pop;
+class Mu23490 : Pop23490 { }
+class Frop23490 : Pop23490 {
+  // final       // does not fail if declared final
+  void frolick() {}
+}
diff --git a/gcc/testsuite/gdc.test/compilable/imports/test23490pop.d b/gcc/testsuite/gdc.test/compilable/imports/test23490pop.d
new file mode 100644
index 00000000000..4757bbd0208
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/test23490pop.d
@@ -0,0 +1,7 @@ 
+module imports.test23490pop;
+import imports.test23490frop;
+import imports.test23490zoo : Zoo23490;
+class Pop23490 {
+  void frop(Frop23490) { }
+  void zoo(Zoo23490) { }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/imports/test23490zoo.d b/gcc/testsuite/gdc.test/compilable/imports/test23490zoo.d
new file mode 100644
index 00000000000..7ae8b97d7c6
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/test23490zoo.d
@@ -0,0 +1,17 @@ 
+module imports.test23490zoo;
+import imports.test23490pop;
+import imports.test23490frop;
+class Foo23490() : Pop23490 {
+  override void frop(Frop23490 f) {
+    f.frolick;
+  }
+}
+class Baz23490 {
+  Foo23490!() foo;
+  Frop23490 frop;
+}
+class Bar23490 {
+  static instance() { return new Baz23490; }
+  auto ss = __traits(getAttributes, instance.frop);
+}
+class Zoo23490 { }
diff --git a/gcc/testsuite/gdc.test/compilable/isexpalias.d b/gcc/testsuite/gdc.test/compilable/isexpalias.d
new file mode 100644
index 00000000000..5cd8d8ecfc5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/isexpalias.d
@@ -0,0 +1,9 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23578
+struct S(alias a)
+{
+}
+
+static if (is(S!int == S!av, alias av))
+    static assert(is(av == int));
+else
+    static assert(false);
diff --git a/gcc/testsuite/gdc.test/compilable/issue20618.d b/gcc/testsuite/gdc.test/compilable/issue20618.d
new file mode 100644
index 00000000000..0cc90cff661
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/issue20618.d
@@ -0,0 +1,10 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22198
+// This test was in fail_compilation, however the change in the compiler has
+// been reverted to make this code compilable again.
+void main()
+{
+    int[10] a;
+    auto b = a[1..12];
+    auto c = a[4..3];
+    auto d = a[0..$ + 1];
+}
diff --git a/gcc/testsuite/gdc.test/compilable/issue22646.d b/gcc/testsuite/gdc.test/compilable/issue22646.d
new file mode 100644
index 00000000000..88a3b60cdab
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/issue22646.d
@@ -0,0 +1,67 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22646
+
+static template logicalOr22646(T, const T name)
+{
+    enum bool ok = name.length < 3 || name[0..3] != "pad";
+}
+static template logicalAnd22646(T, const T name)
+{
+    enum bool ok = name.length >= 3 && name[0..3] == "pad";
+}
+
+bool runtime22646Or(T, const T name)()
+{
+    return name.length < 3 || name[0..3] != "pad";
+}
+
+// SCOPE.ctfe
+static assert(logicalOr22646!(string, "x").ok == true);
+static assert(logicalOr22646!(string, "foo").ok == true);
+static assert(logicalOr22646!(string, "pad").ok == false);
+static assert(logicalOr22646!(string, "pad123").ok == false);
+
+static assert(logicalOr22646!(char[1], "x").ok == true);
+static assert(logicalOr22646!(char[3], "foo").ok == true);
+static assert(logicalOr22646!(char[3], "pad").ok == false);
+static assert(logicalOr22646!(char[6], "pad123").ok == false);
+
+static assert(logicalAnd22646!(string, "x").ok == false);
+static assert(logicalAnd22646!(string, "foo").ok == false);
+static assert(logicalAnd22646!(string, "pad").ok == true);
+static assert(logicalAnd22646!(string, "pad123").ok == true);
+
+static assert(logicalAnd22646!(char[1], "x").ok == false);
+static assert(logicalAnd22646!(char[3], "foo").ok == false);
+static assert(logicalAnd22646!(char[3], "pad").ok == true);
+static assert(logicalAnd22646!(char[6], "pad123").ok == true);
+
+// SCOPE.compile
+enum char[1] x22646 = "x";
+enum char[3] pad22646 = "pad";
+
+static assert(__traits(compiles, x22646.length < 3 || x22646[0..3] != "pad") == true);
+static assert(__traits(compiles, x22646.length >= 3 || x22646[0..3] == "pad") == true);
+static assert(__traits(compiles, pad22646.length < 3 || pad22646[0..3] != "pad") == true);
+static assert(__traits(compiles, pad22646.length >= 3 || pad22646[0..3] == "pad") == true);
+
+// sc.intypeof
+typeof(x22646.length < 3 || x22646[0..3] != "pad") typeof22646or1;
+static assert(is(typeof(typeof22646or1) == bool));
+typeof(pad22646.length < 3 || pad22646[0..3] != "pad") typeof22646or2;
+static assert(is(typeof(typeof22646or2) == bool));
+
+typeof(x22646.length >= 3 && x22646[0..3] == "pad") typeof22646and1;
+static assert(is(typeof(typeof22646and1) == bool));
+typeof(pad22646.length >= 3 && pad22646[0..3] == "pad") typeof22646and2;
+static assert(is(typeof(typeof22646and2) == bool));
+
+// No SCOPE flags
+alias test22646a = runtime22646Or!(string, "x");
+alias test22646b = runtime22646Or!(string, "foo");
+alias test22646c = runtime22646Or!(string, "pad");
+alias test22646d = runtime22646Or!(string, "pad123");
+
+alias test22646e = runtime22646Or!(char[1], "x");
+alias test22646f = runtime22646Or!(char[3], "foo");
+alias test22646g = runtime22646Or!(char[3], "pad");
+alias test22646h = runtime22646Or!(char[6], "pad123");
diff --git a/gcc/testsuite/gdc.test/compilable/issue22854.d b/gcc/testsuite/gdc.test/compilable/issue22854.d
new file mode 100644
index 00000000000..4d5a518853f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/issue22854.d
@@ -0,0 +1,20 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22854
+void test22854()
+{
+    static foreach (ch; SomeContainer().range) { }
+}
+
+struct SomeContainer
+{
+    SomeRange range() { return SomeRange(); }
+    TypeWithDestructor data;
+}
+
+struct TypeWithDestructor { ~this() { } }
+
+struct SomeRange
+{
+    int front() { return 0; }
+    bool empty() { return true; }
+    void popFront() { }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/issue22975.d b/gcc/testsuite/gdc.test/compilable/issue22975.d
new file mode 100644
index 00000000000..02b59aa71c0
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/issue22975.d
@@ -0,0 +1,12 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22975
+void test22975a(int) {};
+
+alias test22975b = test22975a;
+
+void test22975b(bool) {}
+
+alias test22975c = test22975b;
+
+alias test22975a = test22975c;
+
+void test22975c(float) {}
diff --git a/gcc/testsuite/gdc.test/compilable/issue23391.d b/gcc/testsuite/gdc.test/compilable/issue23391.d
new file mode 100644
index 00000000000..d33242ded3b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/issue23391.d
@@ -0,0 +1,31 @@ 
+struct MyTuple {
+    string s;
+}
+
+inout(string) myfront(inout(string)[] a)
+{
+    return a[0];
+}
+
+MyTuple[] myarray(MyZip r)
+{
+    MyTuple[] result;
+    foreach (e; r)
+        result ~= e;
+    return result;
+}
+
+struct MyZip
+{
+    bool empty = false;
+    MyTuple front()
+    {
+        return MyTuple([""].myfront);
+    }
+    void popFront()
+    {
+        empty = true;
+    }
+}
+
+static foreach(t; MyZip().myarray) {}
diff --git a/gcc/testsuite/gdc.test/compilable/issue23567.d b/gcc/testsuite/gdc.test/compilable/issue23567.d
new file mode 100644
index 00000000000..9c0406b81ed
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/issue23567.d
@@ -0,0 +1,9 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23567
+extern(C++) abstract class CCvar
+{
+public:
+    pragma(printf) void func1(const(char)* pFormat, ...);
+    pragma(printf) void func2(const(char)* pFormat, ...);
+}
+
+static assert(__traits(getVirtualIndex, CCvar.func2) == 1);
diff --git a/gcc/testsuite/gdc.test/compilable/noreturn1.d b/gcc/testsuite/gdc.test/compilable/noreturn1.d
index e648a56d896..daf194d034c 100644
--- a/gcc/testsuite/gdc.test/compilable/noreturn1.d
+++ b/gcc/testsuite/gdc.test/compilable/noreturn1.d
@@ -150,3 +150,14 @@  void noreturnImplicit()
         auto y = (throw new Exception("wow")) + value;
     }
 }
+
+// https://issues.dlang.org/show_bug.cgi?id=23549
+int foo(int g = assert(0)) {
+    return g;
+}
+
+// https://issues.dlang.org/show_bug.cgi?id=22587
+int front(int param)
+{
+    return param ? 1 : assert(0);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/noreturn3.d b/gcc/testsuite/gdc.test/compilable/noreturn3.d
index 737125d1322..69689d24d85 100644
--- a/gcc/testsuite/gdc.test/compilable/noreturn3.d
+++ b/gcc/testsuite/gdc.test/compilable/noreturn3.d
@@ -245,13 +245,3 @@  struct S22858
 static assert (S22858.arr.offsetof % size_t.sizeof == 0);
 static assert (S22858.arr2.offsetof == S22858.c.offsetof + 1);
 static assert (S22858.arr2.offsetof == S22858.c2.offsetof);
-
-// https://issues.dlang.org/show_bug.cgi?id=23331
-
-auto fun() { return double(new noreturn[](0)[0]); }
-auto gun() { return double(assert(0)); }
-auto hun() { return int(assert(0)); }
-
-// https://issues.dlang.org/show_bug.cgi?id=23379
-
-void casting_noreturn() { auto b = cast(double)(assert(0)); }
diff --git a/gcc/testsuite/gdc.test/compilable/test18646.d b/gcc/testsuite/gdc.test/compilable/test18646.d
new file mode 100644
index 00000000000..a9d62a1ebaa
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test18646.d
@@ -0,0 +1,14 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=18646
+class SuperClass {}
+
+class TemplatedClass(T : SuperClass) {}
+
+class A18646 : SuperClass {
+    alias T = TemplatedClass!B18646;
+}
+
+class B18646 : SuperClass {
+    alias T = TemplatedClass!C18646;
+}
+
+class C18646 : SuperClass {}
diff --git a/gcc/testsuite/gdc.test/compilable/test19585.d b/gcc/testsuite/gdc.test/compilable/test19585.d
new file mode 100644
index 00000000000..a84a7ee3cd6
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test19585.d
@@ -0,0 +1,10 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=19585
+struct S19585
+{
+    M2 stdin;
+}
+
+mixin template Handle(T, T invalid_value = T.init) {}
+
+struct M1 { mixin Handle!(size_t); }
+struct M2 { mixin Handle!(M1); }
diff --git a/gcc/testsuite/gdc.test/compilable/test22638.d b/gcc/testsuite/gdc.test/compilable/test22638.d
new file mode 100644
index 00000000000..d7b5fdf1a9d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22638.d
@@ -0,0 +1,15 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22638
+
+struct S
+{
+    this(ref const(S));
+    ~this();
+}
+
+extern(C++) void set(const S s);
+
+void disp()
+{
+    S p;
+    return set(p);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test22813.d b/gcc/testsuite/gdc.test/compilable/test22813.d
new file mode 100644
index 00000000000..7cdd5345b99
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22813.d
@@ -0,0 +1,9 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22813
+struct Template(int i) { }
+uint test22813()
+{
+    Template!(1) x;
+    return 0;
+}
+immutable constant = test22813();
+alias X = Template!constant;
diff --git a/gcc/testsuite/gdc.test/compilable/test23481.d b/gcc/testsuite/gdc.test/compilable/test23481.d
new file mode 100644
index 00000000000..7c03e824bc6
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23481.d
@@ -0,0 +1,28 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23481
+
+struct flagenum(I = ubyte)
+{
+	I i = 1;
+    alias i this;
+
+	auto opBinary(string s)(int j) {
+		return typeof(this)(cast(I)(i*2));
+	}
+	auto opEquals(I a) {
+		return false;
+	}
+}
+
+enum alphakey
+{
+    a = flagenum!int(), b, c, d, e, f, g, h, i, j, k, l,
+    m, n, o, p, q, r, s, t, u, v, w, x, y, z
+}
+
+flagenum!int alpha;
+
+void main()
+{
+	alpha &= alphakey.a;
+    alpha = alpha & alphakey.a; // also crashed in another way
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23490.d b/gcc/testsuite/gdc.test/compilable/test23490.d
new file mode 100644
index 00000000000..0d61a092cac
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23490.d
@@ -0,0 +1,3 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23490
+// EXTRA_FILES: imports/test23490frop.d imports/test23490pop.d imports/test23490zoo.d
+import imports.test23490pop;
diff --git a/gcc/testsuite/gdc.test/compilable/test23497.d b/gcc/testsuite/gdc.test/compilable/test23497.d
new file mode 100644
index 00000000000..7a13c042fdc
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23497.d
@@ -0,0 +1,19 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23497
+
+class A {}
+
+A getA(T t) {
+    return t.a;
+}
+
+struct T {
+    A _a;
+
+    void k() {}
+
+    auto a() in {
+        k();
+    } do {
+        return _a;
+    }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23499.d b/gcc/testsuite/gdc.test/compilable/test23499.d
new file mode 100644
index 00000000000..12e3f25b225
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23499.d
@@ -0,0 +1,6 @@ 
+// REQUIRED_ARGS: -inline
+// EXTRA_SOURCES: extra-files/build23499.d
+// EXTRA_FILES: imports/file23499.d
+// https://issues.dlang.org/show_bug.cgi?id=23499
+
+import imports.file23499;
diff --git a/gcc/testsuite/gdc.test/compilable/test23529.d b/gcc/testsuite/gdc.test/compilable/test23529.d
new file mode 100644
index 00000000000..712c284bb11
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23529.d
@@ -0,0 +1,6 @@ 
+static assert(!__traits(compiles, ()
+{
+    char[24] x;
+    int myNumber = 4;
+    return cast(char[4]) (x[myNumber .. myNumber + 4]);
+} ()));
diff --git a/gcc/testsuite/gdc.test/compilable/test23532.d b/gcc/testsuite/gdc.test/compilable/test23532.d
new file mode 100644
index 00000000000..db6bbe749d3
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23532.d
@@ -0,0 +1,67 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23532
+// DISABLED: win32 win64
+struct _Complex(T)
+{
+    T re;
+    T im;
+    static @property epsilon()()    { return _Complex(T.epsilon, T.epsilon); }
+    static @property infinity()()   { return _Complex(T.infinity, T.infinity); }
+    static @property max()()        { return _Complex(T.max, T.max); }
+    static @property min_normal()() { return _Complex(T.min_normal, T.min_normal); }
+    static @property nan()()        { return _Complex(T.nan, T.nan); }
+    static @property dig()()        { return T.dig; }
+    static @property mant_dig()()   { return T.mant_dig; }
+    static @property max_10_exp()() { return T.max_10_exp; }
+    static @property max_exp()()    { return T.max_exp; }
+    static @property min_10_exp()() { return T.min_10_exp; }
+    static @property min_exp()()    { return T.min_exp; }
+}
+
+enum __c_complex_float  : _Complex!float;
+enum __c_complex_double : _Complex!double;
+enum __c_complex_real   : _Complex!real;
+
+static assert(__c_complex_float.epsilon is _Complex!float.epsilon);
+static assert(__c_complex_float.infinity is _Complex!float.infinity);
+static assert(__c_complex_float.init is _Complex!float.init);
+static assert(__c_complex_float.max is _Complex!float.max);
+static assert(__c_complex_float.min_normal is _Complex!float.min_normal);
+static assert(__c_complex_float.nan is _Complex!float.nan);
+static assert(__c_complex_float.sizeof == _Complex!float.sizeof);
+static assert(__c_complex_float.alignof == _Complex!float.alignof);
+static assert(__c_complex_float.dig == _Complex!float.dig);
+static assert(__c_complex_float.mant_dig == _Complex!float.mant_dig);
+static assert(__c_complex_float.max_10_exp == _Complex!float.max_10_exp);
+static assert(__c_complex_float.max_exp == _Complex!float.max_exp);
+static assert(__c_complex_float.min_10_exp == _Complex!float.min_10_exp);
+static assert(__c_complex_float.min_exp == _Complex!float.min_exp);
+
+static assert(__c_complex_double.epsilon is _Complex!double.epsilon);
+static assert(__c_complex_double.infinity is _Complex!double.infinity);
+static assert(__c_complex_double.init is _Complex!double.init);
+static assert(__c_complex_double.max is _Complex!double.max);
+static assert(__c_complex_double.min_normal is _Complex!double.min_normal);
+static assert(__c_complex_double.nan is _Complex!double.nan);
+static assert(__c_complex_double.sizeof == _Complex!double.sizeof);
+static assert(__c_complex_double.alignof == _Complex!double.alignof);
+static assert(__c_complex_double.dig == _Complex!double.dig);
+static assert(__c_complex_double.mant_dig == _Complex!double.mant_dig);
+static assert(__c_complex_double.max_10_exp == _Complex!double.max_10_exp);
+static assert(__c_complex_double.max_exp == _Complex!double.max_exp);
+static assert(__c_complex_double.min_10_exp == _Complex!double.min_10_exp);
+static assert(__c_complex_double.min_exp == _Complex!double.min_exp);
+
+static assert(__c_complex_real.epsilon is _Complex!real.epsilon);
+static assert(__c_complex_real.infinity is _Complex!real.infinity);
+static assert(__c_complex_real.init is _Complex!real.init);
+static assert(__c_complex_real.max is _Complex!real.max);
+static assert(__c_complex_real.min_normal is _Complex!real.min_normal);
+static assert(__c_complex_real.nan is _Complex!real.nan);
+static assert(__c_complex_real.sizeof == _Complex!real.sizeof);
+static assert(__c_complex_real.alignof == _Complex!real.alignof);
+static assert(__c_complex_real.dig == _Complex!real.dig);
+static assert(__c_complex_real.mant_dig == _Complex!real.mant_dig);
+static assert(__c_complex_real.max_10_exp == _Complex!real.max_10_exp);
+static assert(__c_complex_real.max_exp == _Complex!real.max_exp);
+static assert(__c_complex_real.min_10_exp == _Complex!real.min_10_exp);
+static assert(__c_complex_real.min_exp == _Complex!real.min_exp);
diff --git a/gcc/testsuite/gdc.test/compilable/test23533.d b/gcc/testsuite/gdc.test/compilable/test23533.d
new file mode 100644
index 00000000000..6cf116eab12
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23533.d
@@ -0,0 +1,10 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23533
+// REQUIRED_ARGS: -preview=nosharedaccess
+
+enum E { a, b }
+
+void main()
+{
+	E x = E.b;
+	E y = E.max;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23586.d b/gcc/testsuite/gdc.test/compilable/test23586.d
new file mode 100644
index 00000000000..ee7ef3c4280
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23586.d
@@ -0,0 +1,34 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23586
+
+int test23686a(int x)
+{
+    switch(x)
+    {
+        case 0:
+            goto Bar;
+
+        Bar:
+        default:
+            auto y = 6;
+            return y;
+    }
+}
+
+int test23686b(int x)
+{
+    switch(x)
+    {
+        case 0:
+        Bar:
+        case 1:
+        case 2:
+            auto y = 7;
+            return y;
+
+        default:
+            goto Bar;
+    }
+}
+
+static assert(test23686a(0) == 6);
+static assert(test23686b(3) == 7);
diff --git a/gcc/testsuite/gdc.test/compilable/test23587.d b/gcc/testsuite/gdc.test/compilable/test23587.d
new file mode 100644
index 00000000000..6698f9cbc87
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23587.d
@@ -0,0 +1,18 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23587
+// REQUIRED_ARGS: -w
+noreturn stuff()
+{
+    assert(false);
+}
+
+void doStuff(alias fun)()
+{
+    cast(void) fun();
+    string s = "never executed";
+    static assert(is(typeof(cast(void) fun()) == void));
+}
+
+void main()
+{
+    doStuff!stuff();
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23589.d b/gcc/testsuite/gdc.test/compilable/test23589.d
new file mode 100644
index 00000000000..beff31f28f1
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23589.d
@@ -0,0 +1,30 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23589
+struct TemplStr(string Description_) {}
+
+template A() {
+    bool member;
+    alias THIS = typeof(this);
+    static THIS staticInstance;
+    static asSize()
+    {
+        return staticInstance.member;
+    }
+}
+
+template B() {
+    enum cols = columns();
+
+    enum cols_two = cols;
+    TemplStr!(cols_two) tstr;
+}
+
+struct S
+{
+  mixin A;
+  mixin B;
+
+  static string columns() {
+    auto dummy = &asSize;
+    return "as";
+  }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail109.d b/gcc/testsuite/gdc.test/fail_compilation/fail109.d
index 7caae59d052..87297dbacd7 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail109.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail109.d
@@ -90,3 +90,19 @@  enum RegValueType2b : DWORD
     DWORD = REG_DWORD,
     Unknown = DWORD.min,
 }
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail109.d(107): Error: enum member `fail109.d` initialization with `__anonymous.c+1` causes overflow for type `Q`
+---
+*/
+
+struct Q {
+	enum max = Q();
+}
+
+enum {
+	c = Q(),
+	d
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail20618.d b/gcc/testsuite/gdc.test/fail_compilation/fail20618.d
deleted file mode 100644
index ac6b33a3a9c..00000000000
--- a/gcc/testsuite/gdc.test/fail_compilation/fail20618.d
+++ /dev/null
@@ -1,16 +0,0 @@ 
-/*
-TEST_OUTPUT:
----
-fail_compilation/fail20618.d(13): Error: in slice `a[1 .. 12]`, upper bound is greater than array length `10`
-fail_compilation/fail20618.d(14): Error: in slice `a[4 .. 3]`, lower bound is greater than upper bound
-fail_compilation/fail20618.d(15): Error: in slice `a[0 .. 11]`, upper bound is greater than array length `10`
----
-*/
-
-void main()
-{
-    int[10] a;
-    auto b = a[1..12];
-    auto c = a[4..3];
-    auto d = a[0..$ + 1];
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23151.d b/gcc/testsuite/gdc.test/fail_compilation/fail23151.d
new file mode 100644
index 00000000000..e24dcc2b704
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23151.d
@@ -0,0 +1,41 @@ 
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail23151.d(30): Error: class `fail23151.makeDerivedObj.Derived` is nested within `makeDerivedObj`, but super class `Base` is nested within `makeBaseObj`
+---
+*/
+interface I
+{
+    void intfunc(int x);
+}
+
+auto makeBaseObj()
+{
+    int realPrivateX;
+    class Base : I
+    {
+        private int modulePrivateX;
+        int publicX;
+        override void intfunc(int x)
+        {
+            realPrivateX++; // expected OK
+        }
+    }
+    return new Base;
+}
+
+auto makeDerivedObj()
+{
+    int realPrivateY;
+    class Derived : typeof(makeBaseObj())
+    {
+        private int modulePrivateY;
+        int publicY;
+        override void intfunc(int x)
+        {
+            realPrivateX++; // expected NG
+            modulePrivateX++;
+        }
+    }
+    return new Derived;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23574.d b/gcc/testsuite/gdc.test/fail_compilation/fail23574.d
new file mode 100644
index 00000000000..c314d92fae5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23574.d
@@ -0,0 +1,41 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23574
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail23574.d(26): Error: function `object._xopEquals` has no `return` statement, but is expected to return a value of type `bool`
+Error: undefined identifier `size_t` in module `object`
+fail_compilation/fail23574.d(34): Error: template instance `object.S17915!(MyClass)` error instantiating
+fail_compilation/fail23574.d(30): Error: function `object.SDL_GetKeyName` has no `return` statement, but is expected to return a value of type `const(char)`
+---
+*/
+module object;
+
+class Object
+{
+}
+
+bool opEquals(LHS, RHS)(LHS lhs, RHS)
+{
+    opEquals(cast()lhs);
+}
+
+class TypeInfo
+{
+}
+
+bool _xopEquals()
+{
+}
+
+const(char)SDL_GetKeyName()
+{
+    class MyClass
+    {
+        S17915!MyClass m_member;
+    }
+}
+
+struct S17915(T)
+{
+    T owner;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23591.d b/gcc/testsuite/gdc.test/fail_compilation/fail23591.d
new file mode 100644
index 00000000000..ddfc5587c64
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23591.d
@@ -0,0 +1,16 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23591
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail23591.d(13): Error: cannot implicitly convert expression `square(i) , null` of type `string` to `int`
+fail_compilation/fail23591.d(14): Error: cannot implicitly convert expression `assert(0) , null` of type `real function(char)` to `int`
+---
+*/
+noreturn square(int x);
+
+int example(int i)
+{
+    int x = cast(string)square(i);
+    int y = cast(real function(char))assert(0);
+    return x + y;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/failattr.d b/gcc/testsuite/gdc.test/fail_compilation/failattr.d
index c7f0f31d068..012305af956 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/failattr.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/failattr.d
@@ -3,14 +3,17 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/failattr.d(16): Error: variable `failattr.C2901.v1` cannot be `synchronized`
-fail_compilation/failattr.d(17): Error: variable `failattr.C2901.v2` cannot be `override`
-fail_compilation/failattr.d(18): Error: variable `failattr.C2901.v3` cannot be `abstract`
-fail_compilation/failattr.d(19): Error: variable `failattr.C2901.v4` cannot be `final`, perhaps you meant `const`?
-fail_compilation/failattr.d(31): Error: variable `failattr.C2901.v13` cannot be `final abstract synchronized override`
-fail_compilation/failattr.d(33): Error: variable `failattr.C2901.v14` cannot be `final`, perhaps you meant `const`?
+fail_compilation/failattr.d(103): Error: variable `failattr.C2901.v1` cannot be `synchronized`
+fail_compilation/failattr.d(104): Error: variable `failattr.C2901.v2` cannot be `override`
+fail_compilation/failattr.d(105): Error: variable `failattr.C2901.v3` cannot be `abstract`
+fail_compilation/failattr.d(106): Error: variable `failattr.C2901.v4` cannot be `final`, perhaps you meant `const`?
+fail_compilation/failattr.d(118): Error: variable `failattr.C2901.v13` cannot be `final abstract synchronized override`
+fail_compilation/failattr.d(120): Error: variable `failattr.C2901.v14` cannot be `final`, perhaps you meant `const`?
+fail_compilation/failattr.d(123): Error: undefined identifier `ERROR`
 ---
 */
+#line 100
+
 class C2901
 {
     synchronized    int v1;         // error
@@ -32,3 +35,5 @@  class C2901
 
     static final int v14;           // error, even if static is applied at the same time
 }
+
+enum B23122 { @ERROR e }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice23564.d b/gcc/testsuite/gdc.test/fail_compilation/ice23564.d
new file mode 100644
index 00000000000..75b5d4ef9c6
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice23564.d
@@ -0,0 +1,25 @@ 
+/* TEST_OUTPUT:
+---
+fail_compilation/ice23564.d(10): Error: cannot construct nested class `FreeList` because no implicit `this` reference to outer class `RBTree` is available
+---
+*/
+class BlockHeader
+{
+    this()
+    {
+        new FreeList;
+    }
+}
+
+class RBTree
+{
+    class FreeList
+    {
+    }
+
+    void _each_reverse()
+    {
+    }
+}
+
+alias FreeList = RBTree.FreeList;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice23569.d b/gcc/testsuite/gdc.test/fail_compilation/ice23569.d
new file mode 100644
index 00000000000..277814f76cf
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice23569.d
@@ -0,0 +1,19 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23569
+/*
+TEST_OUTPUT:
+---
+fail_compilation/ice23569.d(18): Error: cannot compare classes for equality because `object.Object` was not declared
+---
+*/
+module object;
+
+@safe unittest1()
+{
+    class F
+    {
+        this(int )
+        {
+        }
+    }
+    auto ice23569 = new F(0) == new F(0);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/staticassertargs.d b/gcc/testsuite/gdc.test/fail_compilation/staticassertargs.d
new file mode 100644
index 00000000000..9591fd809a9
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/staticassertargs.d
@@ -0,0 +1,9 @@ 
+/*
+TEST_OUTPUT:
+---
+fail_compilation/staticassertargs.d(9): Error: static assert:  abcxe3!!
+---
+*/
+
+enum e = "!!";
+static assert(false, "abc", ['x', 'e'], 3, e);
diff --git a/gcc/testsuite/gdc.test/fail_compilation/staticassertargsfail.d b/gcc/testsuite/gdc.test/fail_compilation/staticassertargsfail.d
new file mode 100644
index 00000000000..911d5887562
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/staticassertargsfail.d
@@ -0,0 +1,10 @@ 
+/*
+TEST_OUTPUT:
+---
+fail_compilation/staticassertargsfail.d(10): Error: incompatible types for `('x') : (new Object)`: `char` and `object.Object`
+fail_compilation/staticassertargsfail.d(10):        while evaluating `static assert` argument `['x', new Object] ~ ""`
+---
+*/
+
+
+static assert(0, "abc", ['x', new Object] ~ "");
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test12228.d b/gcc/testsuite/gdc.test/fail_compilation/test12228.d
index a62eb864a54..d96b2a522d9 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test12228.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test12228.d
@@ -1,10 +1,9 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/test12228.d(13): Error: undefined identifier `this`, did you mean `typeof(this)`?
-fail_compilation/test12228.d(18): Error: no property `x` for type `object.Object`
+fail_compilation/test12228.d(12): Error: undefined identifier `this`, did you mean `typeof(this)`?
+fail_compilation/test12228.d(18): Error: undefined identifier `super`, did you mean `typeof(super)`?
 fail_compilation/test12228.d(19): Error: undefined identifier `super`, did you mean `typeof(super)`?
-fail_compilation/test12228.d(20): Error: undefined identifier `super`, did you mean `typeof(super)`?
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21008.d b/gcc/testsuite/gdc.test/fail_compilation/test21008.d
index 641c802c254..7d5bb375c10 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test21008.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21008.d
@@ -12,7 +12,6 @@  fail_compilation/test21008.d(117): Error: `Monitor` has no effect
 fail_compilation/test21008.d(117): Error: function `object.Object.factory(string classname)` is not callable using argument types `()`
 fail_compilation/test21008.d(117):        too few arguments, expected 1, got 0
 fail_compilation/test21008.d(105):        called from here: `handleMiddlewareAnnotation()`
-fail_compilation/test21008.d(108): Error: class `test21008.C` no size because of forward reference
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23552.d b/gcc/testsuite/gdc.test/fail_compilation/test23552.d
new file mode 100644
index 00000000000..bf9e3a66399
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test23552.d
@@ -0,0 +1,24 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=23552
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test23552.d(17): Error: cannot implicitly override base class method `test23552.Base.foo` with `test23552.Derived.foo`; add `override` attribute
+---
+*/
+
+abstract class Base
+{
+    void foo();
+}
+
+class Derived : Base
+{
+    void foo() { }
+    int data() { return 0; }
+}
+
+class DerivedX : Derived
+{
+    override int data() { return 1; }
+}
diff --git a/gcc/testsuite/gdc.test/runnable/issue22854.d b/gcc/testsuite/gdc.test/runnable/issue22854.d
new file mode 100644
index 00000000000..c4cae17f95b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/issue22854.d
@@ -0,0 +1,27 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22854
+void main()
+{
+    uint loops = 0;
+    static foreach (i; 0 .. 50)
+    {
+        static foreach (ch; SomeContainer().range)
+            loops++;
+    }
+    assert(loops == 50 * 50);
+}
+
+struct SomeContainer
+{
+    SomeRange range() { return SomeRange(); }
+    TypeWithDestructor data;
+}
+
+struct TypeWithDestructor { ~this() { } }
+
+struct SomeRange
+{
+    int count = 50;
+    int front() { return count; }
+    bool empty() { return count <= 0; }
+    void popFront() { count--; }
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test16098.d b/gcc/testsuite/gdc.test/runnable/test16098.d
new file mode 100644
index 00000000000..16b34f1894c
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test16098.d
@@ -0,0 +1,14 @@ 
+
+// https://issues.dlang.org/show_bug.cgi?id=16098
+
+void main() {
+    byte a;
+    align(128) byte b;
+    assert((cast(size_t) &b) % 128 == 0);
+
+    byte foo() { return b; }
+    dg = &foo;
+    assert(dg() == false);
+}
+
+__gshared byte delegate() dg;
diff --git a/gcc/testsuite/gdc.test/runnable/test20811.d b/gcc/testsuite/gdc.test/runnable/test20811.d
new file mode 100644
index 00000000000..a300d2a3b1d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test20811.d
@@ -0,0 +1,34 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=20811
+
+// OK: Mutable array literals are copied before CTFE takes ownership.
+string issue20811a()
+{
+    char[1] counter = ['0'];
+    counter[$-1]++;
+    return counter.dup;
+}
+
+static assert(issue20811a() == "1");
+static assert(issue20811a() == "1");
+static assert(issue20811a() == "1");
+static assert(issue20811a() == "1");
+
+// Issue 20811: String literals were assumed to be read-only, so weren't copied.
+string issue20811b()
+{
+    char[1] counter = "0";
+    counter[$-1]++;
+    return counter.dup;
+}
+
+static assert(issue20811b() == "1");
+static assert(issue20811b() == "1");
+static assert(issue20811b() == "1");
+static assert(issue20811b() == "1");
+
+void main()
+{
+    // Ensure CTFE did not overwrite the original AST.
+    assert(issue20811a() == "1");
+    assert(issue20811b() == "1");
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test23307.d b/gcc/testsuite/gdc.test/runnable/test23307.d
new file mode 100644
index 00000000000..a61b0d7ca58
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test23307.d
@@ -0,0 +1,93 @@ 
+// REQUIRED_ARGS: -inline -O
+
+// https://issues.dlang.org/show_bug.cgi?id=23307
+import core.simd;
+
+static if(__traits(compiles, int4))
+{
+
+alias __m128i = int4;
+
+uint bitwiseRotateRight_uint(const uint value, const uint count)
+{
+    assert(count < 8 * uint.sizeof);
+    return cast(uint) ((value >> count) | (value << (uint.sizeof * 8 - count)));
+}
+
+
+__m128i _mm_sha256rnds2_epu32(__m128i a, __m128i b, __m128i k)
+{
+
+    static uint Ch(uint x, uint y, uint z)
+    {
+        return z ^ (x & (y ^ z));
+    }
+
+    static uint Maj(uint x, uint y, uint z)
+    {
+        return (x & y) | (z & (x ^ y));
+    }
+
+    static uint sum0(uint x)
+    {
+        return bitwiseRotateRight_uint(x, 2) ^ bitwiseRotateRight_uint(x, 13) ^ bitwiseRotateRight_uint(x, 22);
+    }
+
+    static uint sum1(uint x)
+    {
+        return bitwiseRotateRight_uint(x, 6) ^ bitwiseRotateRight_uint(x, 11) ^ bitwiseRotateRight_uint(x, 25);
+    }
+
+    int4 dst;
+    int4 a4 = cast(int4) a;
+    int4 b4 = cast(int4) b;
+    int4 k4 = cast(int4) k;
+
+    const A0 = b4.array[3];
+    const B0 = b4.array[2];
+    const C0 = a4.array[3];
+    const D0 = a4.array[2];
+    const E0 = b4.array[1];
+    const F0 = b4.array[0];
+    const G0 = a4.array[1];
+    const H0 = a4.array[0];
+    const W_K0 = k4.array[0];
+    const W_K1 = k4.array[1];
+    const A1 = Ch(E0, F0, G0) + sum1(E0) + W_K0 + H0 + Maj(A0, B0, C0) + sum0(A0);
+    const B1 = A0;
+    const C1 = B0;
+    const D1 = C0;
+    const E1 = Ch(E0, F0, G0) + sum1(E0) + W_K0 + H0 + D0;
+    const F1 = E0;
+    const G1 = F0;
+    const H1 = G0;
+    const A2 = Ch(E1, F1, G1) + sum1(E1) + W_K1 + H1 + Maj(A1, B1, C1) + sum0(A1);
+    const B2 = A1;
+    const C2 = B1;
+    const D2 = C1;
+    const E2 = Ch(E1, F1, G1) + sum1(E1) + W_K1 + H1 + D1;
+    const F2 = E1;
+    const G2 = F1;
+    const H2 = G1;
+
+    dst.ptr[3] = A2;
+    dst.ptr[2] = B2;
+    dst.ptr[1] = E2;
+    dst.ptr[0] = F2;
+
+    return cast(__m128i) dst;
+}
+
+void main(string[] args)
+{
+    __m128i a = [15, 20, 130, 12345];
+    __m128i b = [15, 20, 130, 12345];
+    __m128i k = [15, 20, 130, 12345];
+    __m128i result = _mm_sha256rnds2_epu32(a, b, k);
+    assert(result.array == [1384123044, -2050674062, 327754346, 956342016]);
+}
+}
+else
+{
+int main() { return 0; }
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test34.d b/gcc/testsuite/gdc.test/runnable/test34.d
index df461370066..11543f1ae85 100644
--- a/gcc/testsuite/gdc.test/runnable/test34.d
+++ b/gcc/testsuite/gdc.test/runnable/test34.d
@@ -1,3 +1,5 @@ 
+// REQUIRED_ARGS: -d
+
 module test34;
 
 import core.exception;
diff --git a/gcc/testsuite/gdc.test/runnable/xtest46.d b/gcc/testsuite/gdc.test/runnable/xtest46.d
index 8ae08ad2e47..a0907f4b856 100644
--- a/gcc/testsuite/gdc.test/runnable/xtest46.d
+++ b/gcc/testsuite/gdc.test/runnable/xtest46.d
@@ -1,4 +1,4 @@ 
-// REQUIRED_ARGS: -preview=rvaluerefparam
+// REQUIRED_ARGS: -d -preview=rvaluerefparam
 //
 /* TEST_OUTPUT:
 ---
diff --git a/gcc/testsuite/gdc.test/runnable/xtest46_gc.d b/gcc/testsuite/gdc.test/runnable/xtest46_gc.d
index 348c05bd09d..b0288a25e08 100644
--- a/gcc/testsuite/gdc.test/runnable/xtest46_gc.d
+++ b/gcc/testsuite/gdc.test/runnable/xtest46_gc.d
@@ -1,5 +1,5 @@ 
 /*
-REQUIRED_ARGS: -lowmem -Jrunnable -preview=rvaluerefparam
+REQUIRED_ARGS: -d -lowmem -Jrunnable -preview=rvaluerefparam
 EXTRA_FILES: xtest46.d
 TEST_OUTPUT:
 ---
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 5ee6f624836..ac3dd129268 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@ 
-c8ae4adb2eda515b09b326948e3a4aa9f489af45
+09faa4eacd4fb147107e94eeebf56b3a73fdcc05
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/libphobos/libdruntime/core/demangle.d b/libphobos/libdruntime/core/demangle.d
index 869ade64821..fe273319f21 100644
--- a/libphobos/libdruntime/core/demangle.d
+++ b/libphobos/libdruntime/core/demangle.d
@@ -2134,7 +2134,7 @@  pure @safe:
  */
 char[] demangle(return scope const(char)[] buf, return scope char[] dst = null, CXX_DEMANGLER __cxa_demangle = null) nothrow pure @safe
 {
-    if (buf.length > 2 && buf[0..2] == "_Z")
+    if (__cxa_demangle && buf.length > 2 && buf[0..2] == "_Z")
         return demangleCXX(buf, __cxa_demangle, dst);
     auto d = Demangle!()(buf, dst);
     // fast path (avoiding throwing & catching exception) for obvious
@@ -2734,6 +2734,9 @@  unittest
     s ~= "FiZi";
     expected ~= "F";
     assert(s.demangle == expected);
+
+    // https://issues.dlang.org/show_bug.cgi?id=23562
+    assert(demangle("_Zv") == "_Zv");
 }
 
 // https://issues.dlang.org/show_bug.cgi?id=22235
@@ -2929,6 +2932,7 @@  CXX_DEMANGLER getCXXDemangler() nothrow @trusted
         version (FreeBSD) import core.sys.freebsd.dlfcn : RTLD_DEFAULT;
         version (linux) import core.sys.linux.dlfcn : RTLD_DEFAULT;
         version (NetBSD) import core.sys.netbsd.dlfcn : RTLD_DEFAULT;
+        version (OpenBSD) import core.sys.openbsd.dlfcn : RTLD_DEFAULT;
         version (OSX) import core.sys.darwin.dlfcn : RTLD_DEFAULT;
         version (Solaris) import core.sys.solaris.dlfcn : RTLD_DEFAULT;
 
diff --git a/libphobos/libdruntime/core/exception.d b/libphobos/libdruntime/core/exception.d
index 62179fec58b..d2016b115f1 100644
--- a/libphobos/libdruntime/core/exception.d
+++ b/libphobos/libdruntime/core/exception.d
@@ -278,7 +278,6 @@  class FinalizeError : Error
     this( TypeInfo ci, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc
     {
         super( "Finalization error", file, line, next );
-        super.info = SuppressTraceInfo.instance;
         info = ci;
     }
 
@@ -393,7 +392,6 @@  class InvalidMemoryOperationError : Error
     this(string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc
     {
         super( "Invalid memory operation", file, line, next );
-        this.info = SuppressTraceInfo.instance;
     }
 
     override string toString() const @trusted
diff --git a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
index e29e42648b6..6d19247fbe0 100644
--- a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
+++ b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
@@ -110,13 +110,23 @@  alias GC gc_t;
 /* ============================ GC =============================== */
 
 // register GC in C constructor (_STI_)
-extern(C) pragma(crt_constructor) void _d_register_conservative_gc()
+private pragma(crt_constructor) void gc_conservative_ctor()
+{
+    _d_register_conservative_gc();
+}
+
+extern(C) void _d_register_conservative_gc()
 {
     import core.gc.registry;
     registerGCFactory("conservative", &initialize);
 }
 
-extern(C) pragma(crt_constructor) void _d_register_precise_gc()
+private pragma(crt_constructor) void gc_precise_ctor()
+{
+    _d_register_precise_gc();
+}
+
+extern(C) void _d_register_precise_gc()
 {
     import core.gc.registry;
     registerGCFactory("precise", &initialize_precise);
diff --git a/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d b/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d
index a65c636ef23..570781e2fdc 100644
--- a/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d
+++ b/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d
@@ -29,7 +29,12 @@  static import core.memory;
 extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc; /* dmd @@@BUG11461@@@ */
 
 // register GC in C constructor (_STI_)
-extern(C) pragma(crt_constructor) void _d_register_manual_gc()
+private pragma(crt_constructor) void gc_manual_ctor()
+{
+    _d_register_manual_gc();
+}
+
+extern(C) void _d_register_manual_gc()
 {
     import core.gc.registry;
     registerGCFactory("manual", &initialize);
diff --git a/libphobos/libdruntime/core/runtime.d b/libphobos/libdruntime/core/runtime.d
index 799e5252941..19bb61b0c22 100644
--- a/libphobos/libdruntime/core/runtime.d
+++ b/libphobos/libdruntime/core/runtime.d
@@ -112,7 +112,7 @@  private
     alias void delegate( Throwable ) ExceptionHandler;
     extern (C) void _d_print_throwable(Throwable t);
 
-    extern (C) void* thread_stackBottom();
+    extern (C) void* thread_stackBottom() nothrow @nogc;
 }
 
 
@@ -122,7 +122,7 @@  shared static this()
     //       still possible the app could exit without a stack trace.  If
     //       this becomes an issue, the handler could be set in C main
     //       before the module ctors are run.
-    Runtime.traceHandler = &defaultTraceHandler;
+    Runtime.traceHandler(&defaultTraceHandler, &defaultTraceDeallocator);
 }
 
 
@@ -284,10 +284,18 @@  struct Runtime
      * If the supplied pointer is null then the trace routine should determine
      * an appropriate calling context from which to begin the trace.
      *
+     * If the deallocator is set, then it is called with the traceinfo when the
+     * exception is finalized. The deallocator is only set in the exception if
+     * the default handler is used to generate the trace info.
+     *
      * Params:
      *  h = The new trace handler.  Set to null to disable exception backtracing.
+     *  d = The new trace deallocator. If non-null, this will be called on
+     *      exception destruction with the trace info, only when the trace
+     *      handler is used to generate TraceInfo.
      */
-    extern(C) pragma(mangle, "rt_setTraceHandler") static @property void traceHandler(TraceHandler h);
+    extern(C) pragma(mangle, "rt_setTraceHandler") static @property void traceHandler(TraceHandler h,
+                    Throwable.TraceDeallocator d = null);
 
     /**
      * Gets the current trace handler.
@@ -297,6 +305,14 @@  struct Runtime
      */
     extern(C) pragma(mangle, "rt_getTraceHandler") static @property TraceHandler traceHandler();
 
+    /**
+     * Gets the current trace deallocator.
+     *
+     * Returns:
+     *  The current trace deallocator or null if none has been set.
+     */
+    extern(C) pragma(mangle, "rt_getTraceDeallocator") static @property Throwable.TraceDeallocator traceDeallocator();
+
     /**
      * Overrides the default collect hander with a user-supplied version.  This
      * routine will be called for each resource object that is finalized in a
@@ -705,6 +721,10 @@  extern (C) UnitTestResult runModuleUnitTests()
  * This functions returns a trace handler, allowing to inspect the
  * current stack trace.
  *
+ * IMPORTANT NOTE! the returned trace is potentially not GC allocated, and so
+ * you must call `defaultTraceDeallocator` when you are finished with the
+ * `TraceInfo`
+ *
  * Params:
  *   ptr = (Windows only) The context to get the stack trace from.
  *         When `null` (the default), start from the current frame.
@@ -714,14 +734,24 @@  extern (C) UnitTestResult runModuleUnitTests()
  *   or `null`. If called from a finalizer (destructor), always returns `null`
  *   as trace handlers allocate.
  */
-Throwable.TraceInfo defaultTraceHandler( void* ptr = null )
+Throwable.TraceInfo defaultTraceHandler( void* ptr = null ) // @nogc
 {
+    // NOTE: with traces now being allocated using C malloc, no need to worry
+    // about GC reentrancy. This code left commented out for reference.
+    //
     // avoid recursive GC calls in finalizer, trace handlers should be made @nogc instead
-    import core.memory : GC;
+    /*import core.memory : GC;
     if (GC.inFinalizer)
-        return null;
+        return null;*/
 
-    static if (__traits(compiles, new LibBacktrace(0)))
+    static T allocate(T, Args...)(auto ref Args args) @nogc
+    {
+        import core.lifetime : emplace;
+        import core.stdc.stdlib : malloc;
+        auto result = cast(T)malloc(__traits(classInstanceSize, T));
+        return emplace(result, args);
+    }
+    static if (__traits(compiles, allocate!LibBacktrace(0)))
     {
         version (Posix)
             static enum FIRSTFRAME = 4;
@@ -729,9 +759,9 @@  Throwable.TraceInfo defaultTraceHandler( void* ptr = null )
             static enum FIRSTFRAME = 4;
         else
             static enum FIRSTFRAME = 0;
-        return new LibBacktrace(FIRSTFRAME);
+        return allocate!LibBacktrace(FIRSTFRAME);
     }
-    else static if (__traits(compiles, new UnwindBacktrace(0)))
+    else static if (__traits(compiles, allocate!UnwindBacktrace(0)))
     {
         version (Posix)
             static enum FIRSTFRAME = 5;
@@ -739,25 +769,25 @@  Throwable.TraceInfo defaultTraceHandler( void* ptr = null )
             static enum FIRSTFRAME = 4;
         else
             static enum FIRSTFRAME = 0;
-        return new UnwindBacktrace(FIRSTFRAME);
+        return allocate!UnwindBacktrace(FIRSTFRAME);
     }
     else version (Windows)
     {
         import core.sys.windows.stacktrace;
-        static if (__traits(compiles, new StackTrace(0, null)))
+        static if (__traits(compiles, allocate!StackTrace(0, null)))
         {
             import core.sys.windows.winnt : CONTEXT;
             version (Win64)
                 enum FIRSTFRAME = 4;
             else version (Win32)
                 enum FIRSTFRAME = 0;
-            return new StackTrace(FIRSTFRAME, cast(CONTEXT*)ptr);
+            return allocate!StackTrace(FIRSTFRAME, cast(CONTEXT*)ptr);
         }
         else
             return null;
     }
-    else static if (__traits(compiles, new DefaultTraceInfo()))
-        return new DefaultTraceInfo();
+    else static if (__traits(compiles, allocate!DefaultTraceInfo()))
+        return allocate!DefaultTraceInfo();
     else
         return null;
 }
@@ -775,9 +805,32 @@  unittest
         {
             printf("%.*s\n", cast(int)line.length, line.ptr);
         }
+        defaultTraceDeallocator(trace);
     }
 }
 
+/***
+ * Deallocate a traceinfo generated by deaultTraceHander.
+ *
+ * Call this function on a TraceInfo generated via `defaultTraceHandler` when
+ * you are done with it. If necessary, this cleans up any manually managed
+ * resources from the `TraceInfo`, and invalidates it. After this, the object
+ * is no longer valid.
+ *
+ * Params:
+ *      info = The `TraceInfo` to deallocate. This should only be a value that
+ *             was returned by `defaultTraceHandler`.
+ */
+void defaultTraceDeallocator(Throwable.TraceInfo info) nothrow
+{
+    if (info is null)
+        return;
+    auto obj = cast(Object)info;
+    destroy(obj);
+    import core.stdc.stdlib : free;
+    free(cast(void *)obj);
+}
+
 version (DRuntime_Use_Libunwind)
 {
     import core.internal.backtrace.handler;
@@ -791,7 +844,7 @@  else static if (hasExecinfo) private class DefaultTraceInfo : Throwable.TraceInf
     import core.stdc.stdlib : free;
     import core.stdc.string : strlen, memchr, memmove;
 
-    this()
+    this() @nogc
     {
         // it may not be 1 but it is good enough to get
         // in CALL instruction address range for backtrace
@@ -805,13 +858,13 @@  else static if (hasExecinfo) private class DefaultTraceInfo : Throwable.TraceInf
                 elem -= CALL_INSTRUCTION_SIZE;
         else // backtrace() failed, do it ourselves
         {
-            static void** getBasePtr()
+            static void** getBasePtr() @nogc
             {
                 version (D_InlineAsm_X86)
-                    asm { naked; mov EAX, EBP; ret; }
+                    asm @nogc { naked; mov EAX, EBP; ret; }
                 else
                     version (D_InlineAsm_X86_64)
-                        asm { naked; mov RAX, RBP; ret; }
+                        asm @nogc { naked; mov RAX, RBP; ret; }
                 else
                     return null;
             }
diff --git a/libphobos/libdruntime/core/stdc/config.d b/libphobos/libdruntime/core/stdc/config.d
index c576e991db5..16bc47501e3 100644
--- a/libphobos/libdruntime/core/stdc/config.d
+++ b/libphobos/libdruntime/core/stdc/config.d
@@ -286,6 +286,22 @@  private struct _Complex(T)
 {
     T re;
     T im;
+
+    // Helper properties.
+    pragma(inline, true)
+    {
+        static @property epsilon()()    { return _Complex(T.epsilon, T.epsilon); }
+        static @property infinity()()   { return _Complex(T.infinity, T.infinity); }
+        static @property max()()        { return _Complex(T.max, T.max); }
+        static @property min_normal()() { return _Complex(T.min_normal, T.min_normal); }
+        static @property nan()()        { return _Complex(T.nan, T.nan); }
+        static @property dig()()        { return T.dig; }
+        static @property mant_dig()()   { return T.mant_dig; }
+        static @property max_10_exp()() { return T.max_10_exp; }
+        static @property max_exp()()    { return T.max_exp; }
+        static @property min_10_exp()() { return T.min_10_exp; }
+        static @property min_exp()()    { return T.min_exp; }
+    }
 }
 
 enum __c_complex_float  : _Complex!float;
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/getsect.d b/libphobos/libdruntime/core/sys/darwin/mach/getsect.d
index dc42a2dc450..b6e10a81b00 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/getsect.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/getsect.d
@@ -148,7 +148,7 @@  version (CoreDdoc)
      *
      *      auto mph = _NSGetMachExecuteHeader();
      *      int size;
-     *      assert(getsectdata(mph, "__TEXT", "__text", &size));
+     *      assert(getsectiondata(mph, "__TEXT", "__text", &size));
      *      assert(size > 0);
      * }
      * ---
diff --git a/libphobos/libdruntime/core/sys/posix/sys/wait.d b/libphobos/libdruntime/core/sys/posix/sys/wait.d
index 145149be528..f6b0674a3b1 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/wait.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/wait.d
@@ -386,9 +386,15 @@  else version (NetBSD)
 else version (OpenBSD)
 {
     enum WCONTINUED     = 8;
-    // OpenBSD does not define the following:
-    //enum WSTOPPED
-    //enum WNOWAIT
+    enum WSTOPPED       = WUNTRACED;
+    enum WNOWAIT        = 16;
+
+    enum idtype_t
+    {
+        P_ALL,
+        P_PID,
+        P_PGID
+    }
 }
 else version (DragonFlyBSD)
 {
diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d
index de14bce94ee..55fbc56a754 100644
--- a/libphobos/libdruntime/core/sys/windows/dbghelp.d
+++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d
@@ -31,7 +31,7 @@  extern(Windows)
     alias PVOID        function(HANDLE hProcess, DWORD64 AddrBase) SymFunctionTableAccess64Func;
     alias BOOL         function(DWORD MachineType, HANDLE hProcess, HANDLE hThread, STACKFRAME64 *StackFrame, PVOID ContextRecord,
                                 ReadProcessMemoryProc64 ReadMemoryRoutine, FunctionTableAccessProc64 FunctoinTableAccess,
-                                GetModuleBaseProc64 GetModuleBaseRoutine, TranslateAddressProc64 TranslateAddress) StackWalk64Func;
+                                GetModuleBaseProc64 GetModuleBaseRoutine, TranslateAddressProc64 TranslateAddress) @nogc StackWalk64Func;
     alias BOOL         function(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, IMAGEHLP_LINEA64 *line) SymGetLineFromAddr64Func;
     alias DWORD64      function(HANDLE hProcess, DWORD64 dwAddr) SymGetModuleBase64Func;
     alias BOOL         function(HANDLE hProcess, DWORD64 dwAddr, IMAGEHLP_MODULEA64 *ModuleInfo) SymGetModuleInfo64Func;
@@ -66,7 +66,7 @@  struct DbgHelp
     SymRegisterCallback64Func SymRegisterCallback64;
     ImagehlpApiVersionFunc   ImagehlpApiVersion;
 
-    static DbgHelp* get()
+    static DbgHelp* get() @nogc
     {
         if ( sm_hndl != sm_hndl.init )
             return &sm_inst;
diff --git a/libphobos/libdruntime/core/sys/windows/stacktrace.d b/libphobos/libdruntime/core/sys/windows/stacktrace.d
index 6e5c4cd13cf..8df29729af3 100644
--- a/libphobos/libdruntime/core/sys/windows/stacktrace.d
+++ b/libphobos/libdruntime/core/sys/windows/stacktrace.d
@@ -24,10 +24,10 @@  import core.sys.windows.windef;
 debug(PRINTF) import core.stdc.stdio;
 
 
-extern(Windows) void RtlCaptureContext(CONTEXT* ContextRecord);
+extern(Windows) void RtlCaptureContext(CONTEXT* ContextRecord) @nogc;
 extern(Windows) DWORD GetEnvironmentVariableA(LPCSTR lpName, LPSTR pBuffer, DWORD nSize);
 
-extern(Windows) alias USHORT function(ULONG FramesToSkip, ULONG FramesToCapture, PVOID *BackTrace, PULONG BackTraceHash) RtlCaptureStackBackTraceFunc;
+extern(Windows) alias USHORT function(ULONG FramesToSkip, ULONG FramesToCapture, PVOID *BackTrace, PULONG BackTraceHash) @nogc RtlCaptureStackBackTraceFunc;
 
 private __gshared RtlCaptureStackBackTraceFunc RtlCaptureStackBackTrace;
 private __gshared immutable bool initialized;
@@ -42,7 +42,7 @@  public:
      *  skip = The number of stack frames to skip.
      *  context = The context to receive the stack trace from. Can be null.
      */
-    this(size_t skip, CONTEXT* context)
+    this(size_t skip, CONTEXT* context) @nogc
     {
         if (context is null)
         {
@@ -64,7 +64,7 @@  public:
             skip += INTERNALFRAMES;
         }
         if ( initialized )
-            m_trace = trace(skip, context);
+            m_trace = trace(tracebuf[], skip, context);
     }
 
     int opApply( scope int delegate(ref const(char[])) dg ) const
@@ -100,18 +100,27 @@  public:
     }
 
     /**
-     * Receive a stack trace in the form of an address list.
+     * Receive a stack trace in the form of an address list. One form accepts
+     * an allocated buffer, the other form automatically allocates the buffer.
+     *
      * Params:
      *  skip = How many stack frames should be skipped.
      *  context = The context that should be used. If null the current context is used.
+     *  buffer = The buffer to use for the trace. This should be at least 63 elements.
      * Returns:
      *  A list of addresses that can be passed to resolve at a later point in time.
      */
     static ulong[] trace(size_t skip = 0, CONTEXT* context = null)
+    {
+        return trace(new ulong[63], skip, context);
+    }
+
+    /// ditto
+    static ulong[] trace(ulong[] buffer, size_t skip = 0, CONTEXT* context = null) @nogc
     {
         synchronized( typeid(StackTrace) )
         {
-            return traceNoSync(skip, context);
+            return traceNoSync(buffer, skip, context);
         }
     }
 
@@ -131,38 +140,43 @@  public:
     }
 
 private:
+    ulong[128] tracebuf;
     ulong[] m_trace;
 
 
-    static ulong[] traceNoSync(size_t skip, CONTEXT* context)
+    static ulong[] traceNoSync(ulong[] buffer, size_t skip, CONTEXT* context) @nogc
     {
         auto dbghelp  = DbgHelp.get();
         if (dbghelp is null)
             return []; // dbghelp.dll not available
 
-        if (RtlCaptureStackBackTrace !is null && context is null)
+        if (buffer.length >= 63 && RtlCaptureStackBackTrace !is null &&
+            context is null)
         {
-            size_t[63] buffer = void; // On windows xp the sum of "frames to skip" and "frames to capture" can't be greater then 63
-            auto backtraceLength = RtlCaptureStackBackTrace(cast(ULONG)skip, cast(ULONG)(buffer.length - skip), cast(void**)buffer.ptr, null);
+            version (Win64)
+            {
+                auto bufptr = cast(void**)buffer.ptr;
+            }
+            version (Win32)
+            {
+                size_t[63] bufstorage = void; // On windows xp the sum of "frames to skip" and "frames to capture" can't be greater then 63
+                auto bufptr = cast(void**)bufstorage.ptr;
+            }
+            auto backtraceLength = RtlCaptureStackBackTrace(cast(ULONG)skip, cast(ULONG)(63 - skip), bufptr, null);
 
             // If we get a backtrace and it does not have the maximum length use it.
             // Otherwise rely on tracing through StackWalk64 which is slower but works when no frame pointers are available.
-            if (backtraceLength > 1 && backtraceLength < buffer.length - skip)
+            if (backtraceLength > 1 && backtraceLength < 63 - skip)
             {
                 debug(PRINTF) printf("Using result from RtlCaptureStackBackTrace\n");
-                version (Win64)
+                version (Win32)
                 {
-                    return buffer[0..backtraceLength].dup;
-                }
-                else version (Win32)
-                {
-                    auto result = new ulong[backtraceLength];
-                    foreach (i, ref e; result)
+                    foreach (i, ref e; buffer[0 .. backtraceLength])
                     {
-                        e = buffer[i];
+                        e = bufstorage[i];
                     }
-                    return result;
                 }
+                return buffer[0..backtraceLength];
             }
         }
 
@@ -210,21 +224,21 @@  private:
         else version (X86_64) enum imageType = IMAGE_FILE_MACHINE_AMD64;
         else                  static assert(0, "unimplemented");
 
-        ulong[] result;
         size_t frameNum = 0;
+        size_t nframes = 0;
 
         // do ... while so that we don't skip the first stackframe
         do
         {
             if (frameNum >= skip)
             {
-                result ~= stackframe.AddrPC.Offset;
+                buffer[nframes++] = stackframe.AddrPC.Offset;
             }
             frameNum++;
         }
         while (dbghelp.StackWalk64(imageType, hProcess, hThread, &stackframe,
                                    &ctxt, null, null, null, null));
-        return result;
+        return buffer[0 .. nframes];
     }
 
     static char[][] resolveNoSync(const(ulong)[] addresses)
diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d
index 415430c80e1..7316373195a 100644
--- a/libphobos/libdruntime/core/thread/osthread.d
+++ b/libphobos/libdruntime/core/thread/osthread.d
@@ -1997,12 +1997,17 @@  extern (C) void thread_suspendAll() nothrow
         Thread.criticalRegionLock.lock_nothrow();
         scope (exit) Thread.criticalRegionLock.unlock_nothrow();
         size_t cnt;
+        bool suspendedSelf;
         Thread t = ThreadBase.sm_tbeg.toThread;
         while (t)
         {
             auto tn = t.next.toThread;
             if (suspend(t))
+            {
+                if (t is ThreadBase.getThis())
+                    suspendedSelf = true;
                 ++cnt;
+            }
             t = tn;
         }
 
@@ -2010,9 +2015,12 @@  extern (C) void thread_suspendAll() nothrow
         {}
         else version (Posix)
         {
-            // subtract own thread
+            // Subtract own thread if we called suspend() on ourselves.
+            // For example, suspendedSelf would be false if the current
+            // thread ran thread_detachThis().
             assert(cnt >= 1);
-            --cnt;
+            if (suspendedSelf)
+                --cnt;
             // wait for semaphore notifications
             for (; cnt; --cnt)
             {
diff --git a/libphobos/libdruntime/core/time.d b/libphobos/libdruntime/core/time.d
index ea163a0958a..8d508755c7d 100644
--- a/libphobos/libdruntime/core/time.d
+++ b/libphobos/libdruntime/core/time.d
@@ -2822,7 +2822,7 @@  struct TickDuration
     }
 
 
-    @trusted shared static this()
+    static pragma(crt_constructor) void time_initializer()
     {
         version (Windows)
         {
diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d
index 83351f26038..0385b51d60e 100644
--- a/libphobos/libdruntime/object.d
+++ b/libphobos/libdruntime/object.d
@@ -246,7 +246,7 @@  class Object
      * }
      * ---
      */
-    static Object factory(string classname)
+    deprecated static Object factory(string classname)
     {
         auto ci = TypeInfo_Class.find(classname);
         if (ci)
@@ -256,7 +256,7 @@  class Object
         return null;
     }
 
-    @system unittest
+    deprecated @system unittest
     {
         Object valid_obj = Object.factory("object.Object");
         Object invalid_obj = Object.factory("object.__this_class_doesnt_exist__");
@@ -2481,6 +2481,8 @@  class Throwable : Object
         string toString() const;
     }
 
+    alias TraceDeallocator = void function(TraceInfo) nothrow;
+
     string      msg;    /// A message describing the error.
 
     /**
@@ -2501,6 +2503,12 @@  class Throwable : Object
      */
     TraceInfo   info;
 
+    /**
+     * If set, this is used to deallocate the TraceInfo on destruction.
+     */
+    TraceDeallocator infoDeallocator;
+
+
     /**
      * A reference to the _next error in the list. This is used when a new
      * $(D Throwable) is thrown from inside a $(D catch) block. The originally
@@ -2614,6 +2622,13 @@  class Throwable : Object
     {
         if (nextInChain && nextInChain._refcount)
             _d_delThrowable(nextInChain);
+        // handle owned traceinfo
+        if (infoDeallocator !is null)
+        {
+            infoDeallocator(info);
+            info = null; // avoid any kind of dangling pointers if we can help
+                         // it.
+        }
     }
 
     /**
diff --git a/libphobos/libdruntime/rt/deh.d b/libphobos/libdruntime/rt/deh.d
index 695f2ce9dd7..0a44be3e31f 100644
--- a/libphobos/libdruntime/rt/deh.d
+++ b/libphobos/libdruntime/rt/deh.d
@@ -42,12 +42,14 @@  module rt.deh;
 extern (C)
 {
     Throwable.TraceInfo _d_traceContext(void* ptr = null);
+    Throwable.TraceDeallocator rt_getTraceDeallocator();
     void _d_createTrace(Throwable t, void* context)
     {
         if (t !is null && t.info is null &&
             cast(byte*) t !is typeid(t).initializer.ptr)
         {
             t.info = _d_traceContext(context);
+            t.infoDeallocator = rt_getTraceDeallocator();
         }
     }
 }
diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d
index 264fdf6204a..8a10aac8fcb 100644
--- a/libphobos/libdruntime/rt/dmain2.d
+++ b/libphobos/libdruntime/rt/dmain2.d
@@ -182,6 +182,7 @@  extern (C) int rt_term()
  */
 alias Throwable.TraceInfo function(void* ptr) TraceHandler;
 private __gshared TraceHandler traceHandler = null;
+private __gshared Throwable.TraceDeallocator traceDeallocator = null;
 
 
 /**
@@ -189,10 +190,12 @@  private __gshared TraceHandler traceHandler = null;
  *
  * Params:
  *  h = The new trace handler.  Set to null to use the default handler.
+ *  d = The new dealloactor to use.
  */
-extern (C) void  rt_setTraceHandler(TraceHandler h)
+extern (C) void  rt_setTraceHandler(TraceHandler h, Throwable.TraceDeallocator d = null)
 {
     traceHandler = h;
+    traceDeallocator = d;
 }
 
 /**
@@ -203,6 +206,11 @@  extern (C) TraceHandler rt_getTraceHandler()
     return traceHandler;
 }
 
+extern (C) Throwable.TraceDeallocator rt_getTraceDeallocator()
+{
+    return traceDeallocator;
+}
+
 /**
  * This function will be called when an exception is constructed.  The
  * user-supplied trace handler will be called if one has been supplied,
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 09da6a800bd..be31395ec2b 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@ 
-792c8b7c1d5957767e138f78d04bf175d4b92f10
+13ef27a56e4c22e122fc4dd54bb46b5955babdb0
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/phobos repository.
diff --git a/libphobos/src/std/algorithm/iteration.d b/libphobos/src/std/algorithm/iteration.d
index 9a365d59e2c..967d2a6f50c 100644
--- a/libphobos/src/std/algorithm/iteration.d
+++ b/libphobos/src/std/algorithm/iteration.d
@@ -7737,8 +7737,9 @@  if (isInputRange!R &&
 
 // uniq
 /**
-Lazily iterates unique consecutive elements of the given range (functionality
-akin to the $(HTTP wikipedia.org/wiki/_Uniq, _uniq) system
+Lazily iterates unique consecutive elements of the given range, which is
+assumed to be sorted (functionality akin to the
+$(HTTP wikipedia.org/wiki/_Uniq, _uniq) system
 utility). Equivalence of elements is assessed by using the predicate
 `pred`, by default `"a == b"`. The predicate is passed to
 $(REF binaryFun, std,functional), and can either accept a string, or any callable
diff --git a/libphobos/src/std/conv.d b/libphobos/src/std/conv.d
index d1b64212e39..aef23655f2a 100644
--- a/libphobos/src/std/conv.d
+++ b/libphobos/src/std/conv.d
@@ -1891,9 +1891,7 @@  if (!is(S : T) && isAssociativeArray!S &&
     }
     // test conversions floating => integral
     {
-        // AllInts[0 .. $ - 1] should be AllInts
-        // @@@ BUG IN COMPILER @@@
-        foreach (Integral; AllInts[0 .. $ - 1])
+        foreach (Integral; AllInts)
         {
             foreach (Floating; AllFloats)
             {
@@ -1903,7 +1901,7 @@  if (!is(S : T) && isAssociativeArray!S &&
     }
     // test conversion integral => floating
     {
-        foreach (Integral; AllInts[0 .. $ - 1])
+        foreach (Integral; AllInts)
         {
             foreach (Floating; AllFloats)
             {
diff --git a/libphobos/src/std/math/exponential.d b/libphobos/src/std/math/exponential.d
index e32330fd932..66f4b8a0592 100644
--- a/libphobos/src/std/math/exponential.d
+++ b/libphobos/src/std/math/exponential.d
@@ -2910,7 +2910,7 @@  private
             alias log10P = logP;
             alias log10Q = logQ;
 
-            // Coefficients for log(x) = z + z^^3 P(z^^2)/Q(z^^2)
+            // Coefficients for log(x) = z + z^^3 R(z^^2)/S(z^^2)
             // where z = 2(x-1)/(x+1)
             // Theoretical peak relative error = 1.1e-35
             static immutable real[6] logR = [
@@ -2931,7 +2931,8 @@  private
                 1.0
             ];
         }
-        else
+        else static if (floatTraits!T.realFormat == RealFormat.ieeeExtended ||
+                        floatTraits!T.realFormat == RealFormat.ieeeExtended53)
         {
             // Coefficients for log(1 + x) = x - x^^2/2 + x^^3 P(x)/Q(x)
             // Theoretical peak relative error = 2.32e-20
@@ -2980,7 +2981,7 @@  private
             alias log10P = log2P;
             alias log10Q = log2Q;
 
-            // Coefficients for log(x) = z + z^^3 P(z^^2)/Q(z^^2)
+            // Coefficients for log(x) = z + z^^3 R(z^^2)/S(z^^2)
             // where z = 2(x-1)/(x+1)
             // Theoretical peak relative error = 6.16e-22
             static immutable real[4] logR = [
@@ -2996,6 +2997,85 @@  private
                 1.0000000000000000000000E0L,
             ];
         }
+        else static if (floatTraits!T.realFormat == RealFormat.ieeeDouble)
+        {
+            // Coefficients for log(1 + x) = x - x^^2/2 + x^^3 P(x)/Q(x)
+            static immutable double[6] logP = [
+                7.70838733755885391666E0,
+                1.79368678507819816313E1,
+                1.44989225341610930846E1,
+                4.70579119878881725854E0,
+                4.97494994976747001425E-1,
+                1.01875663804580931796E-4,
+            ];
+            static immutable double[6] logQ = [
+                2.31251620126765340583E1,
+                7.11544750618563894466E1,
+                8.29875266912776603211E1,
+                4.52279145837532221105E1,
+                1.12873587189167450590E1,
+                1.00000000000000000000E0,
+            ];
+
+            // log2 uses the same coefficients as log.
+            alias log2P = logP;
+            alias log2Q = logQ;
+
+            // Coefficients for log(1 + x) = x - x^^2/2 + x^^3 P(x)/Q(x)
+            static immutable double[7] log10P = [
+                1.98892446572874072159E1,
+                5.67349287391754285487E1,
+                6.06127134467767258030E1,
+                2.97877425097986925891E1,
+                6.56312093769992875930E0,
+                4.98531067254050724270E-1,
+                4.58482948458143443514E-5,
+            ];
+            static immutable double[7] log10Q = [
+                5.96677339718622216300E1,
+                2.14955586696422947765E2,
+                3.07254189979530058263E2,
+                2.20664384982121929218E2,
+                8.27410449222435217021E1,
+                1.50314182634250003249E1,
+                1.00000000000000000000E0,
+            ];
+
+            // Coefficients for log(x) = z + z^^3 R(z)/S(z)
+            // where z = 2(x-1)/(x+1)
+            static immutable double[3] logR = [
+                -6.41409952958715622951E1,
+                1.63866645699558079767E1,
+                -7.89580278884799154124E-1,
+            ];
+            static immutable double[4] logS = [
+                -7.69691943550460008604E2,
+                3.12093766372244180303E2,
+                -3.56722798256324312549E1,
+                1.00000000000000000000E0,
+            ];
+        }
+        else static if (floatTraits!T.realFormat == RealFormat.ieeeSingle)
+        {
+            // Coefficients for log(1 + x) = x - x^^2/2 + x^^3 P(x)
+            static immutable float[9] logP = [
+                 3.3333331174E-1,
+                -2.4999993993E-1,
+                 2.0000714765E-1,
+                -1.6668057665E-1,
+                 1.4249322787E-1,
+                -1.2420140846E-1,
+                 1.1676998740E-1,
+                -1.1514610310E-1,
+                 7.0376836292E-2,
+            ];
+
+            // log2 and log10 uses the same coefficients as log.
+            alias log2P = logP;
+            alias log10P = logP;
+        }
+        else
+            static assert(0, "no coefficients for log()");
     }
 }
 
@@ -3009,6 +3089,7 @@  private
  *    $(TR $(TD +$(INFIN))    $(TD +$(INFIN)) $(TD no)           $(TD no))
  *    )
  */
+pragma(inline, true)
 real log(real x) @safe pure nothrow @nogc
 {
     version (INLINE_YL2X)
@@ -3020,6 +3101,31 @@  real log(real x) @safe pure nothrow @nogc
         return logImpl(x);
 }
 
+/// ditto
+pragma(inline, true)
+double log(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) log(cast(real) x) : logImpl(x); }
+
+/// ditto
+pragma(inline, true)
+float log(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) log(cast(real) x) : logImpl(x); }
+
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log` called with argument types `(int)` matches both "
+           ~ "`log(real)`, `log(double)`, and `log(float)`. Cast argument to floating point type instead.")
+real log(int x) @safe pure nothrow @nogc { return log(cast(real) x); }
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log` called with argument types `(uint)` matches both "
+           ~ "`log(real)`, `log(double)`, and `log(float)`. Cast argument to floating point type instead.")
+real log(uint x) @safe pure nothrow @nogc { return log(cast(real) x); }
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log` called with argument types `(long)` matches both "
+           ~ "`log(real)`, `log(double)`, and `log(float)`. Cast argument to floating point type instead.")
+real log(long x) @safe pure nothrow @nogc { return log(cast(real) x); }
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log` called with argument types `(ulong)` matches both "
+           ~ "`log(real)`, `log(double)`, and `log(float)`. Cast argument to floating point type instead.")
+real log(ulong x) @safe pure nothrow @nogc { return log(cast(real) x); }
+
 ///
 @safe pure nothrow @nogc unittest
 {
@@ -3034,12 +3140,31 @@  private T logImpl(T)(T x) @safe pure nothrow @nogc
     import std.math.constants : SQRT1_2;
     import std.math.algebraic : poly;
     import std.math.traits : isInfinity, isNaN, signbit;
+    import std.math : floatTraits, RealFormat;
 
     alias coeffs = LogCoeffs!T;
+    alias F = floatTraits!T;
 
-    // C1 + C2 = LN2.
-    enum T C1 = 6.93145751953125E-1L;
-    enum T C2 = 1.428606820309417232121458176568075500134E-6L;
+    static if (F.realFormat == RealFormat.ieeeExtended ||
+               F.realFormat == RealFormat.ieeeExtended53 ||
+               F.realFormat == RealFormat.ieeeQuadruple)
+    {
+        // C1 + C2 = LN2.
+        enum T C1 = 6.93145751953125E-1L;
+        enum T C2 = 1.428606820309417232121458176568075500134E-6L;
+    }
+    else static if (F.realFormat == RealFormat.ieeeDouble)
+    {
+        enum T C1 = 0.693359375;
+        enum T C2 = -2.121944400546905827679e-4;
+    }
+    else static if (F.realFormat == RealFormat.ieeeSingle)
+    {
+        enum T C1 = 0.693359375;
+        enum T C2 = -2.12194440e-4;
+    }
+    else
+        static assert(0, "Not implemented for this architecture");
 
     // Special cases.
     if (isNaN(x))
@@ -3058,30 +3183,36 @@  private T logImpl(T)(T x) @safe pure nothrow @nogc
 
     x = frexp(x, exp);
 
-    // Logarithm using log(x) = z + z^^3 R(z) / S(z),
-    // where z = 2(x - 1)/(x + 1)
-    if ((exp > 2) || (exp < -2))
+    static if (F.realFormat == RealFormat.ieeeDouble ||
+               F.realFormat == RealFormat.ieeeExtended ||
+               F.realFormat == RealFormat.ieeeExtended53 ||
+               F.realFormat == RealFormat.ieeeQuadruple)
     {
-        if (x < SQRT1_2)
-        {   // 2(2x - 1)/(2x + 1)
-            exp -= 1;
-            z = x - 0.5;
-            y = 0.5 * z + 0.5;
-        }
-        else
-        {   // 2(x - 1)/(x + 1)
-            z = x - 0.5;
-            z -= 0.5;
-            y = 0.5 * x  + 0.5;
-        }
-        x = z / y;
-        z = x * x;
-        z = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS));
-        z += exp * C2;
-        z += x;
-        z += exp * C1;
+        // Logarithm using log(x) = z + z^^3 R(z) / S(z),
+        // where z = 2(x - 1)/(x + 1)
+        if ((exp > 2) || (exp < -2))
+        {
+            if (x < SQRT1_2)
+            {   // 2(2x - 1)/(2x + 1)
+                exp -= 1;
+                z = x - 0.5;
+                y = 0.5 * z + 0.5;
+            }
+            else
+            {   // 2(x - 1)/(x + 1)
+                z = x - 0.5;
+                z -= 0.5;
+                y = 0.5 * x  + 0.5;
+            }
+            x = z / y;
+            z = x * x;
+            z = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS));
+            z += exp * C2;
+            z += x;
+            z += exp * C1;
 
-        return z;
+            return z;
+        }
     }
 
     // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x)
@@ -3095,7 +3226,10 @@  private T logImpl(T)(T x) @safe pure nothrow @nogc
         x = x - 1.0;
     }
     z = x * x;
-    y = x * (z * poly(x, coeffs.logP) / poly(x, coeffs.logQ));
+    static if (F.realFormat == RealFormat.ieeeSingle)
+        y = x * (z * poly(x, coeffs.logP));
+    else
+        y = x * (z * poly(x, coeffs.logP) / poly(x, coeffs.logQ));
     y += exp * C2;
     z = y - 0.5 * z;
 
@@ -3117,6 +3251,7 @@  private T logImpl(T)(T x) @safe pure nothrow @nogc
  *      $(TR $(TD +$(INFIN))    $(TD +$(INFIN)) $(TD no)           $(TD no))
  *      )
  */
+pragma(inline, true)
 real log10(real x) @safe pure nothrow @nogc
 {
     version (INLINE_YL2X)
@@ -3128,12 +3263,37 @@  real log10(real x) @safe pure nothrow @nogc
         return log10Impl(x);
 }
 
+/// ditto
+pragma(inline, true)
+double log10(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) log10(cast(real) x) : log10Impl(x); }
+
+/// ditto
+pragma(inline, true)
+float log10(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) log10(cast(real) x) : log10Impl(x); }
+
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log10` called with argument types `(int)` matches both "
+           ~ "`log10(real)`, `log10(double)`, and `log10(float)`. Cast argument to floating point type instead.")
+real log10(int x) @safe pure nothrow @nogc { return log10(cast(real) x); }
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log10` called with argument types `(uint)` matches both "
+           ~ "`log10(real)`, `log10(double)`, and `log10(float)`. Cast argument to floating point type instead.")
+real log10(uint x) @safe pure nothrow @nogc { return log10(cast(real) x); }
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log10` called with argument types `(long)` matches both "
+           ~ "`log10(real)`, `log10(double)`, and `log10(float)`. Cast argument to floating point type instead.")
+real log10(long x) @safe pure nothrow @nogc { return log10(cast(real) x); }
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log10` called with argument types `(ulong)` matches both "
+           ~ "`log10(real)`, `log10(double)`, and `log10(float)`. Cast argument to floating point type instead.")
+real log10(ulong x) @safe pure nothrow @nogc { return log10(cast(real) x); }
+
 ///
 @safe pure nothrow @nogc unittest
 {
     import std.math.algebraic : fabs;
 
-    assert(fabs(log10(1000) - 3) < .000001);
+    assert(fabs(log10(1000.0L) - 3) < .000001);
 }
 
 private T log10Impl(T)(T x) @safe pure nothrow @nogc
@@ -3141,16 +3301,34 @@  private T log10Impl(T)(T x) @safe pure nothrow @nogc
     import std.math.constants : SQRT1_2;
     import std.math.algebraic : poly;
     import std.math.traits : isNaN, isInfinity, signbit;
+    import std.math : floatTraits, RealFormat;
 
     alias coeffs = LogCoeffs!T;
+    alias F = floatTraits!T;
 
-    // log10(2) split into two parts.
-    enum T L102A =  0.3125L;
-    enum T L102B = -1.14700043360188047862611052755069732318101185E-2L;
+    static if (F.realFormat == RealFormat.ieeeExtended ||
+               F.realFormat == RealFormat.ieeeExtended53 ||
+               F.realFormat == RealFormat.ieeeQuadruple)
+    {
+        // log10(2) split into two parts.
+        enum T L102A =  0.3125L;
+        enum T L102B = -1.14700043360188047862611052755069732318101185E-2L;
 
-    // log10(e) split into two parts.
-    enum T L10EA =  0.5L;
-    enum T L10EB = -6.570551809674817234887108108339491770560299E-2L;
+        // log10(e) split into two parts.
+        enum T L10EA =  0.5L;
+        enum T L10EB = -6.570551809674817234887108108339491770560299E-2L;
+    }
+    else static if (F.realFormat == RealFormat.ieeeDouble ||
+                    F.realFormat == RealFormat.ieeeSingle)
+    {
+        enum T L102A =  3.0078125E-1;
+        enum T L102B = 2.48745663981195213739E-4;
+
+        enum T L10EA =  4.3359375E-1;
+        enum T L10EB = 7.00731903251827651129E-4;
+    }
+    else
+        static assert(0, "Not implemented for this architecture");
 
     // Special cases are the same as for log.
     if (isNaN(x))
@@ -3169,26 +3347,31 @@  private T log10Impl(T)(T x) @safe pure nothrow @nogc
 
     x = frexp(x, exp);
 
-    // Logarithm using log(x) = z + z^^3 R(z) / S(z),
-    // where z = 2(x - 1)/(x + 1)
-    if ((exp > 2) || (exp < -2))
-    {
-        if (x < SQRT1_2)
-        {   // 2(2x - 1)/(2x + 1)
-            exp -= 1;
-            z = x - 0.5;
-            y = 0.5 * z + 0.5;
-        }
-        else
-        {   // 2(x - 1)/(x + 1)
-            z = x - 0.5;
-            z -= 0.5;
-            y = 0.5 * x  + 0.5;
+    static if (F.realFormat == RealFormat.ieeeExtended ||
+               F.realFormat == RealFormat.ieeeExtended53 ||
+               F.realFormat == RealFormat.ieeeQuadruple)
+    {
+        // Logarithm using log(x) = z + z^^3 R(z) / S(z),
+        // where z = 2(x - 1)/(x + 1)
+        if ((exp > 2) || (exp < -2))
+        {
+            if (x < SQRT1_2)
+            {   // 2(2x - 1)/(2x + 1)
+                exp -= 1;
+                z = x - 0.5;
+                y = 0.5 * z + 0.5;
+            }
+            else
+            {   // 2(x - 1)/(x + 1)
+                z = x - 0.5;
+                z -= 0.5;
+                y = 0.5 * x  + 0.5;
+            }
+            x = z / y;
+            z = x * x;
+            y = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS));
+            goto Ldone;
         }
-        x = z / y;
-        z = x * x;
-        y = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS));
-        goto Ldone;
     }
 
     // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x)
@@ -3201,7 +3384,10 @@  private T log10Impl(T)(T x) @safe pure nothrow @nogc
         x = x - 1.0;
 
     z = x * x;
-    y = x * (z * poly(x, coeffs.log10P) / poly(x, coeffs.log10Q));
+    static if (F.realFormat == RealFormat.ieeeSingle)
+        y = x * (z * poly(x, coeffs.log10P));
+    else
+        y = x * (z * poly(x, coeffs.log10P) / poly(x, coeffs.log10Q));
     y = y - 0.5 * z;
 
     // Multiply log of fraction by log10(e) and base 2 exponent by log10(2).
@@ -3232,6 +3418,7 @@  Ldone:
  *  $(TR $(TD +$(INFIN))    $(TD +$(INFIN))    $(TD no)           $(TD no))
  *  )
  */
+pragma(inline, true)
 real log1p(real x) @safe pure nothrow @nogc
 {
     version (INLINE_YL2X)
@@ -3245,6 +3432,31 @@  real log1p(real x) @safe pure nothrow @nogc
         return log1pImpl(x);
 }
 
+/// ditto
+pragma(inline, true)
+double log1p(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) log1p(cast(real) x) : log1pImpl(x); }
+
+/// ditto
+pragma(inline, true)
+float log1p(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) log1p(cast(real) x) : log1pImpl(x); }
+
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log1p` called with argument types `(int)` matches both "
+           ~ "`log1p(real)`, `log1p(double)`, and `log1p(float)`. Cast argument to floating point type instead.")
+real log1p(int x) @safe pure nothrow @nogc { return log1p(cast(real) x); }
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log1p` called with argument types `(uint)` matches both "
+           ~ "`log1p(real)`, `log1p(double)`, and `log1p(float)`. Cast argument to floating point type instead.")
+real log1p(uint x) @safe pure nothrow @nogc { return log1p(cast(real) x); }
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log1p` called with argument types `(long)` matches both "
+           ~ "`log1p(real)`, `log1p(double)`, and `log1p(float)`. Cast argument to floating point type instead.")
+real log1p(long x) @safe pure nothrow @nogc { return log1p(cast(real) x); }
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log1p` called with argument types `(ulong)` matches both "
+           ~ "`log1p(real)`, `log1p(double)`, and `log1p(float)`. Cast argument to floating point type instead.")
+real log1p(ulong x) @safe pure nothrow @nogc { return log1p(cast(real) x); }
+
 ///
 @safe pure unittest
 {
@@ -3289,6 +3501,7 @@  private T log1pImpl(T)(T x) @safe pure nothrow @nogc
  *  $(TR $(TD +$(INFIN))    $(TD +$(INFIN)) $(TD no)           $(TD no) )
  *  )
  */
+pragma(inline, true)
 real log2(real x) @safe pure nothrow @nogc
 {
     version (INLINE_YL2X)
@@ -3297,6 +3510,31 @@  real log2(real x) @safe pure nothrow @nogc
         return log2Impl(x);
 }
 
+/// ditto
+pragma(inline, true)
+double log2(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) log2(cast(real) x) : log2Impl(x); }
+
+/// ditto
+pragma(inline, true)
+float log2(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) log2(cast(real) x) : log2Impl(x); }
+
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log2` called with argument types `(int)` matches both "
+           ~ "`log2(real)`, `log2(double)`, and `log2(float)`. Cast argument to floating point type instead.")
+real log2(int x) @safe pure nothrow @nogc { return log2(cast(real) x); }
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log2` called with argument types `(uint)` matches both "
+           ~ "`log2(real)`, `log2(double)`, and `log2(float)`. Cast argument to floating point type instead.")
+real log2(uint x) @safe pure nothrow @nogc { return log2(cast(real) x); }
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log2` called with argument types `(long)` matches both "
+           ~ "`log2(real)`, `log2(double)`, and `log2(float)`. Cast argument to floating point type instead.")
+real log2(long x) @safe pure nothrow @nogc { return log2(cast(real) x); }
+// @@@DEPRECATED_[2.112.0]@@@
+deprecated("`std.math.exponential.log2` called with argument types `(ulong)` matches both "
+           ~ "`log2(real)`, `log2(double)`, and `log2(float)`. Cast argument to floating point type instead.")
+real log2(ulong x) @safe pure nothrow @nogc { return log2(cast(real) x); }
+
 ///
 @safe unittest
 {
@@ -3318,8 +3556,10 @@  private T log2Impl(T)(T x) @safe pure nothrow @nogc
     import std.math.traits : isNaN, isInfinity, signbit;
     import std.math.constants : SQRT1_2, LOG2E;
     import std.math.algebraic : poly;
+    import std.math : floatTraits, RealFormat;
 
     alias coeffs = LogCoeffs!T;
+    alias F = floatTraits!T;
 
     // Special cases are the same as for log.
     if (isNaN(x))
@@ -3338,26 +3578,32 @@  private T log2Impl(T)(T x) @safe pure nothrow @nogc
 
     x = frexp(x, exp);
 
-    // Logarithm using log(x) = z + z^^3 R(z) / S(z),
-    // where z = 2(x - 1)/(x + 1)
-    if ((exp > 2) || (exp < -2))
+    static if (F.realFormat == RealFormat.ieeeDouble ||
+               F.realFormat == RealFormat.ieeeExtended ||
+               F.realFormat == RealFormat.ieeeExtended53 ||
+               F.realFormat == RealFormat.ieeeQuadruple)
     {
-        if (x < SQRT1_2)
-        {   // 2(2x - 1)/(2x + 1)
-            exp -= 1;
-            z = x - 0.5;
-            y = 0.5 * z + 0.5;
-        }
-        else
-        {   // 2(x - 1)/(x + 1)
-            z = x - 0.5;
-            z -= 0.5;
-            y = 0.5 * x  + 0.5;
+        // Logarithm using log(x) = z + z^^3 R(z) / S(z),
+        // where z = 2(x - 1)/(x + 1)
+        if ((exp > 2) || (exp < -2))
+        {
+            if (x < SQRT1_2)
+            {   // 2(2x - 1)/(2x + 1)
+                exp -= 1;
+                z = x - 0.5;
+                y = 0.5 * z + 0.5;
+            }
+            else
+            {   // 2(x - 1)/(x + 1)
+                z = x - 0.5;
+                z -= 0.5;
+                y = 0.5 * x  + 0.5;
+            }
+            x = z / y;
+            z = x * x;
+            y = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS));
+            goto Ldone;
         }
-        x = z / y;
-        z = x * x;
-        y = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS));
-        goto Ldone;
     }
 
     // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x)
@@ -3370,7 +3616,10 @@  private T log2Impl(T)(T x) @safe pure nothrow @nogc
         x = x - 1.0;
 
     z = x * x;
-    y = x * (z * poly(x, coeffs.log2P) / poly(x, coeffs.log2Q));
+    static if (F.realFormat == RealFormat.ieeeSingle)
+        y = x * (z * poly(x, coeffs.log2P));
+    else
+        y = x * (z * poly(x, coeffs.log2P) / poly(x, coeffs.log2Q));
     y = y - 0.5 * z;
 
     // Multiply log of fraction by log10(e) and base 2 exponent by log10(2).
diff --git a/libphobos/src/std/math/operations.d b/libphobos/src/std/math/operations.d
index cb3c805f76f..f2e18005e25 100644
--- a/libphobos/src/std/math/operations.d
+++ b/libphobos/src/std/math/operations.d
@@ -1793,7 +1793,7 @@  if (isFloatingPoint!T)
         }
 
         import std.math.exponential : log2;
-        enum log2_max_exp = cast(int) log2(T.max_exp);
+        enum log2_max_exp = cast(int) log2(T(T.max_exp));
 
         ret.mantissa = ival & ((1L << (T.mant_dig - 1)) - 1);
         ret.exponent = (ival >> (T.mant_dig - 1)) & ((1L << (log2_max_exp + 1)) - 1);
diff --git a/libphobos/src/std/numeric.d b/libphobos/src/std/numeric.d
index df7ac39b4e4..648b70eeea8 100644
--- a/libphobos/src/std/numeric.d
+++ b/libphobos/src/std/numeric.d
@@ -436,7 +436,7 @@  public:
     static @property size_t dig()
     {
         auto shiftcnt = precision - ((flags&Flags.storeNormalized) == 0);
-        return shiftcnt == 64 ? 19 : cast(size_t) log10(1uL << shiftcnt);
+        return shiftcnt == 64 ? 19 : cast(size_t) log10(real(1uL << shiftcnt));
     }
 
     /// Returns: smallest increment to the value 1
diff --git a/libphobos/src/std/parallelism.d b/libphobos/src/std/parallelism.d
index 2c976388d10..9b231f3ac8a 100644
--- a/libphobos/src/std/parallelism.d
+++ b/libphobos/src/std/parallelism.d
@@ -1508,7 +1508,7 @@  public:
 
         if (this.size == 0)
         {
-            return rangeLen;
+            return max(rangeLen, 1);
         }
 
         immutable size_t eightSize = 4 * (this.size + 1);
@@ -3644,6 +3644,15 @@  ParallelForeach!R parallel(R)(R range, size_t workUnitSize)
     assert(arrIndex.sum == 10.iota.sum);
 }
 
+// https://issues.dlang.org/show_bug.cgi?id=22745
+@system unittest
+{
+    auto pool = new TaskPool(0);
+    int[] empty;
+    foreach (i; pool.parallel(empty)) {}
+    pool.finish();
+}
+
 // Thrown when a parallel foreach loop is broken from.
 class ParallelForeachError : Error
 {
@@ -4339,7 +4348,7 @@  version (StdUnittest)
 
     foreach (i, elem; logs)
     {
-        assert(isClose(elem, cast(double) log(i + 1)));
+        assert(isClose(elem, log(double(i + 1))));
     }
 
     assert(poolInstance.amap!"a * a"([1,2,3,4,5]) == [1,4,9,16,25]);
diff --git a/libphobos/src/std/random.d b/libphobos/src/std/random.d
index 9b3c5edfcf0..93be764abd1 100644
--- a/libphobos/src/std/random.d
+++ b/libphobos/src/std/random.d
@@ -2516,7 +2516,7 @@  if (!is(T == enum) && (isIntegral!T || isSomeChar!T))
     assert(rnd.uniform!ulong == 4838462006927449017);
 
     enum Fruit { apple, mango, pear }
-    version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147
+    version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
     assert(rnd.uniform!Fruit == Fruit.mango);
 }
 
@@ -2798,7 +2798,7 @@  auto ref choice(Range)(ref Range range)
     auto rnd = MinstdRand0(42);
 
     auto elem  = [1, 2, 3, 4, 5].choice(rnd);
-    version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147
+    version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
     assert(elem == 3);
 }
 
@@ -2913,7 +2913,7 @@  if (isRandomAccessRange!Range)
     auto rnd = MinstdRand0(42);
 
     auto arr = [1, 2, 3, 4, 5].randomShuffle(rnd);
-    version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147
+    version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
     assert(arr == [3, 5, 2, 4, 1]);
 }
 
@@ -3003,15 +3003,15 @@  if (isRandomAccessRange!Range)
     auto arr = [1, 2, 3, 4, 5, 6];
     arr = arr.dup.partialShuffle(1, rnd);
 
-    version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147
+    version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
     assert(arr == [2, 1, 3, 4, 5, 6]); // 1<->2
 
     arr = arr.dup.partialShuffle(2, rnd);
-    version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147
+    version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
     assert(arr == [1, 4, 3, 2, 5, 6]); // 1<->2, 2<->4
 
     arr = arr.dup.partialShuffle(3, rnd);
-    version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147
+    version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
     assert(arr == [5, 4, 6, 2, 1, 3]); // 1<->5, 2<->4, 3<->6
 }
 
@@ -3428,7 +3428,7 @@  if (isRandomAccessRange!Range)
     import std.range : iota;
     auto rnd = MinstdRand0(42);
 
-    version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147
+    version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
     assert(10.iota.randomCover(rnd).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5]));
 }
 
diff --git a/libphobos/src/std/regex/package.d b/libphobos/src/std/regex/package.d
index 1562d797e88..d6a01e24486 100644
--- a/libphobos/src/std/regex/package.d
+++ b/libphobos/src/std/regex/package.d
@@ -212,7 +212,7 @@  They met on 24/01/1970.
         names work like aliases in addition to direct numbers.
      )
     $(REG_TITLE Assertions, Match position rather than character )
-    $(REG_ROW ^, Matches at the begining of input or line (in multiline mode).)
+    $(REG_ROW ^, Matches at the beginning of input or line (in multiline mode).)
     $(REG_ROW $, Matches at the end of input or line (in multiline mode). )
     $(REG_ROW \b, Matches at word boundary. )
     $(REG_ROW \B, Matches when $(U not) at word boundary. )
diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d
index e83b6171334..25cf9e00841 100644
--- a/libphobos/src/std/typecons.d
+++ b/libphobos/src/std/typecons.d
@@ -225,7 +225,10 @@  public:
     {
         if (_p !is null)
         {
-            destroy(_p);
+            static if (is(T == class) || is(T == interface))
+                destroy(_p);
+            else
+                destroy(*_p);
             _p = null;
         }
     }
@@ -259,7 +262,7 @@  private:
 ///
 @safe unittest
 {
-    static struct S
+    struct S
     {
         int i;
         this(int i){this.i = i;}
@@ -284,6 +287,7 @@  private:
     Unique!S u1;
     assert(u1.isEmpty);
     u1 = produce();
+    assert(u1.i == 5);
     increment(u1);
     assert(u1.i == 6);
     //consume(u1); // Error: u1 is not copyable
@@ -292,6 +296,24 @@  private:
     assert(u1.isEmpty);
 }
 
+@safe unittest
+{
+    int i;
+    struct S
+    {
+        ~this()
+        {
+            // check context pointer still exists - dtor also called before GC frees struct
+            if (this.tupleof[0])
+                i++;
+        }
+    }
+    {
+        Unique!S u = new S;
+    }
+    assert(i == 1);
+}
+
 @system unittest
 {
     // test conversion to base ref
diff --git a/libphobos/testsuite/libphobos.exceptions/refcounted.d b/libphobos/testsuite/libphobos.exceptions/refcounted.d
index 2b7e79bbf39..e4ed8e80ee8 100644
--- a/libphobos/testsuite/libphobos.exceptions/refcounted.d
+++ b/libphobos/testsuite/libphobos.exceptions/refcounted.d
@@ -2,9 +2,9 @@ 
 class E : Exception
 {
     static int instances;
-    this(string msg = "")
+    this(string msg = "", Throwable nextInChain = null)
     {
-        super(msg);
+        super(msg, nextInChain);
         instances++;
     }
 
@@ -93,4 +93,34 @@  void main()
     }
 
     assert(E.instances == 0);
+
+    try
+    {
+        throw new E("first");
+    }
+    catch (E first)
+    {
+        assert(first.refcount == 2);
+        assert(E.instances == 1);
+
+        try
+        {
+            throw new E("second", first);
+        }
+        catch (E second)
+        {
+            assert(first.next is null);
+            assert(second.next is first);
+
+            assert(first.refcount == 3);
+            assert(second.refcount == 2);
+
+            assert(E.instances == 2);
+        }
+
+        assert(first.refcount == 2);
+        assert(E.instances == 1);
+    }
+
+    assert(E.instances == 0);
 }
diff --git a/libphobos/testsuite/libphobos.gc/issue22843.d b/libphobos/testsuite/libphobos.gc/issue22843.d
new file mode 100644
index 00000000000..bf6e830f598
--- /dev/null
+++ b/libphobos/testsuite/libphobos.gc/issue22843.d
@@ -0,0 +1,12 @@ 
+import core.memory;
+void main()
+{
+    auto collections = GC.profileStats().numCollections;
+    // loop until we trigger a collection
+    for (;;)
+    {
+        cast(void)GC.malloc(100_000, GC.BlkAttr.NO_SCAN);
+        if (GC.profileStats().numCollections == collections+1)
+            break;
+    }
+}
diff --git a/libphobos/testsuite/libphobos.shared/finalize.d b/libphobos/testsuite/libphobos.shared/finalize.d
index f31b818e261..fcec87b1aac 100644
--- a/libphobos/testsuite/libphobos.shared/finalize.d
+++ b/libphobos/testsuite/libphobos.shared/finalize.d
@@ -7,9 +7,9 @@  import core.sys.posix.dlfcn;
 void runTest()
 {
     Object obj;
-    obj = Object.factory("lib.MyFinalizer");
+    obj = Object.factory("lib.MyFinalizer");    // { dg-warning "is deprecated" } 
     assert(obj.toString() == "lib.MyFinalizer");
-    obj = Object.factory("lib.MyFinalizerBig");
+    obj = Object.factory("lib.MyFinalizerBig"); // { dg-warning "is deprecated" }
     assert(obj.toString() == "lib.MyFinalizerBig");
 }