Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2218310/?format=api
{ "id": 2218310, "url": "http://patchwork.ozlabs.org/api/patches/2218310/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20260331235807.3584669-1-ibuclaw@gdcproject.org/", "project": { "id": 17, "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api", "name": "GNU Compiler Collection", "link_name": "gcc", "list_id": "gcc-patches.gcc.gnu.org", "list_email": "gcc-patches@gcc.gnu.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260331235807.3584669-1-ibuclaw@gdcproject.org>", "list_archive_url": null, "date": "2026-03-31T23:58:05", "name": "[committed] d: Merge upstream dmd, druntime e7c34c13de, phobos 0c5c9e984.", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "d77ba06e349f89c4ab3c9ee71dc7c8e1e4cba5f5", "submitter": { "id": 46728, "url": "http://patchwork.ozlabs.org/api/people/46728/?format=api", "name": "Iain Buclaw", "email": "ibuclaw@gdcproject.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/20260331235807.3584669-1-ibuclaw@gdcproject.org/mbox/", "series": [ { "id": 498262, "url": "http://patchwork.ozlabs.org/api/series/498262/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=498262", "date": "2026-03-31T23:58:05", "name": "[committed] d: Merge upstream dmd, druntime e7c34c13de, phobos 0c5c9e984.", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/498262/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2218310/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2218310/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "gcc-patches@gcc.gnu.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "gcc-patches@gcc.gnu.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gdcproject.org header.i=@gdcproject.org\n header.a=rsa-sha256 header.s=MBO0001 header.b=K21stVWv;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)", "sourceware.org;\n\tdkim=pass (2048-bit key,\n unprotected) header.d=gdcproject.org header.i=@gdcproject.org\n header.a=rsa-sha256 header.s=MBO0001 header.b=K21stVWv", "sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=gdcproject.org", "sourceware.org; spf=pass smtp.mailfrom=gdcproject.org", "server2.sourceware.org;\n arc=none smtp.remote-ip=80.241.56.151" ], "Received": [ "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fllTb1Vlcz1yCp\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 01 Apr 2026 10:59:29 +1100 (AEDT)", "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id C95394BAD174\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 31 Mar 2026 23:59:27 +0000 (GMT)", "from mout-p-101.mailbox.org (mout-p-101.mailbox.org [80.241.56.151])\n by sourceware.org (Postfix) with ESMTPS id 1B5F04BAD14A\n for <gcc-patches@gcc.gnu.org>; Tue, 31 Mar 2026 23:58:22 +0000 (GMT)", "from smtp202.mailbox.org (smtp202.mailbox.org [10.196.197.202])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mout-p-101.mailbox.org (Postfix) with ESMTPS id 4fllS94fLXz9tkB;\n Wed, 1 Apr 2026 01:58:17 +0200 (CEST)" ], "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 sourceware.org C95394BAD174", "OpenDKIM Filter v2.11.0 sourceware.org 1B5F04BAD14A" ], "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 1B5F04BAD14A", "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 1B5F04BAD14A", "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1775001502; cv=none;\n b=gve325nSy0Pa28U4ow5kriSyAOcwo1A0bPO6buyxAB4qxQKS6D9t4KHdziohXwLDkYiF8BI4Rl8BWc9d0xTzhDGcuFLU1WYRJIDHV6ATuTgpDGJoTeL+aCdMnut6dlMVGQmYsVChvUUBDxMxI2hQMCwRPo02MQU+18iblblIp9A=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1775001502; c=relaxed/simple;\n bh=Q0HrJ6LeWEuB7VufcmraV0GIMyTVcHrGb6RBTeWBhUI=;\n h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version;\n b=xQZaOOCfhnuCVjD1VwfMKcP0utxHqLVoTA+99tsCwhzeDczPOvffaSFHf8oXxDRKIAQ2QhxNSDpxhAglUKOytqzGWKEdmr9l460DiONmcGLyBo98g+0F3Xko5+mXSkun0op9U14gJS1CJ6rxNWkGr2TT0SefOQGPCfumVuBvSSk=", "ARC-Authentication-Results": "i=1; server2.sourceware.org", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gdcproject.org;\n s=MBO0001; t=1775001497;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding;\n bh=gxFnCIRo/bSpwFbFEBGDAH+j0TKY04JMZ3h5r//Wjg8=;\n b=K21stVWvmkZI4eMJ4EqQeHmXukPNzn9eYAMVaMVCQMDjHkTAIrAVmjhBuH4q1O7qnxR2bF\n Ya2HRZkRWhAyojMc4B7IxY1NeNT2KkQp8/YYJObAwqh0HDm4REDp68wkjkAgH9ox++g355\n W7BVZajMR3nxHBH+nGAmRJgJbqNK4IBLB9PTQrTAeU1c6nci1st9lNmtswuX27oSXB6gkr\n ii9Blt5lc/J5QQZ0PoLFZXpRTx1uf4VpL93ORB19s2Q6Whmnd+m1SV/gGZ2VU/yJt/8l7j\n bKJbwn5OsNlwsClxZRNiREQXbGJIEu6MHjnynRcgFk9ZLgVyDe1U9dMeIz2a5Q==", "From": "Iain Buclaw <ibuclaw@gdcproject.org>", "To": "gcc-patches@gcc.gnu.org", "Cc": "Iain Buclaw <ibuclaw@gdcproject.org>", "Subject": "[committed][PATCH] d: Merge upstream dmd, druntime e7c34c13de,\n phobos 0c5c9e984.", "Date": "Wed, 1 Apr 2026 01:58:05 +0200", "Message-ID": "<20260331235807.3584669-1-ibuclaw@gdcproject.org>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "gcc-patches@gcc.gnu.org", "X-Mailman-Version": "2.1.30", "Precedence": "list", "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>", "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>", "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>", "List-Post": "<mailto:gcc-patches@gcc.gnu.org>", "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>", "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>", "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org" }, "content": "Hi,\n\nThis patch merges the D front-end and runtime library with upstream dmd\ne7c34c13de, and the standard library with phobos 0c5c9e984.\n\nThis, now in sync with upstream development as of February 2026.\n\nD front-end changes:\n\n\t- Add support for `with' statements with an expression\n\t initializer.\n\t- Support for default values in bitfields.\n\nPhobos changes:\n\n\t- `std.variant' support for large structs with `@disabled this'.\n\nBootstrapped and regtested on x86_64-linux-gnu, committed to mainline.\n\nRegards,\nIain.\n\n---\ngcc/d/ChangeLog:\n\n\t* dmd/MERGE: Merge upstream dmd e7c34c13de.\n\t* d-codegen.cc (build_vthis): Update for new front-end interface.\n\t(get_frameinfo): Likewise.\n\t* d-lang.cc (d_post_options): Disable null pointer checks.\n\t* decl.cc (DeclVisitor::visit (VarDeclaration *)): Ignore ref noreturn\n\tvariables.\n\nlibphobos/ChangeLog:\n\n\t* libdruntime/MERGE: Merge upstream druntime e7c34c13de.\n\t* src/MERGE: Merge upstream phobos 0c5c9e984.\n\t* testsuite/libphobos.phobos/std_algorithm_comparison.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_algorithm_iteration.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_algorithm_searching.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_array.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_concurrency.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_conv.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_datetime_date.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_datetime_systime.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_math_algebraic.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_meta.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_range_package.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_sumtype.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_traits.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_typecons.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_uuid.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_internal_entropy.d: New test.\n\t* testsuite/libphobos.phobos/std_mathspecial.d: New test.\n---\n gcc/d/d-codegen.cc | 4 +-\n gcc/d/d-lang.cc | 4 +\n gcc/d/decl.cc | 2 +-\n gcc/d/dmd/MERGE | 2 +-\n gcc/d/dmd/cparse.d | 57 ++++-\n gcc/d/dmd/cxxfrontend.d | 18 ++\n gcc/d/dmd/dcast.d | 54 +++-\n gcc/d/dmd/declaration.d | 8 +-\n gcc/d/dmd/declaration.h | 37 +--\n gcc/d/dmd/dmodule.d | 12 +-\n gcc/d/dmd/doc.d | 90 ++++---\n gcc/d/dmd/dscope.d | 3 +-\n gcc/d/dmd/dsymbolsem.d | 97 ++++++--\n gcc/d/dmd/dtoh.d | 1 +\n gcc/d/dmd/expression.d | 2 +\n gcc/d/dmd/expression.h | 1 +\n gcc/d/dmd/expressionsem.d | 166 +++++++++----\n gcc/d/dmd/func.d | 221 -----------------\n gcc/d/dmd/funcsem.d | 231 +++++++++++++++++-\n gcc/d/dmd/globals.d | 16 +-\n gcc/d/dmd/globals.h | 2 +\n gcc/d/dmd/hdrgen.d | 3 +\n gcc/d/dmd/importc.d | 4 +-\n gcc/d/dmd/initsem.d | 20 ++\n gcc/d/dmd/intrange.d | 45 ----\n gcc/d/dmd/module.h | 2 +-\n gcc/d/dmd/nogc.d | 29 ++-\n gcc/d/dmd/opover.d | 2 +-\n gcc/d/dmd/parse.d | 37 +--\n gcc/d/dmd/root/array.d | 27 +-\n gcc/d/dmd/safe.d | 19 +-\n gcc/d/dmd/scope.h | 2 +-\n gcc/d/dmd/semantic2.d | 42 ++++\n gcc/d/dmd/semantic3.d | 26 +-\n gcc/d/dmd/sideeffect.d | 34 +++\n gcc/d/dmd/statement.d | 14 +-\n gcc/d/dmd/statement.h | 1 +\n gcc/d/dmd/statementsem.d | 32 ++-\n gcc/d/dmd/templatesem.d | 56 ++++-\n gcc/d/dmd/traits.d | 4 +-\n gcc/d/dmd/typesem.d | 37 ++-\n .../gdc.test/compilable/alias_param_qual.d | 7 +\n gcc/testsuite/gdc.test/compilable/b12001.d | 4 +\n gcc/testsuite/gdc.test/compilable/depmsg.d | 39 ++-\n .../gdc.test/compilable/deprecationlimit.d | 9 +-\n .../gdc.test/compilable/imports/defines.c | 6 +\n .../gdc.test/compilable/issue22254.d | 6 +\n .../gdc.test/compilable/issue22397.d | 14 ++\n .../gdc.test/compilable/issue22448.d | 8 +\n gcc/testsuite/gdc.test/compilable/test19905.d | 29 +++\n gcc/testsuite/gdc.test/compilable/test22323.d | 12 +\n gcc/testsuite/gdc.test/compilable/test22381.d | 17 ++\n gcc/testsuite/gdc.test/compilable/test22383.d | 12 +\n gcc/testsuite/gdc.test/compilable/test9701.d | 6 +-\n .../gdc.test/compilable/testdefines.d | 6 +\n gcc/testsuite/gdc.test/compilable/zerosize2.d | 178 ++++++++++++++\n .../fail_compilation/array_literal_assign.d | 22 ++\n .../gdc.test/fail_compilation/b23686.d | 2 +-\n .../gdc.test/fail_compilation/biterrors.d | 1 -\n .../gdc.test/fail_compilation/biterrors2.d | 12 +-\n .../gdc.test/fail_compilation/biterrors6.d | 24 ++\n .../gdc.test/fail_compilation/biterrors7.d | 15 ++\n .../gdc.test/fail_compilation/dep_d1_ops.d | 40 +--\n .../gdc.test/fail_compilation/depmsg.d | 60 +++--\n .../gdc.test/fail_compilation/depmsg15814.d | 3 +-\n .../gdc.test/fail_compilation/depmsg15815.d | 3 +-\n .../fail_compilation/deprecatedImports.d | 21 +-\n .../fail_compilation/deprecatedTemplates.d | 4 +\n .../gdc.test/fail_compilation/deprecations.d | 15 +-\n .../gdc.test/fail_compilation/diag14235.d | 7 +-\n .../gdc.test/fail_compilation/diag14875.d | 27 +-\n .../gdc.test/fail_compilation/diag14876.d | 23 +-\n .../gdc.test/fail_compilation/diag16499.d | 4 +-\n .../gdc.test/fail_compilation/diag21167.d | 21 ++\n .../gdc.test/fail_compilation/diag21381.d | 15 ++\n .../gdc.test/fail_compilation/diag21413.d | 15 ++\n .../gdc.test/fail_compilation/fail19202.d | 3 +-\n .../gdc.test/fail_compilation/fail199.d | 6 +-\n .../gdc.test/fail_compilation/fail200.d | 6 +-\n .../gdc.test/fail_compilation/fail20779.d | 2 +-\n .../gdc.test/fail_compilation/fail21830.d | 3 +\n .../gdc.test/fail_compilation/fail21831.d | 3 +\n .../gdc.test/fail_compilation/fail21832.d | 2 +\n .../gdc.test/fail_compilation/fail22384.d | 51 ++++\n .../gdc.test/fail_compilation/fail23822.d | 3 +-\n .../gdc.test/fail_compilation/fail23826.d | 3 +-\n .../gdc.test/fail_compilation/fail243.d | 15 +-\n .../gdc.test/fail_compilation/fail244.d | 30 ++-\n .../gdc.test/fail_compilation/fail245.d | 30 ++-\n .../gdc.test/fail_compilation/fail4206.d | 3 +-\n .../gdc.test/fail_compilation/fail8262.d | 7 +-\n .../gdc.test/fail_compilation/fail8691.d | 2 +-\n .../gdc.test/fail_compilation/fail_opover.d | 2 +-\n .../gdc.test/fail_compilation/ice11822.d | 9 +-\n .../gdc.test/fail_compilation/ice11850.d | 2 +-\n .../gdc.test/fail_compilation/ice11919.d | 5 +-\n .../gdc.test/fail_compilation/issue22394.d | 16 ++\n .../gdc.test/fail_compilation/obsolete_body.d | 6 +-\n .../fail_compilation/struct_rvalue_assign.d | 62 +++++\n .../gdc.test/fail_compilation/test19193.d | 3 +-\n .../gdc.test/fail_compilation/test20515.d | 5 +-\n .../gdc.test/fail_compilation/test21259.d | 12 +-\n .../gdc.test/fail_compilation/test21634.d | 2 +-\n .../gdc.test/fail_compilation/test22397.d | 16 ++\n .../gdc.test/fail_compilation/test23968.d | 3 +-\n .../gdc.test/fail_compilation/test9701b.d | 6 +-\n .../fail_compilation/type_as_initializer.d | 52 ++++\n .../runnable/imports/pragmainline_a.d | 6 +\n gcc/testsuite/gdc.test/runnable/issue20578.d | 14 ++\n gcc/testsuite/gdc.test/runnable/issue22481.d | 18 ++\n gcc/testsuite/gdc.test/runnable/noreturn2.d | 62 ++++-\n .../gdc.test/runnable/pragmainline.d | 7 +\n .../gdc.test/runnable/real_to_float.d | 48 +++-\n gcc/testsuite/gdc.test/runnable/stress.d | 51 ----\n gcc/testsuite/gdc.test/runnable/test22384.d | 49 ++++\n gcc/testsuite/gdc.test/runnable/test22427.d | 40 +++\n gcc/testsuite/gdc.test/runnable/test22489.d | 20 ++\n gcc/testsuite/gdc.test/runnable/test28.d | 5 +-\n gcc/testsuite/gdc.test/runnable/testaa3.d | 10 +\n gcc/testsuite/gdc.test/runnable/uda.d | 17 ++\n gcc/testsuite/gdc.test/runnable/with.d | 15 ++\n libphobos/libdruntime/MERGE | 2 +-\n libphobos/libdruntime/__importc_builtins.di | 2 +-\n libphobos/libdruntime/core/bitop.d | 55 ++++-\n libphobos/libdruntime/core/exception.d | 82 +++++++\n .../libdruntime/core/sys/freebsd/config.d | 3 +-\n .../libdruntime/core/sys/linux/hdlc/ioctl.d | 2 +-\n .../libdruntime/core/sys/linux/net/if_.d | 2 +-\n libphobos/libdruntime/core/sys/posix/signal.d | 4 +-\n .../libdruntime/core/sys/posix/sys/stat.d | 32 +--\n .../libdruntime/core/sys/posix/sys/types.d | 26 +-\n libphobos/libdruntime/core/thread/osthread.d | 147 +++++++----\n libphobos/libdruntime/core/thread/types.d | 3 +\n libphobos/libdruntime/object.d | 3 +-\n libphobos/src/MERGE | 2 +-\n libphobos/src/std/format/spec.d | 26 +-\n libphobos/src/std/functional.d | 22 +-\n .../src/std/internal/math/gammafunction.d | 112 ++++++---\n libphobos/src/std/mathspecial.d | 102 ++++++--\n libphobos/src/std/meta.d | 158 ++++--------\n libphobos/src/std/range/package.d | 50 ++--\n .../src/std/regex/internal/backtracking.d | 22 +-\n libphobos/src/std/regex/internal/tests.d | 4 +\n libphobos/src/std/regex/internal/thompson.d | 14 +-\n libphobos/src/std/socket.d | 64 +++++\n libphobos/src/std/typecons.d | 103 ++++++++\n libphobos/src/std/variant.d | 195 ++++++++++++++-\n .../std_algorithm_comparison.d | 22 +-\n .../std_algorithm_iteration.d | 86 +++++--\n .../std_algorithm_searching.d | 21 +-\n .../testsuite/libphobos.phobos/std_array.d | 16 +-\n .../libphobos.phobos/std_concurrency.d | 17 ++\n .../testsuite/libphobos.phobos/std_conv.d | 25 ++\n .../libphobos.phobos/std_datetime_date.d | 7 +\n .../libphobos.phobos/std_datetime_systime.d | 3 +\n .../libphobos.phobos/std_internal_entropy.d | 82 +++++++\n .../libphobos.phobos/std_math_algebraic.d | 7 +-\n .../libphobos.phobos/std_mathspecial.d | 86 +++++++\n .../testsuite/libphobos.phobos/std_meta.d | 11 +-\n .../libphobos.phobos/std_range_package.d | 45 +++-\n .../testsuite/libphobos.phobos/std_sumtype.d | 26 +-\n .../testsuite/libphobos.phobos/std_traits.d | 36 ++-\n .../testsuite/libphobos.phobos/std_typecons.d | 15 ++\n .../testsuite/libphobos.phobos/std_uuid.d | 59 +++++\n 164 files changed, 3513 insertions(+), 1171 deletions(-)\n create mode 100644 gcc/testsuite/gdc.test/compilable/alias_param_qual.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/issue22254.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/issue22397.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/issue22448.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/test19905.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/test22323.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/test22381.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/test22383.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/zerosize2.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/array_literal_assign.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/biterrors6.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/biterrors7.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/diag21167.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/diag21381.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/diag21413.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail22384.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/issue22394.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/struct_rvalue_assign.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test22397.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/type_as_initializer.d\n create mode 100644 gcc/testsuite/gdc.test/runnable/issue20578.d\n create mode 100644 gcc/testsuite/gdc.test/runnable/issue22481.d\n create mode 100644 gcc/testsuite/gdc.test/runnable/test22384.d\n create mode 100644 gcc/testsuite/gdc.test/runnable/test22427.d\n create mode 100644 gcc/testsuite/gdc.test/runnable/test22489.d\n create mode 100644 gcc/testsuite/gdc.test/runnable/with.d\n create mode 100644 libphobos/testsuite/libphobos.phobos/std_internal_entropy.d\n create mode 100644 libphobos/testsuite/libphobos.phobos/std_mathspecial.d", "diff": "diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc\nindex 791918a1ab5..562a8c7ae26 100644\n--- a/gcc/d/d-codegen.cc\n+++ b/gcc/d/d-codegen.cc\n@@ -2753,7 +2753,7 @@ build_vthis (AggregateDeclaration *decl)\n \t{\n \t tree ffo = get_frameinfo (fdo);\n \t if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo)\n-\t || fdo->hasNestedFrameRefs ())\n+\t || dmd::hasNestedFrameRefs (fdo))\n \t vthis_value = get_frame_for_symbol (decl);\n \t else if (cd != NULL)\n \t {\n@@ -2997,7 +2997,7 @@ get_frameinfo (FuncDeclaration *fd)\n FRAMEINFO_CREATES_FRAME (ffi) = 1;\n FRAMEINFO_IS_CLOSURE (ffi) = 1;\n }\n- else if (fd->hasNestedFrameRefs ())\n+ else if (dmd::hasNestedFrameRefs (fd))\n {\n /* Functions with nested refs must create a static frame for local\n \t variables to be referenced from. */\ndiff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc\nindex 815b1782a65..cbdd3bfdffd 100644\n--- a/gcc/d/d-lang.cc\n+++ b/gcc/d/d-lang.cc\n@@ -886,6 +886,10 @@ d_post_options (const char ** fn)\n \t? CHECKENABLEoff : CHECKENABLEon;\n }\n \n+ /* Checks for `null' pointer dereferences are default off. */\n+ if (global.params.useNullCheck == CHECKENABLEdefault)\n+ global.params.useNullCheck = CHECKENABLEoff;\n+\n /* When not linking against D runtime, turn off all code generation that\n would otherwise reference it. */\n if (global.params.betterC)\ndiff --git a/gcc/d/decl.cc b/gcc/d/decl.cc\nindex b95fd1a2521..fd2b1013a46 100644\n--- a/gcc/d/decl.cc\n+++ b/gcc/d/decl.cc\n@@ -759,7 +759,7 @@ public:\n `assert(0)` if ever read. */\n if (d->type->isTypeNoreturn ())\n {\n-\tif (!d->isDataseg () && !d->isMember ()\n+\tif (!d->isDataseg () && !d->isMember () && !d->isRef ()\n \t && d->_init && !d->_init->isVoidInitializer ())\n \t {\n \t /* Evaluate RHS for side effects first. */\ndiff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE\nindex 423f245b753..434ad554b84 100644\n--- a/gcc/d/dmd/MERGE\n+++ b/gcc/d/dmd/MERGE\n@@ -1,4 +1,4 @@\n-24a41073c2dbf456d4f7a6fe6a7965d6ce6fc5cb\n+e7c34c13de2930f2becc484e12b2c2cf1a16f6e8\n \n The first line of this file holds the git revision number of the last\n merge done from the dlang/dmd repository.\ndiff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d\nindex 0d961e06749..32b4e0146a3 100644\n--- a/gcc/d/dmd/cparse.d\n+++ b/gcc/d/dmd/cparse.d\n@@ -5629,6 +5629,24 @@ final class CParser(AST) : Parser!AST\n ++p; // advance to start of next line\n }\n \n+ /* Create a nullary template function from an expression:\n+ * auto id()() { return exp; }\n+ */\n+ void addNullaryTemplate(AST.Expression exp, Identifier id)\n+ {\n+ auto ret = new AST.ReturnStatement(exp.loc, exp);\n+ auto parameterList = AST.ParameterList(new AST.Parameters(), VarArg.none, STC.none);\n+ STC stc = STC.auto_;\n+ auto tf = new AST.TypeFunction(parameterList, null, LINK.d, stc);\n+ auto fd = new AST.FuncDeclaration(exp.loc, exp.loc, id, stc, tf, 0);\n+ fd.fbody = ret;\n+ AST.Dsymbols* decldefs = new AST.Dsymbols();\n+ decldefs.push(fd);\n+ AST.TemplateParameters* tpl = new AST.TemplateParameters();\n+ auto tempdecl = new AST.TemplateDeclaration(exp.loc, id, tpl, null, decldefs, false);\n+ addSym(tempdecl);\n+ }\n+\n while (p < endp)\n {\n //printf(\"|%s|\\n\", p);\n@@ -5752,6 +5770,32 @@ final class CParser(AST) : Parser!AST\n }\n break;\n \n+ case TOK.identifier:\n+ {\n+ /* Look for:\n+ * #define ID identifier ( args )\n+ * where the macro body is exactly a function-like macro call\n+ * (no additional operators that could cause precedence issues).\n+ * Rewrite to a template function:\n+ * auto ID()() { return identifier(args); }\n+ */\n+ assert(!params); // would be TOK.leftParenthesis\n+ eLatch.sawErrors = false;\n+ auto exp = cparseExpression();\n+ if (eLatch.sawErrors) // parsing errors\n+ break; // abandon this #define\n+ if (token.value != TOK.endOfFile) // did not consume the entire line\n+ break;\n+ // Only allow bare function calls to avoid precedence issues.\n+ // E.g., `#define X FUNC(5)` is safe, but `#define X FUNC(5) + 1`\n+ // would have different semantics in D vs C when used as `X * 2`.\n+ if (!exp.isCallExp())\n+ break;\n+ addNullaryTemplate(exp, id);\n+ ++p;\n+ continue;\n+ }\n+\n case TOK.leftParenthesis:\n {\n /* Look for:\n@@ -5771,18 +5815,7 @@ final class CParser(AST) : Parser!AST\n nextToken();\n if (token.value != TOK.endOfFile)\n break;\n- auto ret = new AST.ReturnStatement(exp.loc, exp);\n- auto parameterList = AST.ParameterList(new AST.Parameters(), VarArg.none, STC.none);\n- STC stc = STC.auto_;\n- auto tf = new AST.TypeFunction(parameterList, null, LINK.d, stc);\n- auto fd = new AST.FuncDeclaration(exp.loc, exp.loc, id, stc, tf, 0);\n- fd.fbody = ret;\n- AST.Dsymbols* decldefs = new AST.Dsymbols();\n- decldefs.push(fd);\n- AST.TemplateParameters* tpl = new AST.TemplateParameters();\n- AST.Expression constraint = null;\n- auto tempdecl = new AST.TemplateDeclaration(exp.loc, id, tpl, constraint, decldefs, false);\n- addSym(tempdecl);\n+ addNullaryTemplate(exp, id);\n ++p;\n continue;\n }\ndiff --git a/gcc/d/dmd/cxxfrontend.d b/gcc/d/dmd/cxxfrontend.d\nindex e29fe28f6c4..b4524a465bc 100644\n--- a/gcc/d/dmd/cxxfrontend.d\n+++ b/gcc/d/dmd/cxxfrontend.d\n@@ -529,6 +529,24 @@ bool needsClosure(FuncDeclaration fd)\n return dmd.funcsem.needsClosure(fd);\n }\n \n+bool hasNestedFrameRefs(FuncDeclaration fd)\n+{\n+ import dmd.funcsem;\n+ return dmd.funcsem.hasNestedFrameRefs(fd);\n+}\n+\n+bool isVirtualMethod(FuncDeclaration fd)\n+{\n+ import dmd.funcsem;\n+ return dmd.funcsem.isVirtualMethod(fd);\n+}\n+\n+bool isVirtual(const FuncDeclaration fd)\n+{\n+ import dmd.funcsem;\n+ return dmd.funcsem.isVirtual(fd);\n+}\n+\n /***********************************************************\n * hdrgen.d\n */\ndiff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d\nindex 73cfca8a5d1..66c0b8a8c20 100644\n--- a/gcc/d/dmd/dcast.d\n+++ b/gcc/d/dmd/dcast.d\n@@ -50,6 +50,50 @@ import dmd.typesem;\n \n enum LOG = false;\n \n+IntRange _cast(IntRange _this, Type type)\n+{\n+ if (!type.isIntegral() || type.toBasetype().isTypeVector())\n+ return _this;\n+ if (!type.isUnsigned())\n+ return _this.castSigned(type.sizemask());\n+ if (type.toBasetype().ty == Tdchar)\n+ return _this.castDchar();\n+ return _this.castUnsigned(type.sizemask());\n+}\n+\n+IntRange castUnsigned(IntRange _this, Type type)\n+{\n+ if (!type.isIntegral() || type.toBasetype().isTypeVector())\n+ return _this.castUnsigned(ulong.max);\n+ if (type.toBasetype().ty == Tdchar)\n+ return _this.castDchar();\n+ return _this.castUnsigned(type.sizemask());\n+}\n+\n+IntRange intRangeFromType(Type type)\n+{\n+ return intRangeFromType(type, type.isUnsigned());\n+}\n+\n+IntRange intRangeFromType(Type type, bool isUnsigned)\n+{\n+ if (!type.isIntegral() || type.toBasetype().isTypeVector())\n+ return IntRange.widest();\n+\n+ uinteger_t mask = type.sizemask();\n+ auto lower = SignExtendedNumber(0);\n+ auto upper = SignExtendedNumber(mask);\n+ if (type.toBasetype().ty == Tdchar)\n+ upper.value = 0x10FFFFUL;\n+ else if (!isUnsigned)\n+ {\n+ lower.value = ~(mask >> 1);\n+ lower.negative = true;\n+ upper.value = (mask >> 1);\n+ }\n+ return IntRange(lower, upper);\n+}\n+\n /**\n * Attempt to implicitly cast the expression into type `t`.\n *\n@@ -304,7 +348,7 @@ MATCH implicitConvTo(Expression e, Type t)\n if (e.type.isIntegral() && t.isIntegral() && e.type.isTypeBasic() && t.isTypeBasic())\n {\n IntRange src = getIntRange(e);\n- IntRange target = IntRange.fromType(t);\n+ IntRange target = intRangeFromType(t);\n if (target.contains(src))\n {\n return MATCH.convert;\n@@ -4358,7 +4402,7 @@ IntRange getIntRange(Expression e)\n {\n IntRange visit(Expression e)\n {\n- return IntRange.fromType(e.type);\n+ return intRangeFromType(e.type);\n }\n \n IntRange visitInteger(IntegerExp e)\n@@ -4462,7 +4506,7 @@ IntRange getIntRange(Expression e)\n \n IntRange visitUshr(UshrExp e)\n {\n- IntRange ir1 = getIntRange(e.e1).castUnsigned(e.e1.type);\n+ IntRange ir1 = castUnsigned(getIntRange(e.e1), e.e1.type);\n IntRange ir2 = getIntRange(e.e2);\n \n return (ir1 >>> ir2)._cast(e.type);\n@@ -4486,7 +4530,7 @@ IntRange getIntRange(Expression e)\n Expression ie;\n VarDeclaration vd = e.var.isVarDeclaration();\n if (vd && vd.range)\n- return vd.range._cast(e.type);\n+ return _cast(*vd.range, e.type);\n if (vd && vd._init && !vd.type.isMutable() && (ie = vd.getConstInitializer()) !is null)\n return getIntRange(ie);\n return visit(e);\n@@ -4541,7 +4585,7 @@ IntRange getIntRange(Expression e)\n * However, the dmd backend does not like a naive cast from a noreturn expression\n * (particularly an `assert(0)`) so this function generates:\n *\n- * `(assert(0), value)` instead of `cast(to)(assert(0))`.\n+ * `(value, assert(0))` instead of `cast(to)(assert(0))`.\n *\n * `value` is currently `to.init` however it cannot be read so could be made simpler.\n * Params:\ndiff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d\nindex 537e51e9a69..d9eab5b7642 100644\n--- a/gcc/d/dmd/declaration.d\n+++ b/gcc/d/dmd/declaration.d\n@@ -421,6 +421,8 @@ extern (C++) final class OverDeclaration : Declaration\n }\n \n /***********************************************************\n+ * Note: dsymbolSemantic turns a VarDeclaration inside a function into\n+ * AssignExp(e1: VarExp, e2: ConstructExp or BlitExp).\n */\n extern (C++) class VarDeclaration : Declaration\n {\n@@ -663,9 +665,9 @@ extern (C++) class BitFieldDeclaration : VarDeclaration\n uint fieldWidth;\n uint bitOffset;\n \n- final extern (D) this(Loc loc, Type type, Identifier ident, Expression width)\n+ final extern (D) this(Loc loc, Type type, Identifier ident, Expression width, Initializer _init = null)\n {\n- super(loc, type, ident, null);\n+ super(loc, type, ident, _init);\n this.dsym = DSYM.bitFieldDeclaration;\n this.width = width;\n this.storage_class |= STC.field;\n@@ -675,7 +677,7 @@ extern (C++) class BitFieldDeclaration : VarDeclaration\n {\n //printf(\"BitFieldDeclaration::syntaxCopy(%s)\\n\", toChars());\n assert(!s);\n- auto bf = new BitFieldDeclaration(loc, type ? type.syntaxCopy() : null, ident, width.syntaxCopy());\n+ auto bf = new BitFieldDeclaration(loc, type ? type.syntaxCopy() : null, ident, width.syntaxCopy(), _init ? _init.syntaxCopy() : null);\n bf.comment = comment;\n return bf;\n }\ndiff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h\nindex 612c5de5b35..759e533543d 100644\n--- a/gcc/d/dmd/declaration.h\n+++ b/gcc/d/dmd/declaration.h\n@@ -43,6 +43,9 @@ namespace dmd\n bool isAbstract(ClassDeclaration *cd);\n bool overloadInsert(Dsymbol *ds, Dsymbol *s);\n bool equals(const Dsymbol * const ds, const Dsymbol * const s);\n+ bool hasNestedFrameRefs(FuncDeclaration *fd);\n+ bool isVirtualMethod(FuncDeclaration *fd);\n+ bool isVirtual(const FuncDeclaration *fd);\n }\n \n //enum STC : ulong from astenums.d:\n@@ -714,13 +717,9 @@ public:\n virtual bool isNested() const;\n AggregateDeclaration *isThis() override;\n bool needThis() override final;\n- bool isVirtualMethod();\n- virtual bool isVirtual() const;\n+ bool isVirtual() const { return dmd::isVirtual(this); };\n bool isFinalFunc() const;\n- virtual bool addPreInvariant();\n- virtual bool addPostInvariant();\n const char *kind() const override;\n- bool hasNestedFrameRefs();\n ParameterList getParameterList();\n \n virtual FuncDeclaration *toAliasFunc() { return this; }\n@@ -751,9 +750,6 @@ public:\n FuncLiteralDeclaration *syntaxCopy(Dsymbol *) override;\n bool isNested() const override;\n AggregateDeclaration *isThis() override;\n- bool isVirtual() const override;\n- bool addPreInvariant() override;\n- bool addPostInvariant() override;\n \n const char *kind() const override;\n const char *toPrettyChars(bool QualifyTypes = false) override;\n@@ -767,9 +763,6 @@ public:\n d_bool isMoveCtor;\n CtorDeclaration *syntaxCopy(Dsymbol *) override;\n const char *kind() const override;\n- bool isVirtual() const override;\n- bool addPreInvariant() override;\n- bool addPostInvariant() override;\n \n void accept(Visitor *v) override { v->visit(this); }\n };\n@@ -778,9 +771,6 @@ class PostBlitDeclaration final : public FuncDeclaration\n {\n public:\n PostBlitDeclaration *syntaxCopy(Dsymbol *) override;\n- bool isVirtual() const override;\n- bool addPreInvariant() override;\n- bool addPostInvariant() override;\n \n void accept(Visitor *v) override { v->visit(this); }\n };\n@@ -790,9 +780,6 @@ class DtorDeclaration final : public FuncDeclaration\n public:\n DtorDeclaration *syntaxCopy(Dsymbol *) override;\n const char *kind() const override;\n- bool isVirtual() const override;\n- bool addPreInvariant() override;\n- bool addPostInvariant() override;\n \n void accept(Visitor *v) override { v->visit(this); }\n };\n@@ -802,9 +789,6 @@ class StaticCtorDeclaration : public FuncDeclaration\n public:\n StaticCtorDeclaration *syntaxCopy(Dsymbol *) override;\n AggregateDeclaration *isThis() override final;\n- bool isVirtual() const override final;\n- bool addPreInvariant() override final;\n- bool addPostInvariant() override final;\n \n void accept(Visitor *v) override { v->visit(this); }\n };\n@@ -825,9 +809,6 @@ public:\n \n StaticDtorDeclaration *syntaxCopy(Dsymbol *) override;\n AggregateDeclaration *isThis() override final;\n- bool isVirtual() const override final;\n- bool addPreInvariant() override final;\n- bool addPostInvariant() override final;\n \n void accept(Visitor *v) override { v->visit(this); }\n };\n@@ -844,9 +825,7 @@ class InvariantDeclaration final : public FuncDeclaration\n {\n public:\n InvariantDeclaration *syntaxCopy(Dsymbol *) override;\n- bool isVirtual() const override;\n- bool addPreInvariant() override;\n- bool addPostInvariant() override;\n+\n \n void accept(Visitor *v) override { v->visit(this); }\n };\n@@ -861,9 +840,6 @@ public:\n \n UnitTestDeclaration *syntaxCopy(Dsymbol *) override;\n AggregateDeclaration *isThis() override;\n- bool isVirtual() const override;\n- bool addPreInvariant() override;\n- bool addPostInvariant() override;\n \n void accept(Visitor *v) override { v->visit(this); }\n };\n@@ -873,9 +849,6 @@ class NewDeclaration final : public FuncDeclaration\n public:\n NewDeclaration *syntaxCopy(Dsymbol *) override;\n const char *kind() const override;\n- bool isVirtual() const override;\n- bool addPreInvariant() override;\n- bool addPostInvariant() override;\n \n void accept(Visitor *v) override { v->visit(this); }\n };\ndiff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d\nindex 4ddbe925ab8..1baf39b0751 100644\n--- a/gcc/d/dmd/dmodule.d\n+++ b/gcc/d/dmd/dmodule.d\n@@ -26,7 +26,6 @@ import dmd.compiler;\n import dmd.cparse;\n import dmd.declaration;\n import dmd.dmacro;\n-import dmd.doc;\n import dmd.dsymbol;\n import dmd.errors;\n import dmd.expression;\n@@ -394,7 +393,7 @@ extern (C++) final class Module : Package\n Identifiers* versionidsNot; // forward referenced version identifiers\n \n MacroTable macrotable; // document comment macros\n- Escape* _escapetable; // document comment escapes\n+ void* _escapetable; // document comment escapes (Escape*)\n \n size_t nameoffset; // offset of module name from start of ModuleInfo\n size_t namelen; // length of module name in characters\n@@ -1020,15 +1019,6 @@ extern (C++) final class Module : Package\n }\n }\n \n- /** Lazily initializes and returns the escape table.\n- Turns out it eats a lot of memory.\n- */\n- extern(D) Escape* escapetable() nothrow\n- {\n- if (!_escapetable)\n- _escapetable = new Escape();\n- return _escapetable;\n- }\n }\n \n /***********************************************************\ndiff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d\nindex ada57729b06..fe887f91d93 100644\n--- a/gcc/d/dmd/doc.d\n+++ b/gcc/d/dmd/doc.d\n@@ -53,6 +53,7 @@ import dmd.root.utf;\n import dmd.tokens;\n import dmd.visitor;\n \n+\n /****************************************************\n * Generate Ddoc text for Module `m` and append it to `outbuf`.\n * Params:\n@@ -212,44 +213,6 @@ void gendocfile(Module m, const char* ddoctext_ptr, size_t ddoctext_length, cons\n gendocfile(m, ddoctext_ptr[0 .. ddoctext_length], datetime, eSink, outbuf);\n }\n \n-public\n-struct Escape\n-{\n- const(char)[][char.max] strings;\n-\n- /***************************************\n- * Find character string to replace c with.\n- */\n- const(char)[] escapeChar(char c) @safe\n- {\n- version (all)\n- {\n- //printf(\"escapeChar('%c') => %p, %p\\n\", c, strings, strings[c].ptr);\n- return strings[c];\n- }\n- else\n- {\n- const(char)[] s;\n- switch (c)\n- {\n- case '<':\n- s = \"<\";\n- break;\n- case '>':\n- s = \">\";\n- break;\n- case '&':\n- s = \"&\";\n- break;\n- default:\n- s = null;\n- break;\n- }\n- return s;\n- }\n- }\n-}\n-\n /***********************************************************\n */\n public\n@@ -660,6 +623,53 @@ struct DocComment\n \n private:\n \n+/** Lazily initializes and returns the escape table.\n+Turns out it eats a lot of memory.\n+*/\n+Escape* escapetable(Module _this) nothrow\n+{\n+ if (!_this._escapetable)\n+ _this._escapetable = new Escape();\n+ return cast(Escape*) _this._escapetable;\n+}\n+\n+struct Escape\n+{\n+ const(char)[][char.max] strings;\n+\n+ /***************************************\n+ * Find character string to replace c with.\n+ */\n+ const(char)[] escapeChar(char c) @safe\n+ {\n+ version (all)\n+ {\n+ //printf(\"escapeChar('%c') => %p, %p\\n\", c, strings, strings[c].ptr);\n+ return strings[c];\n+ }\n+ else\n+ {\n+ const(char)[] s;\n+ switch (c)\n+ {\n+ case '<':\n+ s = \"<\";\n+ break;\n+ case '>':\n+ s = \">\";\n+ break;\n+ case '&':\n+ s = \"&\";\n+ break;\n+ default:\n+ s = null;\n+ break;\n+ }\n+ return s;\n+ }\n+ }\n+}\n+\n /***********************************************************\n */\n class Section\n@@ -1381,11 +1391,11 @@ void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)\n {\n if (s && sc.lastdc && isDitto(com))\n {\n- sc.lastdc.a.push(s);\n+ (cast(DocComment*) sc.lastdc).a.push(s);\n return;\n }\n // Put previous doc comment if exists\n- if (DocComment* dc = sc.lastdc)\n+ if (auto dc = cast(DocComment*) sc.lastdc)\n {\n assert(dc.a.length > 0, \"Expects at least one declaration for a\" ~\n \"documentation comment\");\ndiff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d\nindex 71442c48ba2..f6be0f82730 100644\n--- a/gcc/d/dmd/dscope.d\n+++ b/gcc/d/dmd/dscope.d\n@@ -22,7 +22,6 @@ import dmd.ctorflow;\n import dmd.dclass;\n import dmd.declaration;\n import dmd.dmodule;\n-import dmd.doc;\n import dmd.dstruct;\n import dmd.dsymbol;\n import dmd.dtemplate;\n@@ -190,7 +189,7 @@ extern (C++) struct Scope\n // user defined attributes\n UserAttributeDeclaration userAttribDecl;\n \n- DocComment* lastdc; /// documentation comment for last symbol at this scope\n+ void* lastdc; /// documentation comment for last symbol at this scope (DocComment*)\n uint[void*] anchorCounts; /// lookup duplicate anchor name count\n Identifier prevAnchor; /// qualified symbol name of last doc anchor\n \ndiff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d\nindex b9afe212688..3e372b58e99 100644\n--- a/gcc/d/dmd/dsymbolsem.d\n+++ b/gcc/d/dmd/dsymbolsem.d\n@@ -1613,6 +1613,8 @@ bool checkDeprecated(Dsymbol d, Loc loc, Scope* sc)\n else\n deprecation(loc, \"%s `%s` is deprecated\", d.kind, d.toPrettyChars);\n \n+ deprecationSupplemental(d.loc, \"`%s` is declared here\", d.toErrMsg);\n+\n if (auto ti = sc.parent ? sc.parent.isInstantiated() : null)\n ti.printInstantiationTrace(Classification.deprecation);\n else if (auto ti = sc.parent ? sc.parent.isTemplateInstance() : null)\n@@ -2479,7 +2481,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor\n if (i == 0)\n einit = Expression.combine(te.e0, einit);\n }\n- ti = new ExpInitializer(einit.loc, einit);\n+ // Use the original initializer location, not the tuple element's location,\n+ // so error messages point to the declaration site\n+ ti = new ExpInitializer(dsym._init ? dsym._init.loc : einit.loc, einit);\n }\n else\n ti = dsym._init ? dsym._init.syntaxCopy() : null;\n@@ -3174,6 +3178,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor\n if (dsym.semanticRun >= PASS.semanticdone)\n return;\n \n+ const bool isAnonymous = dsym.isAnonymous();\n+ if (isAnonymous && dsym._init)\n+ {\n+ .error(dsym._init.loc, \"anonymous bitfield cannot have default initializer\");\n+ dsym._init = null;\n+ dsym.errors = true;\n+ }\n+\n visit(cast(VarDeclaration)dsym);\n if (dsym.errors)\n return;\n@@ -3195,8 +3207,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor\n if (!dsym.type.isIntegral())\n {\n // C11 6.7.2.1-5\n- error(width.loc, \"bitfield type `%s` is not an integer type\", dsym.type.toChars());\n+ if (isAnonymous)\n+ error(dsym.loc, \"anonymous bitfield cannot be of non-integral type `%s`\", dsym.type.toChars());\n+ else\n+ error(dsym.loc, \"bitfield `%s` cannot be of non-integral type `%s`\", dsym.toChars(), dsym.type.toChars());\n dsym.errors = true;\n+ return;\n }\n if (!width.isIntegerExp())\n {\n@@ -3204,20 +3220,34 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor\n dsym.errors = true;\n }\n const uwidth = width.toInteger(); // uwidth is unsigned\n- if (uwidth == 0 && !dsym.isAnonymous())\n+ if (uwidth == 0 && !isAnonymous)\n {\n- error(width.loc, \"bitfield `%s` has zero width\", dsym.toChars());\n+ error(dsym.loc, \"bitfield `%s` cannot have zero width\", dsym.toChars());\n dsym.errors = true;\n }\n- const sz = dsym.type.size();\n- if (sz == SIZE_INVALID)\n- dsym.errors = true;\n- const max_width = sz * 8;\n- if (uwidth > max_width)\n+ if (cast(long)uwidth < 0)\n {\n- error(width.loc, \"width `%lld` of bitfield `%s` does not fit in type `%s`\", cast(long)uwidth, dsym.toChars(), dsym.type.toChars());\n+ if (isAnonymous)\n+ error(width.loc, \"anonymous bitfield has negative width `%lld`\", cast(long)uwidth);\n+ else\n+ error(width.loc, \"bitfield `%s` has negative width `%lld`\", dsym.toChars(), cast(long)uwidth);\n dsym.errors = true;\n }\n+ else\n+ {\n+ const sz = dsym.type.size();\n+ if (sz == SIZE_INVALID)\n+ dsym.errors = true;\n+ const max_width = sz * 8;\n+ if (uwidth > max_width)\n+ {\n+ if (isAnonymous)\n+ error(width.loc, \"width `%lld` of anonymous bitfield does not fit in type `%s`\", cast(long)uwidth, dsym.type.toChars());\n+ else\n+ error(width.loc, \"width `%lld` of bitfield `%s` does not fit in type `%s`\", cast(long)uwidth, dsym.toChars(), dsym.type.toChars());\n+ dsym.errors = true;\n+ }\n+ }\n dsym.fieldWidth = cast(uint)uwidth;\n }\n \n@@ -7040,10 +7070,20 @@ bool determineFields(AggregateDeclaration ad)\n {\n if (ad == tvs.sym)\n {\n+ if (ad.type.ty == Terror || ad.errors)\n+ return 1; // failed already\n+\n const(char)* psz = (v.type.toBasetype().ty == Tsarray) ? \"static array of \" : \"\";\n- .error(ad.loc, \"%s `%s` cannot have field `%s` with %ssame struct type\", ad.kind, ad.toPrettyChars, v.toChars(), psz);\n- ad.type = Type.terror;\n- ad.errors = true;\n+ if (!v.isAnonymous())\n+ .error(v.loc, \"%s `%s` cannot have field `%s` with %ssame struct type\", ad.kind, ad.toPrettyChars, v.toChars(), psz);\n+ else\n+ .error(v.loc, \"%s `%s` cannot have anonymous field with %ssame struct type\", ad.kind, ad.toPrettyChars, psz);\n+ // Don't cache errors from speculative semantic\n+ if (!global.gag)\n+ {\n+ ad.type = Type.terror;\n+ ad.errors = true;\n+ }\n return 1;\n }\n }\n@@ -8398,8 +8438,8 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor\n ad.structsize, ad.alignsize,\n isunion);\n \n- //printf(\"\\t%s: memalignsize = %d\\n\", toChars(), memalignsize);\n- //printf(\" addField '%s' to '%s' at offset %d, size = %d\\n\", toChars(), ad.toChars(), offset, memsize);\n+ //printf(\"\\t%s: memalignsize = %d\\n\", vd.toChars(), memalignsize);\n+ //printf(\" addField '%s' to '%s' at offset %d, size = %d\\n\", vd.toChars(), ad.toChars(), fieldState.offset, memsize);\n }\n \n override void visit(BitFieldDeclaration bfd)\n@@ -8433,10 +8473,9 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor\n uint memalignsize = target.fieldalign(t); // size of member for alignment purposes\n if (log) printf(\" memsize: %u memalignsize: %u\\n\", memsize, memalignsize);\n \n- if (bfd.fieldWidth == 0 && !anon)\n- error(bfd.loc, \"named bit fields cannot have 0 width\");\n- if (bfd.fieldWidth > memsize * 8)\n- error(bfd.loc, \"bit field width %d is larger than type\", bfd.fieldWidth);\n+ // Handled in dsymbolSemantic as errors\n+ assert(bfd.fieldWidth != 0 || anon, \"named bit fields cannot have 0 width\");\n+ assert(bfd.fieldWidth <= memsize * 8, \"bit field width is larger than type\");\n \n const style = target.c.bitFieldStyle;\n if (style != TargetC.BitFieldStyle.MS && style != TargetC.BitFieldStyle.Gcc_Clang)\n@@ -9921,7 +9960,7 @@ private extern(C++) class FinalizeSizeVisitor : Visitor\n \n override void visit(StructDeclaration sd)\n {\n- //printf(\"StructDeclaration::finalizeSize() %s, sizeok = %d\\n\", toChars(), sizeok);\n+ //printf(\"StructDeclaration::finalizeSize() %s, sizeok = %d\\n\", sd.toChars(), sd.sizeok);\n assert(sd.sizeok != Sizeok.done);\n \n if (sd.sizeok == Sizeok.inProcess)\n@@ -9952,16 +9991,30 @@ private extern(C++) class FinalizeSizeVisitor : Visitor\n if (sd.structsize == 0)\n {\n sd.hasNoFields = true;\n- sd.alignsize = 1;\n+\n+ // alignsize has already been set when the struct consists only of\n+ // zero sized fields.\n+ if (sd.alignsize == 0)\n+ sd.alignsize = 1;\n \n // A fine mess of what size a zero sized struct should be\n final switch (sd.classKind)\n {\n case ClassKind.d:\n- case ClassKind.cpp:\n sd.structsize = 1;\n break;\n \n+ case ClassKind.cpp:\n+ if (sd.fields.length == 0 ||\n+ target.c.bitFieldStyle == TargetC.BitFieldStyle.MS)\n+ {\n+ // Give struct a size when there's no named fields\n+ sd.structsize = 1;\n+ }\n+ else\n+ sd.structsize = 0;\n+ break;\n+\n case ClassKind.c:\n case ClassKind.objc:\n if (target.c.bitFieldStyle == TargetC.BitFieldStyle.MS)\ndiff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d\nindex 933f0f12ae6..10a4824d57c 100644\n--- a/gcc/d/dmd/dtoh.d\n+++ b/gcc/d/dmd/dtoh.d\n@@ -21,6 +21,7 @@ import dmd.arraytypes;\n import dmd.dsymbolsem;\n import dmd.templatesem : computeOneMember;\n import dmd.expressionsem : toInteger;\n+import dmd.funcsem : isVirtual;\n import dmd.errors;\n import dmd.errorsink;\n import dmd.globals;\ndiff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d\nindex 98d1a8ee34d..f5fbf805de1 100644\n--- a/gcc/d/dmd/expression.d\n+++ b/gcc/d/dmd/expression.d\n@@ -2137,6 +2137,7 @@ extern (C++) final class ImportExp : UnaExp\n extern (C++) final class AssertExp : UnaExp\n {\n Expression msg;\n+ Expression loweredFrom;\n \n extern (D) this(Loc loc, Expression e, Expression msg = null) @safe\n {\n@@ -2362,6 +2363,7 @@ extern (C++) final class CallExp : UnaExp\n bool inDebugStatement; /// true if this was in a debug statement\n bool ignoreAttributes; /// don't enforce attributes (e.g. call @gc function in @nogc code)\n bool isUfcsRewrite; /// the first argument was pushed in here by a UFCS rewrite\n+ bool fromOpAssignment; // set when operator overload method call from assignment (2024 edition)\n VarDeclaration vthis2; // container for multi-context\n Expression loweredFrom; // set if this is the result of a lowering\n \ndiff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h\nindex d6577d6451a..a8e1c9fb921 100644\n--- a/gcc/d/dmd/expression.h\n+++ b/gcc/d/dmd/expression.h\n@@ -671,6 +671,7 @@ class AssertExp final : public UnaExp\n {\n public:\n Expression *msg;\n+ Expression* loweredFrom;\n \n AssertExp *syntaxCopy() override;\n \ndiff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d\nindex 4c564b77617..3dec8c5e749 100644\n--- a/gcc/d/dmd/expressionsem.d\n+++ b/gcc/d/dmd/expressionsem.d\n@@ -1463,6 +1463,10 @@ extern (D) Expression incompatibleTypes(BinExp e, Scope* sc = null)\n error(e.loc, \"incompatible types for `(%s) %s (%s)`: `%s` and `%s`\",\n e.e1.toErrMsg(), thisOp, e.e2.toErrMsg(), ts[0], ts[1]);\n }\n+\n+ if (sc && sc.tinst)\n+ sc.tinst.printInstantiationTrace();\n+\n return ErrorExp.get();\n }\n \n@@ -2064,19 +2068,38 @@ Returns:\n \n Expression checkNoreturnVarAccess(Expression exp)\n {\n- assert(exp.type);\n+ assert(exp);\n \n- Expression result = exp;\n- if (exp.type.isTypeNoreturn() && !exp.isAssertExp() &&\n- !exp.isThrowExp() && !exp.isCallExp())\n+ switch (exp.op)\n {\n+ case EXP.assert_:\n+ case EXP.throw_:\n+ case EXP.call:\n+ return exp;\n+\n+ case EXP.question:\n+ CondExp ce = cast(CondExp)exp;\n+ ce.e1 = checkNoreturnVarAccess(ce.e1);\n+ ce.e2 = checkNoreturnVarAccess(ce.e2);\n+ return ce;\n+\n+ case EXP.comma:\n+ CommaExp ce = cast(CommaExp)exp;\n+ ce.e1 = checkNoreturnVarAccess(ce.e1);\n+ ce.e2 = checkNoreturnVarAccess(ce.e2);\n+ return ce;\n+\n+ default:\n+ if (!exp.type || !exp.type.isTypeNoreturn())\n+ return exp;\n+\n auto msg = new StringExp(exp.loc, \"Accessed expression of type `noreturn`\");\n msg.type = Type.tstring;\n- result = new AssertExp(exp.loc, IntegerExp.literal!0, msg);\n- result.type = exp.type;\n+ auto ae = new AssertExp(exp.loc, IntegerExp.literal!0, msg);\n+ ae.loweredFrom = exp;\n+ ae.type = exp.type;\n+ return ae;\n }\n-\n- return result;\n }\n \n /******************************\n@@ -4187,6 +4210,10 @@ private bool functionParameters(Loc loc, Scope* sc,\n arg = arg.resolveLoc(loc, sc);\n (*arguments)[i] = arg;\n }\n+ else if (!(p.storageClass & (STC.ref_ | STC.out_)))\n+ {\n+ (*arguments)[i] = checkNoreturnVarAccess(arg);\n+ }\n \n if (tf.parameterList.varargs == VarArg.typesafe && i + 1 == nparams) // https://dlang.org/spec/function.html#variadic\n {\n@@ -5274,6 +5301,17 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n setError();\n }\n \n+ // `e` calls opAssign, opOpAssign, opUnary!++, opUnary!-- when lowered from an assignment\n+ private void setOpOverloadAssign(Expression e)\n+ {\n+ result = e;\n+ auto ce = e.isCallExp();\n+ // rvalue error in discardValue from 2024 edition\n+ if (!ce || !sc.hasEdition(Edition.v2024))\n+ return;\n+ ce.fromOpAssignment = true;\n+ }\n+\n /**************************\n * Semantically analyze Expression.\n * Determine types, fold constants, etc.\n@@ -8251,7 +8289,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n return setError();\n }\n \n- void errorHelper(const(char)* failMessage) scope\n+ void errorHelper(const(char)* failMessage, Loc argloc) scope\n {\n OutBuffer buf;\n buf.writeByte('(');\n@@ -8264,7 +8302,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n .error(exp.loc, \"%s `%s` is not callable using argument types `%s`\",\n p, exp.e1.toErrMsg(), buf.peekChars());\n if (failMessage)\n- errorSupplemental(exp.loc, \"%s\", failMessage);\n+ errorSupplemental((argloc !is Loc.initial) ? argloc : exp.loc, \"%s\", failMessage);\n }\n \n if (callMatch(exp.f, tf, null, exp.argumentList, 0, &errorHelper, sc) == MATCH.nomatch)\n@@ -8327,7 +8365,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n exp.f = exp.f.toAliasFunc();\n TypeFunction tf = cast(TypeFunction)exp.f.type;\n \n- void errorHelper2(const(char)* failMessage) scope\n+ void errorHelper2(const(char)* failMessage, Loc argloc) scope\n {\n OutBuffer buf;\n buf.writeByte('(');\n@@ -8345,7 +8383,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n .error(exp.loc, \"%s `%s` is not callable using argument types `%s`\",\n exp.f.kind(), exp.f.toErrMsg(), buf.peekChars());\n if (failMessage)\n- errorSupplemental(exp.loc, \"%s\", failMessage);\n+ errorSupplemental((argloc !is Loc.initial) ? argloc : exp.loc, \"%s\", failMessage);\n .errorSupplemental(exp.f.loc, \"`%s%s` declared here\", exp.f.toPrettyChars(), parametersTypeToChars(tf.parameterList));\n exp.f = null;\n }\n@@ -8705,9 +8743,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n if (ea)\n {\n if (auto sym = getDsymbol(ea))\n+ {\n ea = symbolToExp(sym, exp.loc, sc, false);\n+ ea = checkNoreturnVarAccess(ea);\n+ }\n else\n ea = ea.expressionSemantic(sc);\n+\n ea = resolveProperties(sc, ea);\n ta = ea.type;\n if (ea.op == EXP.type)\n@@ -9140,10 +9182,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n {\n \n if (Expression e = exp.opOverloadBinaryAssign(sc, aliasThisStop))\n- {\n- result = e;\n- return;\n- }\n+ return setOpOverloadAssign(e);\n \n Expression e;\n if (exp.e1.op == EXP.arrayLength)\n@@ -11780,10 +11819,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n \n // printf(\"PreExp::semantic('%s')\\n\", toChars());\n if (Expression e = exp.opOverloadUnary(sc))\n- {\n- result = e;\n- return;\n- }\n+ return setOpOverloadAssign(e);\n \n // Rewrite as e1+=1 or e1-=1\n Expression e;\n@@ -12072,10 +12108,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n e2x.checkSharedAccess(sc))\n return setError();\n \n- auto etmp = checkNoreturnVarAccess(e2x);\n- if (etmp != e2x)\n- return setResult(etmp);\n-\n+ // taking address of noreturn instance is OK\n+ if (!(exp.e1.isVarExp() && exp.e1.isVarExp().var.storage_class & STC.ref_))\n+ {\n+ auto etmp = checkNoreturnVarAccess(e2x);\n+ if (etmp != e2x)\n+ return setResult(etmp);\n+ }\n exp.e2 = e2x;\n }\n \n@@ -12520,10 +12559,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n else if (exp.op == EXP.assign)\n {\n if (Expression e = exp.isAssignExp().opOverloadAssign(sc, aliasThisStop))\n- {\n- result = e;\n- return;\n- }\n+ return setOpOverloadAssign(e);\n }\n else\n assert(exp.op == EXP.blit);\n@@ -12540,10 +12576,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n if (exp.op == EXP.assign && !exp.e2.implicitConvTo(exp.e1.type))\n {\n if (Expression e = exp.isAssignExp().opOverloadAssign(sc, aliasThisStop))\n- {\n- result = e;\n- return;\n- }\n+ return setOpOverloadAssign(e);\n }\n if (exp.e2.checkValue())\n return setError();\n@@ -13208,10 +13241,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n override void visit(PowAssignExp exp)\n {\n if (Expression e = exp.opOverloadBinaryAssign(sc, aliasThisStop))\n- {\n- result = e;\n- return;\n- }\n+ return setOpOverloadAssign(e);\n \n if (exp.suggestOpOpAssign(sc, parent) ||\n exp.e1.checkReadModifyWrite(exp.op, exp.e2))\n@@ -13285,13 +13315,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n \n override void visit(CatAssignExp exp)\n {\n-\n //printf(\"CatAssignExp::semantic() %s\\n\", exp.toChars());\n if (Expression e = exp.opOverloadBinaryAssign(sc, aliasThisStop))\n- {\n- result = e;\n- return;\n- }\n+ return setOpOverloadAssign(e);\n \n if (exp.suggestOpOpAssign(sc, parent))\n return setError();\n@@ -15210,15 +15236,23 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n rewriteCNull(exp.e2, t2);\n }\n \n- if (t1.ty == Tnoreturn)\n+ if (t1 == t2)\n+ {\n+ exp.type = t1;\n+ }\n+ // If only one of the operands is noreturn, cast it to the type of\n+ // the other operand.\n+ else if (t1.ty == Tnoreturn)\n {\n exp.type = t2;\n- exp.e1 = specialNoreturnCast(exp.e1, exp.type);\n+ if (t2.ty != Tnoreturn)\n+ exp.e1 = specialNoreturnCast(exp.e1, exp.type);\n }\n else if (t2.ty == Tnoreturn)\n {\n exp.type = t1;\n- exp.e2 = specialNoreturnCast(exp.e2, exp.type);\n+ if (t1.ty != Tnoreturn)\n+ exp.e2 = specialNoreturnCast(exp.e2, exp.type);\n }\n // If either operand is void the result is void, we have to cast both\n // the expression to void so that we explicitly discard the expression\n@@ -15230,8 +15264,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n exp.e1 = exp.e1.castTo(sc, exp.type);\n exp.e2 = exp.e2.castTo(sc, exp.type);\n }\n- else if (t1 == t2)\n- exp.type = t1;\n else\n {\n if (Expression ex = typeCombine(exp, sc))\n@@ -15964,7 +15996,10 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag)\n if (s.isPackage())\n error(exp.loc, \"undefined identifier `%s` in %s `%s`, perhaps add `static import %s;`\", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars(), s.toPrettyChars());\n else\n+ {\n error(exp.loc, \"undefined identifier `%s` in %s `%s`, did you mean %s `%s`?\", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars(), s.kind(), s.toChars());\n+ errorSupplemental(s.loc, \"`%s` located here\", s.toPrettyChars(true));\n+ }\n }\n else\n error(exp.loc, \"undefined identifier `%s` in %s `%s`\", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars());\n@@ -18225,6 +18260,7 @@ Expression toBoolean(Expression exp, Scope* sc)\n break;\n }\n \n+ e = checkNoreturnVarAccess(e);\n if (!t.isBoolean())\n {\n if (tb != Type.terror)\n@@ -18835,6 +18871,29 @@ Expression getConstInitializer(VarDeclaration vd, bool needFullType = true)\n return e;\n }\n \n+/*******************************************\n+ * Check whether there is an AA literal somewhere inside the expression\n+ */\n+private bool hasAALiteralExp(Expression e)\n+{\n+ extern (C++) final class HasAALiteral : StoppableVisitor\n+ {\n+ alias visit = typeof(super).visit;\n+\n+ override void visit(Expression)\n+ {\n+ }\n+ override void visit(AssocArrayLiteralExp aae)\n+ {\n+ stop = true;\n+ }\n+ }\n+\n+ scope HasAALiteral hal = new HasAALiteral;\n+ walkPostorder(e, hal);\n+ return hal.stop;\n+}\n+\n /*******************************************\n * Helper function for the expansion of manifest constant.\n */\n@@ -18849,9 +18908,10 @@ private Expression expandInitializer(VarDeclaration vd, Loc loc)\n return ErrorExp.get();\n }\n \n- e = e.copy();\n- if (auto aae = e.isAssocArrayLiteralExp())\n- aae.lowering = null; // need to redo lowering as it contains temporary variables that must be renamed\n+ if (hasAALiteralExp(e))\n+ e = e.syntaxCopy(); // need to redo lowering as it contains temporary variables that must be renamed\n+ else\n+ e = e.copy();\n e.loc = loc; // for better error message\n return e;\n }\n@@ -19756,8 +19816,12 @@ private Expression rewriteAAIndexAssign(BinExp exp, Scope* sc, ref Type[2] alias\n ekeys[i-1] = extractSideEffect(sc, \"__aakey\", e0, ekeys[i-1]);\n // some implicit conversions are lost when assigning to a temporary, e.g. from array literal\n auto taa = eaa.type.isTypeAArray();\n- auto match = exp.e2.implicitConvTo(taa.next);\n- auto e2 = match == MATCH.exact || match == MATCH.nomatch ? exp.e2 : exp.e2.implicitCastTo(sc, taa.next);\n+ Expression e2 = exp.e2;\n+ if (exp.isAssignExp()) // must keep original types for op=\n+ {\n+ auto match = exp.e2.implicitConvTo(taa.next);\n+ e2 = match == MATCH.exact || match == MATCH.nomatch ? exp.e2 : exp.e2.implicitCastTo(sc, taa.next);\n+ }\n Expression ev = extractSideEffect(sc, \"__aaval\", e0, e2); // must be evaluated before the insertion\n \n // generate series of calls to _d_aaGetY\ndiff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d\nindex 441089b0fd1..1f902e4f184 100644\n--- a/gcc/d/dmd/func.d\n+++ b/gcc/d/dmd/func.d\n@@ -631,46 +631,6 @@ extern (C++) class FuncDeclaration : Declaration\n return toAliasFunc().isThis() !is null;\n }\n \n- // Determine if a function is pedantically virtual\n- final bool isVirtualMethod()\n- {\n- if (toAliasFunc() != this)\n- return toAliasFunc().isVirtualMethod();\n-\n- //printf(\"FuncDeclaration::isVirtualMethod() %s\\n\", toChars());\n- if (!isVirtual())\n- return false;\n- // If it's a final method, and does not override anything, then it is not virtual\n- if (isFinalFunc() && foverrides.length == 0)\n- {\n- return false;\n- }\n- return true;\n- }\n-\n- // Determine if function goes into virtual function pointer table\n- bool isVirtual() const\n- {\n- if (toAliasFunc() != this)\n- return toAliasFunc().isVirtual();\n-\n- auto p = toParent();\n-\n- if (!isMember || !p.isClassDeclaration)\n- return false;\n-\n- if (p.isClassDeclaration.classKind == ClassKind.objc)\n- return .objc.isVirtual(this);\n-\n- version (none)\n- {\n- printf(\"FuncDeclaration::isVirtual(%s)\\n\", toChars());\n- printf(\"isMember:%p isStatic:%d private:%d ctor:%d !Dlinkage:%d\\n\", isMember(), isStatic(), visibility == Visibility.Kind.private_, isCtorDeclaration(), linkage != LINK.d);\n- printf(\"result is %d\\n\", isMember() && !(isStatic() || visibility == Visibility.Kind.private_ || visibility == Visibility.Kind.package_) && p.isClassDeclaration() && !(p.isInterfaceDeclaration() && isFinalFunc()));\n- }\n- return !(isStatic() || visibility.kind == Visibility.Kind.private_ || visibility.kind == Visibility.Kind.package_) && !(p.isInterfaceDeclaration() && isFinalFunc());\n- }\n-\n final bool isFinalFunc() const\n {\n if (toAliasFunc() != this)\n@@ -693,55 +653,11 @@ extern (C++) class FuncDeclaration : Declaration\n return (cd !is null) && (cd.storage_class & STC.final_);\n }\n \n- bool addPreInvariant()\n- {\n- auto ad = isThis();\n- return (ad && global.params.useInvariants == CHECKENABLE.on && (visibility.kind == Visibility.Kind.protected_ || visibility.kind == Visibility.Kind.public_ || visibility.kind == Visibility.Kind.export_) && !this.isNaked);\n- }\n-\n- bool addPostInvariant()\n- {\n- auto ad = isThis();\n- return (ad && ad.inv && global.params.useInvariants == CHECKENABLE.on && (visibility.kind == Visibility.Kind.protected_ || visibility.kind == Visibility.Kind.public_ || visibility.kind == Visibility.Kind.export_) && !this.isNaked);\n- }\n-\n override const(char)* kind() const\n {\n return this.isGenerated ? \"generated function\" : \"function\";\n }\n \n- /***********************************************\n- * Determine if function's variables are referenced by a function\n- * nested within it.\n- */\n- final bool hasNestedFrameRefs()\n- {\n- if (closureVars.length)\n- return true;\n-\n- /* If a virtual function has contracts, assume its variables are referenced\n- * by those contracts, even if they aren't. Because they might be referenced\n- * by the overridden or overriding function's contracts.\n- * This can happen because frequire and fensure are implemented as nested functions,\n- * and they can be called directly by an overriding function and the overriding function's\n- * context had better match, or\n- * https://issues.dlang.org/show_bug.cgi?id=7335 will bite.\n- */\n- if (fdrequire || fdensure)\n- return true;\n-\n- if (foverrides.length && isVirtualMethod())\n- {\n- for (size_t i = 0; i < foverrides.length; i++)\n- {\n- FuncDeclaration fdv = foverrides[i];\n- if (fdv.hasNestedFrameRefs())\n- return true;\n- }\n- }\n- return false;\n- }\n-\n /*********************************************\n * Returns: the function's parameter list, and whether\n * it is variadic or not.\n@@ -939,21 +855,6 @@ extern (C++) final class FuncLiteralDeclaration : FuncDeclaration\n return tok == TOK.delegate_ ? super.isThis() : null;\n }\n \n- override bool isVirtual() const\n- {\n- return false;\n- }\n-\n- override bool addPreInvariant()\n- {\n- return false;\n- }\n-\n- override bool addPostInvariant()\n- {\n- return false;\n- }\n-\n override const(char)* kind() const\n {\n // GCC requires the (char*) casts\n@@ -1003,21 +904,6 @@ extern (C++) final class CtorDeclaration : FuncDeclaration\n isMoveCtor ? \"move constructor\" : \"constructor\";\n }\n \n- override bool isVirtual() const\n- {\n- return false;\n- }\n-\n- override bool addPreInvariant()\n- {\n- return false;\n- }\n-\n- override bool addPostInvariant()\n- {\n- return (isThis() && vthis && global.params.useInvariants == CHECKENABLE.on);\n- }\n-\n override void accept(Visitor v)\n {\n v.visit(this);\n@@ -1042,21 +928,6 @@ extern (C++) final class PostBlitDeclaration : FuncDeclaration\n return dd;\n }\n \n- override bool isVirtual() const\n- {\n- return false;\n- }\n-\n- override bool addPreInvariant()\n- {\n- return false;\n- }\n-\n- override bool addPostInvariant()\n- {\n- return (isThis() && vthis && global.params.useInvariants == CHECKENABLE.on);\n- }\n-\n override void accept(Visitor v)\n {\n v.visit(this);\n@@ -1092,23 +963,6 @@ extern (C++) final class DtorDeclaration : FuncDeclaration\n return \"destructor\";\n }\n \n- override bool isVirtual() const\n- {\n- // D dtor's don't get put into the vtbl[]\n- // this is a hack so that extern(C++) destructors report as virtual, which are manually added to the vtable\n- return vtblIndex != -1;\n- }\n-\n- override bool addPreInvariant()\n- {\n- return (isThis() && vthis && global.params.useInvariants == CHECKENABLE.on);\n- }\n-\n- override bool addPostInvariant()\n- {\n- return false;\n- }\n-\n override void accept(Visitor v)\n {\n v.visit(this);\n@@ -1144,21 +998,6 @@ extern (C++) class StaticCtorDeclaration : FuncDeclaration\n return null;\n }\n \n- override final bool isVirtual() const @nogc nothrow pure @safe\n- {\n- return false;\n- }\n-\n- override final bool addPreInvariant() @nogc nothrow pure @safe\n- {\n- return false;\n- }\n-\n- override final bool addPostInvariant() @nogc nothrow pure @safe\n- {\n- return false;\n- }\n-\n override void accept(Visitor v)\n {\n v.visit(this);\n@@ -1223,21 +1062,6 @@ extern (C++) class StaticDtorDeclaration : FuncDeclaration\n return null;\n }\n \n- override final bool isVirtual() const\n- {\n- return false;\n- }\n-\n- override final bool addPreInvariant()\n- {\n- return false;\n- }\n-\n- override final bool addPostInvariant()\n- {\n- return false;\n- }\n-\n override void accept(Visitor v)\n {\n v.visit(this);\n@@ -1288,21 +1112,6 @@ extern (C++) final class InvariantDeclaration : FuncDeclaration\n return id;\n }\n \n- override bool isVirtual() const\n- {\n- return false;\n- }\n-\n- override bool addPreInvariant()\n- {\n- return false;\n- }\n-\n- override bool addPostInvariant()\n- {\n- return false;\n- }\n-\n override void accept(Visitor v)\n {\n v.visit(this);\n@@ -1348,21 +1157,6 @@ extern (C++) final class UnitTestDeclaration : FuncDeclaration\n return null;\n }\n \n- override bool isVirtual() const\n- {\n- return false;\n- }\n-\n- override bool addPreInvariant()\n- {\n- return false;\n- }\n-\n- override bool addPostInvariant()\n- {\n- return false;\n- }\n-\n override void accept(Visitor v)\n {\n v.visit(this);\n@@ -1392,21 +1186,6 @@ extern (C++) final class NewDeclaration : FuncDeclaration\n return \"allocator\";\n }\n \n- override bool isVirtual() const\n- {\n- return false;\n- }\n-\n- override bool addPreInvariant()\n- {\n- return false;\n- }\n-\n- override bool addPostInvariant()\n- {\n- return false;\n- }\n-\n override void accept(Visitor v)\n {\n v.visit(this);\ndiff --git a/gcc/d/dmd/funcsem.d b/gcc/d/dmd/funcsem.d\nindex 0bdd75fd55e..e153e11067e 100644\n--- a/gcc/d/dmd/funcsem.d\n+++ b/gcc/d/dmd/funcsem.d\n@@ -67,6 +67,194 @@ import dmd.typesem;\n import dmd.visitor;\n import dmd.visitor.statement_rewrite_walker;\n \n+bool addPostInvariant(FuncDeclaration _this)\n+{\n+ static bool visitFuncDeclaration(FuncDeclaration _this)\n+ {\n+ auto ad = _this.isThis();\n+ return (\n+ ad &&\n+ ad.inv &&\n+ global.params.useInvariants == CHECKENABLE.on &&\n+ (_this.visibility.kind == Visibility.Kind.protected_ ||\n+ _this.visibility.kind == Visibility.Kind.public_ ||\n+ _this.visibility.kind == Visibility.Kind.export_) &&\n+ !_this.isNaked\n+ );\n+ }\n+\n+ switch(_this.dsym)\n+ {\n+ case DSYM.funcLiteralDeclaration:\n+ case DSYM.dtorDeclaration:\n+ case DSYM.staticCtorDeclaration:\n+ case DSYM.sharedStaticCtorDeclaration:\n+ case DSYM.staticDtorDeclaration:\n+ case DSYM.sharedStaticDtorDeclaration:\n+ case DSYM.invariantDeclaration:\n+ case DSYM.unitTestDeclaration:\n+ case DSYM.newDeclaration:\n+ return false;\n+ case DSYM.ctorDeclaration:\n+ {\n+ auto cd = _this.isCtorDeclaration();\n+ return (cd.isThis() && cd.vthis && global.params.useInvariants == CHECKENABLE.on);\n+ }\n+ case DSYM.postBlitDeclaration:\n+ {\n+ auto dd = _this.isPostBlitDeclaration();\n+ return (dd.isThis() && dd.vthis && global.params.useInvariants == CHECKENABLE.on);\n+ }\n+ default: return visitFuncDeclaration(_this);\n+ }\n+}\n+\n+bool addPreInvariant(FuncDeclaration _this)\n+{\n+ static bool visitFuncDeclaration(FuncDeclaration _this)\n+ {\n+ return (\n+ _this.isThis() &&\n+ global.params.useInvariants == CHECKENABLE.on &&\n+ (_this.visibility.kind == Visibility.Kind.protected_ ||\n+ _this.visibility.kind == Visibility.Kind.public_ ||\n+ _this.visibility.kind == Visibility.Kind.export_) &&\n+ !_this.isNaked\n+ );\n+ }\n+\n+ switch(_this.dsym)\n+ {\n+ case DSYM.funcLiteralDeclaration:\n+ case DSYM.ctorDeclaration:\n+ case DSYM.postBlitDeclaration:\n+ case DSYM.staticCtorDeclaration:\n+ case DSYM.sharedStaticCtorDeclaration:\n+ case DSYM.staticDtorDeclaration:\n+ case DSYM.sharedStaticDtorDeclaration:\n+ case DSYM.invariantDeclaration:\n+ case DSYM.unitTestDeclaration:\n+ case DSYM.newDeclaration:\n+ return false;\n+ case DSYM.dtorDeclaration:\n+ {\n+ auto dd = _this.isDtorDeclaration();\n+ return (dd.isThis() && dd.vthis && global.params.useInvariants == CHECKENABLE.on);\n+ }\n+ default: return visitFuncDeclaration(_this);\n+ }\n+}\n+\n+// Determine if function goes into virtual function pointer table\n+bool isVirtual(const FuncDeclaration _this)\n+{\n+ static bool visitFuncDeclaration(const FuncDeclaration _this)\n+ {\n+ if (_this.toAliasFunc() != _this)\n+ return _this.toAliasFunc().isVirtual();\n+\n+ auto p = _this.toParent();\n+\n+ if (!_this.isMember || !p.isClassDeclaration)\n+ return false;\n+\n+ if (p.isClassDeclaration.classKind == ClassKind.objc)\n+ return objc.isVirtual(_this);\n+\n+ version (none)\n+ {\n+ printf(\"FuncDeclaration::isVirtual(%s)\\n\", _this.toChars());\n+ printf(\"isMember:%p isStatic:%d private:%d ctor:%d !Dlinkage:%d\\n\",\n+ _this.isMember(),\n+ _this.isStatic(),\n+ _this.visibility.kind == Visibility.Kind.private_,\n+ _this.isCtorDeclaration() !is null,\n+ _this._linkage != LINK.d\n+ );\n+ printf(\"result is %d\\n\",\n+ _this.isMember() &&\n+ !(_this.isStatic() || _this.visibility.kind == Visibility.Kind.private_ || _this.visibility.kind == Visibility.Kind.package_) &&\n+ p.isClassDeclaration() &&\n+ !(p.isInterfaceDeclaration() && _this.isFinalFunc())\n+ );\n+ }\n+\n+ return !(_this.isStatic() ||\n+ _this.visibility.kind == Visibility.Kind.private_ ||\n+ _this.visibility.kind == Visibility.Kind.package_) &&\n+ !(p.isInterfaceDeclaration() && _this.isFinalFunc());\n+ }\n+\n+ switch(_this.dsym)\n+ {\n+ case DSYM.funcLiteralDeclaration:\n+ case DSYM.ctorDeclaration:\n+ case DSYM.postBlitDeclaration:\n+ case DSYM.staticCtorDeclaration:\n+ case DSYM.sharedStaticCtorDeclaration:\n+ case DSYM.staticDtorDeclaration:\n+ case DSYM.sharedStaticDtorDeclaration:\n+ case DSYM.invariantDeclaration:\n+ case DSYM.unitTestDeclaration:\n+ case DSYM.newDeclaration:\n+ return false;\n+ // D dtor's don't get put into the vtbl[]\n+ // this is a hack so that extern(C++) destructors report as virtual\n+ // which are manually added to the vtable\n+ case DSYM.dtorDeclaration: return _this.vtblIndex != -1;\n+ default: return visitFuncDeclaration(_this);\n+ }\n+}\n+\n+// Determine if a function is pedantically virtual\n+bool isVirtualMethod(FuncDeclaration _this)\n+{\n+ if (_this.toAliasFunc() != _this)\n+ return _this.toAliasFunc().isVirtualMethod();\n+\n+ //printf(\"FuncDeclaration::isVirtualMethod() %s\\n\", toChars());\n+ if (!_this.isVirtual())\n+ return false;\n+\n+ // If it's a final method, and does not override anything, then it is not virtual\n+ if (_this.isFinalFunc() && _this.foverrides.length == 0)\n+ {\n+ return false;\n+ }\n+ return true;\n+}\n+\n+/***********************************************\n+ * Determine if function's variables are referenced by a function\n+ * nested within it.\n+ */\n+bool hasNestedFrameRefs(FuncDeclaration _this)\n+{\n+ if (_this.closureVars.length)\n+ return true;\n+\n+ /* If a virtual function has contracts, assume its variables are referenced\n+ * by those contracts, even if they aren't. Because they might be referenced\n+ * by the overridden or overriding function's contracts.\n+ * This can happen because frequire and fensure are implemented as nested functions,\n+ * and they can be called directly by an overriding function and the overriding function's\n+ * context had better match, or\n+ * https://issues.dlang.org/show_bug.cgi?id=7335 will bite.\n+ */\n+ if (_this.fdrequire || _this.fdensure)\n+ return true;\n+\n+ if (_this.foverrides.length && _this.isVirtualMethod())\n+ {\n+ for (size_t i = 0; i < _this.foverrides.length; i++)\n+ {\n+ FuncDeclaration fdv = _this.foverrides[i];\n+ if (fdv.hasNestedFrameRefs())\n+ return true;\n+ }\n+ }\n+ return false;\n+}\n \n /**********************************\n * Generate a FuncDeclaration for a runtime library function.\n@@ -1908,12 +2096,12 @@ FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,\n }\n \n bool calledHelper;\n- void errorHelper(const(char)* failMessage) scope\n+ void errorHelper(const(char)* failMessage, Loc argloc = Loc.initial) scope\n {\n .error(loc, \"%s `%s%s%s` is not callable using argument types `%s`\",\n fd.kind(), fd.toPrettyChars(), parametersTypeToChars(tf.parameterList),\n tf.modToChars(), fargsBuf.peekChars());\n- errorSupplemental(loc, failMessage);\n+ errorSupplemental((argloc !is Loc.initial) ? argloc : loc, failMessage);\n calledHelper = true;\n }\n \n@@ -1981,9 +2169,9 @@ FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,\n }\n }\n \n- void errorHelper2(const(char)* failMessage) scope\n+ void errorHelper2(const(char)* failMessage, Loc argloc = Loc.initial) scope\n {\n- errorSupplemental(loc, failMessage);\n+ errorSupplemental((argloc !is Loc.initial) ? argloc : loc, failMessage);\n }\n \n functionResolve(m, orig_s, loc, sc, tiargs, tthis, argumentList, &errorHelper2);\n@@ -4094,16 +4282,43 @@ bool arrayBoundsCheck(FuncDeclaration fd)\n case CHECKENABLE.on:\n return true;\n case CHECKENABLE.safeonly:\n+ if (fd)\n {\n+ Type t = fd.type;\n+ if (t.isTypeFunction() && t.isTypeFunction().trust == TRUST.safe)\n+ return true;\n+ }\n+ return false;\n+ case CHECKENABLE._default:\n+ assert(0);\n+ }\n+}\n+\n+/**********************\n+ * Check to see if null dereference checking code has to be generated\n+ *\n+ * Params:\n+ * fd = function for which code is to be generated\n+ * Returns:\n+ * true if do null dereference checking for the given function\n+ */\n+bool nullDerefCheck(FuncDeclaration fd)\n+{\n+ final switch (global.params.useNullCheck)\n+ {\n+ case CHECKENABLE.off:\n+ return false;\n+ case CHECKENABLE.on:\n+ return true;\n+ case CHECKENABLE.safeonly:\n if (fd)\n {\n Type t = fd.type;\n- if (t.ty == Tfunction && (cast(TypeFunction)t).trust == TRUST.safe)\n+ if (t.isTypeFunction() && t.isTypeFunction().trust == TRUST.safe)\n return true;\n }\n return false;\n- }\n- case CHECKENABLE._default:\n- assert(0);\n+ case CHECKENABLE._default:\n+ assert(0);\n }\n }\ndiff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d\nindex 78584bf7cf3..020d24786cb 100644\n--- a/gcc/d/dmd/globals.d\n+++ b/gcc/d/dmd/globals.d\n@@ -218,11 +218,13 @@ extern (C++) struct Param\n FeatureState dtorFields; // destruct fields of partially constructed objects\n // https://issues.dlang.org/show_bug.cgi?id=14246\n FeatureState systemVariables; // limit access to variables marked @system from @safe code\n+ bool useFastDFA; // Use fast data flow analysis engine\n \n CHECKENABLE useInvariants = CHECKENABLE._default; // generate class invariant checks\n CHECKENABLE useIn = CHECKENABLE._default; // generate precondition checks\n CHECKENABLE useOut = CHECKENABLE._default; // generate postcondition checks\n CHECKENABLE useArrayBounds = CHECKENABLE._default; // when to generate code for array bounds checks\n+ CHECKENABLE useNullCheck = CHECKENABLE._default; // when to generate code for null dereference checks\n CHECKENABLE useAssert = CHECKENABLE._default; // when to generate code for assert()'s\n CHECKENABLE useSwitchError = CHECKENABLE._default; // check for switches without a default\n CHECKENABLE boundscheck = CHECKENABLE._default; // state of -boundscheck switch\n@@ -307,7 +309,7 @@ extern (C++) struct Global\n Array!(const(char)*) filePath; /// Array of char*'s which form the file import lookup path\n \n private enum string _version = import(\"VERSION\");\n- char[26] datetime; /// string returned by ctime()\n+ char[26] datetime; /// string returned by asctime()\n CompileEnv compileEnv;\n \n Param params; /// command line parameters\n@@ -406,15 +408,19 @@ extern (C++) struct Global\n import core.stdc.stdlib : getenv;\n \n time_t ct;\n+ const(char)* p;\n // https://issues.dlang.org/show_bug.cgi?id=20444\n- if (auto p = getenv(\"SOURCE_DATE_EPOCH\"))\n+ if (auto epoch = getenv(\"SOURCE_DATE_EPOCH\"))\n {\n- if (!ct.parseDigits(p[0 .. strlen(p)]))\n- errorSink.error(Loc.initial, \"value of environment variable `SOURCE_DATE_EPOCH` should be a valid UNIX timestamp, not: `%s`\", p);\n+ if (!ct.parseDigits(epoch[0 .. strlen(epoch)]))\n+ errorSink.error(Loc.initial, \"value of environment variable `SOURCE_DATE_EPOCH` should be a valid UNIX timestamp, not: `%s`\", epoch);\n+ p = asctime(gmtime(&ct));\n }\n else\n+ {\n core.stdc.time.time(&ct);\n- const p = ctime(&ct);\n+ p = ctime(&ct); // asctime(localtime(&ct))\n+ }\n assert(p);\n datetime[] = p[0 .. 26];\n \ndiff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h\nindex 3d696eb063e..40894f256a6 100644\n--- a/gcc/d/dmd/globals.h\n+++ b/gcc/d/dmd/globals.h\n@@ -239,11 +239,13 @@ struct Param\n FeatureState dtorFields; // destruct fields of partially constructed objects\n // https://issues.dlang.org/show_bug.cgi?id=14246\n FeatureState systemVariables; // limit access to variables marked @system from @safe code\n+ d_bool useFastDFA; // Use fast data flow analysis engine\n \n CHECKENABLE useInvariants; // generate class invariant checks\n CHECKENABLE useIn; // generate precondition checks\n CHECKENABLE useOut; // generate postcondition checks\n CHECKENABLE useArrayBounds; // when to generate code for array bounds checks\n+ CHECKENABLE useNullCheck; // when to generate code for null dereference checks\n CHECKENABLE useAssert; // when to generate code for assert()'s\n CHECKENABLE useSwitchError; // check for switches without a default\n CHECKENABLE boundscheck; // state of -boundscheck switch\ndiff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d\nindex a79822a43b6..7b50af1685f 100644\n--- a/gcc/d/dmd/hdrgen.d\n+++ b/gcc/d/dmd/hdrgen.d\n@@ -2799,6 +2799,9 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt\n \n void visitAssert(AssertExp e)\n {\n+ if (e.loweredFrom)\n+ return e.loweredFrom.expressionPrettyPrint(buf, hgs);\n+\n buf.put(\"assert(\");\n expToBuffer(e.e1, PREC.assign, buf, hgs);\n if (e.msg)\ndiff --git a/gcc/d/dmd/importc.d b/gcc/d/dmd/importc.d\nindex cf94b632a8e..6fc3a51731f 100644\n--- a/gcc/d/dmd/importc.d\n+++ b/gcc/d/dmd/importc.d\n@@ -575,7 +575,7 @@ Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsy\n if (fd.fbody) // fd is the definition\n {\n if (log) printf(\" replace existing with new\\n\");\n- sds.symtab.update(fd); // replace fd2 in symbol table with fd\n+ sds.symtab.update(fd); // replace fd2 in symbol table with fd\n fd.overnext = fd2;\n \n /* If fd2 is covering a tag symbol, then fd has to cover the same one\n@@ -631,7 +631,7 @@ void cEnumSemantic(Scope* sc, EnumDeclaration ed)\n // C11 6.7.2.2-2 value must be representable as an int.\n // The sizemask represents all values that int will fit into,\n // from 0..uint.max. We want to cover int.min..uint.max.\n- IntRange ir = IntRange.fromType(commonType);\n+ IntRange ir = intRangeFromType(commonType);\n \n void emSemantic(EnumMember em, ref ulong nextValue)\n {\ndiff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d\nindex 9ddf5508eb1..21ad68fb6ce 100644\n--- a/gcc/d/dmd/initsem.d\n+++ b/gcc/d/dmd/initsem.d\n@@ -422,6 +422,26 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn\n if (i.exp.op == EXP.type)\n {\n error(i.exp.loc, \"initializer must be an expression, not `%s`\", i.exp.toChars());\n+ // If the error location differs from the initializer location, show where it was used\n+ if (i.exp.loc != i.loc)\n+ errorSupplemental(i.loc, \"used in initialization here\");\n+ // If the type is a struct or class, suggest adding () to construct an instance\n+ if (auto ts = i.exp.type.isTypeStruct())\n+ {\n+ // Check if the struct can be default-constructed (no required args)\n+ if (!ts.sym.hasCopyCtor && (!ts.sym.ctor || ts.sym.defaultCtor))\n+ errorSupplemental(i.exp.loc, \"perhaps use `%s()` to construct a value of the type\", i.exp.toChars());\n+ else if (ts.sym.ctor && !ts.sym.hasCopyCtor)\n+ errorSupplemental(i.exp.loc, \"perhaps use `%s(...)` to construct a value of the type\", i.exp.toChars());\n+ }\n+ else if (auto tc = i.exp.type.isTypeClass())\n+ {\n+ // Check if the class can be default-constructed\n+ if (!tc.sym.noDefaultCtor && (!tc.sym.ctor || tc.sym.defaultCtor))\n+ errorSupplemental(i.exp.loc, \"perhaps use `new %s()` to construct a value of the type\", i.exp.toChars());\n+ else if (tc.sym.ctor)\n+ errorSupplemental(i.exp.loc, \"perhaps use `new %s(...)` to construct a value of the type\", i.exp.toChars());\n+ }\n return err();\n }\n // Make sure all pointers are constants\ndiff --git a/gcc/d/dmd/intrange.d b/gcc/d/dmd/intrange.d\nindex 4f8af92433f..cc69373d121 100644\n--- a/gcc/d/dmd/intrange.d\n+++ b/gcc/d/dmd/intrange.d\n@@ -16,7 +16,6 @@ import core.stdc.stdio;\n import dmd.astenums : Tdchar;\n import dmd.mtype : Type;\n import dmd.globals : uinteger_t;\n-import dmd.typesem;\n \n private uinteger_t copySign(uinteger_t x, bool sign) @safe\n {\n@@ -315,30 +314,6 @@ struct IntRange\n imax = upper;\n }\n \n- static IntRange fromType(Type type)\n- {\n- return fromType(type, type.isUnsigned());\n- }\n-\n- static IntRange fromType(Type type, bool isUnsigned)\n- {\n- if (!type.isIntegral() || type.toBasetype().isTypeVector())\n- return widest();\n-\n- uinteger_t mask = type.sizemask();\n- auto lower = SignExtendedNumber(0);\n- auto upper = SignExtendedNumber(mask);\n- if (type.toBasetype().ty == Tdchar)\n- upper.value = 0x10FFFFUL;\n- else if (!isUnsigned)\n- {\n- lower.value = ~(mask >> 1);\n- lower.negative = true;\n- upper.value = (mask >> 1);\n- }\n- return IntRange(lower, upper);\n- }\n-\n static IntRange fromNumbers2(SignExtendedNumber* numbers)\n {\n if (numbers[0] < numbers[1])\n@@ -442,26 +417,6 @@ struct IntRange\n return this;\n }\n \n- IntRange _cast(Type type)\n- {\n- if (!type.isIntegral() || type.toBasetype().isTypeVector())\n- return this;\n- if (!type.isUnsigned())\n- return castSigned(type.sizemask());\n- if (type.toBasetype().ty == Tdchar)\n- return castDchar();\n- return castUnsigned(type.sizemask());\n- }\n-\n- IntRange castUnsigned(Type type)\n- {\n- if (!type.isIntegral() || type.toBasetype().isTypeVector())\n- return castUnsigned(ulong.max);\n- if (type.toBasetype().ty == Tdchar)\n- return castDchar();\n- return castUnsigned(type.sizemask());\n- }\n-\n bool contains(IntRange a) @safe\n {\n return imin <= a.imin && imax >= a.imax;\ndiff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h\nindex e23851acd57..7ed98199966 100644\n--- a/gcc/d/dmd/module.h\n+++ b/gcc/d/dmd/module.h\n@@ -108,7 +108,7 @@ public:\n Identifiers *versionidsNot; // forward referenced version identifiers\n \n MacroTable macrotable; // document comment macros\n- Escape *escapetable; // document comment escapes\n+ void *escapetable; // document comment escapes (Escape*)\n \n size_t nameoffset; // offset of module name from start of ModuleInfo\n size_t namelen; // length of module name in characters\ndiff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d\nindex 79098cae3fb..c9b8a0275b8 100644\n--- a/gcc/d/dmd/nogc.d\n+++ b/gcc/d/dmd/nogc.d\n@@ -18,11 +18,12 @@ import core.stdc.stdio;\n import dmd.aggregate;\n import dmd.arraytypes;\n import dmd.astenums;\n+import dmd.attrib;\n import dmd.common.outbuffer;\n import dmd.declaration;\n import dmd.dmodule;\n import dmd.dscope;\n-import dmd.dsymbol : PASS;\n+import dmd.dsymbol : PASS, Dsymbol;\n import dmd.dtemplate : isDsymbol;\n import dmd.errors;\n import dmd.escape;\n@@ -76,14 +77,32 @@ public:\n override void visit(DeclarationExp e)\n {\n // Note that, walkPostorder does not support DeclarationExp today.\n- VarDeclaration v = e.declaration.isVarDeclaration();\n- if (v && !(v.storage_class & STC.manifest) && !v.isDataseg() && v._init)\n+ void visitDecl(Dsymbol d)\n {\n- if (ExpInitializer ei = v._init.isExpInitializer())\n+ if (VarDeclaration v = d.isVarDeclaration())\n {\n- doCond(ei.exp);\n+ if (!(v.storage_class & STC.manifest) && !v.isDataseg() && v._init && !v.isCsymbol())\n+ {\n+ if (ExpInitializer ei = v._init.isExpInitializer())\n+ {\n+ doCond(ei.exp);\n+ }\n+ }\n+ }\n+ else if (AttribDeclaration ad = d.isAttribDeclaration())\n+ {\n+ // Don't recurse into anonymous declarations (unions/structs)\n+ // as their members aren't meant to be processed here\n+ if (ad.isAnonDeclaration())\n+ return;\n+ if (ad.decl)\n+ {\n+ foreach (s; *ad.decl)\n+ visitDecl(s);\n+ }\n }\n }\n+ visitDecl(e.declaration);\n }\n \n /**\ndiff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d\nindex 868b22b29c2..d086927db98 100644\n--- a/gcc/d/dmd/opover.d\n+++ b/gcc/d/dmd/opover.d\n@@ -612,7 +612,7 @@ bool suggestBinaryOverloads(BinExp e, Scope* sc)\n return true;\n }\n error(e.loc, \"operator `%s` is not defined for type `%s`\", EXPtoString(e.op).ptr, e.e2.type.toChars);\n- errorSupplemental(ad2.loc, \"perhaps overload the operator with `auto opBinaryRight(string op : \\\"%s\\\")(%s rhs) {}`\", EXPtoString(e.op).ptr, e.e1.type.toChars);\n+ errorSupplemental(ad2.loc, \"perhaps overload the operator with `auto opBinaryRight(string op : \\\"%s\\\")(%s lhs) {}`\", EXPtoString(e.op).ptr, e.e1.type.toChars);\n return true;\n }\n return false;\ndiff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d\nindex 39261002b9c..c8ca3a1a0f2 100644\n--- a/gcc/d/dmd/parse.d\n+++ b/gcc/d/dmd/parse.d\n@@ -4505,6 +4505,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer\n isAliasDeclaration = true;\n }\n \n+ const typeLoc = token.loc;\n AST.Type ts;\n \n if (!autodecl)\n@@ -4641,9 +4642,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer\n \n if (isAliasDeclaration)\n {\n- AST.Declaration v;\n- AST.Initializer _init = null;\n-\n+ if (ident && mod.edition >= Edition.v2024)\n+ {\n+ eSink.error(token.loc, \"use `alias %s = ...;` syntax instead of `alias ... %s;`\",\n+ ident.toChars(), ident.toChars());\n+ }\n /* Aliases can no longer have multiple declarators, storage classes,\n * linkages, or auto declarations.\n * These never made any sense, anyway.\n@@ -4654,6 +4657,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer\n if (udas)\n error(\"user-defined attributes not allowed for `alias` declarations\");\n \n+ AST.Initializer _init = null;\n if (token.value == TOK.assign)\n {\n nextToken();\n@@ -4663,7 +4667,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer\n {\n error(\"alias cannot have initializer\");\n }\n- v = new AST.AliasDeclaration(aliasLoc, ident, t);\n+ AST.Declaration v = new AST.AliasDeclaration(aliasLoc, ident, t);\n \n v.storage_class = storage_class;\n if (pAttrs)\n@@ -4792,11 +4796,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer\n AST.Dsymbol s;\n if (width)\n {\n- if (_init)\n- error(\"initializer not allowed for bitfield declaration\");\n if (storage_class)\n error(\"storage class not allowed for bitfield declaration\");\n- s = new AST.BitFieldDeclaration(width.loc, t, ident, width);\n+ s = new AST.BitFieldDeclaration(ident.isAnonymous() ? typeLoc : loc, t, ident, width, _init);\n }\n else\n {\n@@ -5758,14 +5760,13 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer\n }\n \n /***\n- * Parse an assignment condition for `if`, `switch` or `while` statements.\n+ * Parse an assignment condition for `if`, `switch`, `while` or `with` statements.\n *\n * Returns:\n * The variable that is declared inside the condition\n */\n- AST.Parameter parseAssignCondition()\n+ AST.Parameter parseAssignCondition(bool _with = false)\n {\n- AST.Parameter param = null;\n STC storageClass = STC.none;\n STC stc = STC.none;\n Lwhile:\n@@ -5834,7 +5835,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer\n const aloc = token.loc;\n nextToken();\n check(TOK.assign);\n- param = new AST.Parameter(aloc, storageClass, at, ai, null, null);\n+ return new AST.Parameter(aloc, storageClass, at, ai, null, null);\n }\n else if (isDeclaration(&token, NeedDeclaratorId.must, TOK.assign, null))\n {\n@@ -5842,12 +5843,13 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer\n const aloc = token.loc;\n AST.Type at = parseType(&ai);\n check(TOK.assign);\n- param = new AST.Parameter(aloc, storageClass, at, ai, null, null);\n+ return new AST.Parameter(aloc, storageClass, at, ai, null, null);\n }\n- else if (storageClass != 0)\n+ else if (storageClass != 0 && !_with)\n+ {\n error(\"found `%s` while expecting `=` or identifier\", n.toChars());\n-\n- return param;\n+ }\n+ return null;\n }\n \n /*****************************************\n@@ -6659,10 +6661,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer\n \n nextToken();\n check(TOK.leftParenthesis);\n+ auto param = parseAssignCondition(true);\n exp = parseExpression();\n- closeCondition(\"with\", null, exp);\n+ closeCondition(\"with\", param, exp);\n _body = parseStatement(ParseStatementFlags.scope_, null, &endloc);\n- s = new AST.WithStatement(loc, exp, _body, endloc);\n+ s = new AST.WithStatement(loc, param, exp, _body, endloc);\n break;\n }\n case TOK.try_:\ndiff --git a/gcc/d/dmd/root/array.d b/gcc/d/dmd/root/array.d\nindex d8d49bff056..91abfab69df 100644\n--- a/gcc/d/dmd/root/array.d\n+++ b/gcc/d/dmd/root/array.d\n@@ -51,7 +51,11 @@ public:\n \n ~this() pure nothrow\n {\n- debug (stomp) memset(data.ptr, 0xFF, data.length);\n+ debug (stomp)\n+ {\n+ if (data.ptr)\n+ memset(data.ptr, 0xFF, data.length * T.sizeof);\n+ }\n if (data.ptr && data.ptr != &smallarray[0])\n mem.xfree(data.ptr);\n }\n@@ -201,22 +205,33 @@ public:\n memcpy(p, data.ptr, length * T.sizeof);\n memset(data.ptr, 0xFF, data.length * T.sizeof);\n mem.xfree(data.ptr);\n+ data = p[0 .. allocdim];\n }\n else\n+ {\n auto p = cast(T*)mem.xrealloc(data.ptr, allocdim * T.sizeof);\n- data = p[0 .. allocdim];\n+ data = p[0 .. allocdim];\n+ }\n }\n \n debug (stomp)\n {\n- if (length < data.length)\n- memset(data.ptr + length, 0xFF, (data.length - length) * T.sizeof);\n+ if (data.ptr)\n+ {\n+ if (length < data.length)\n+ memset(data.ptr + length, 0xFF, (data.length - length) * T.sizeof);\n+ }\n }\n else\n {\n if (mem.isGCEnabled)\n- if (length < data.length)\n- memset(data.ptr + length, 0xFF, (data.length - length) * T.sizeof);\n+ {\n+ if (data.ptr)\n+ {\n+ if (length < data.length)\n+ memset(data.ptr + length, 0xFF, (data.length - length) * T.sizeof);\n+ }\n+ }\n }\n }\n \ndiff --git a/gcc/d/dmd/safe.d b/gcc/d/dmd/safe.d\nindex c11ea23c038..464d0120ded 100644\n--- a/gcc/d/dmd/safe.d\n+++ b/gcc/d/dmd/safe.d\n@@ -25,10 +25,11 @@ import dmd.dscope;\n import dmd.dsymbol;\n import dmd.dsymbolsem : determineSize;\n import dmd.errors;\n+import dmd.errorsink;\n import dmd.expression;\n import dmd.func;\n import dmd.funcsem : isRootTraitsCompilesScope;\n-import dmd.globals : FeatureState;\n+import dmd.globals : FeatureState, global;\n import dmd.id;\n import dmd.identifier;\n import dmd.location;\n@@ -365,19 +366,15 @@ bool isTrusted(FuncDeclaration fd)\n * fd = function we are gonna rat on\n * gag = suppress error message (used in escape.d)\n * loc = location of error\n+ * scopeVar = if not null, is the variable whose scope status caused the violation\n * format = printf-style format string\n * args = arguments for %s format specifier\n */\n-extern (D) void reportSafeError(FuncDeclaration fd, bool gag, Loc loc,\n- const(char)* format, RootObject[] args...)\n-{\n- reportSafeError(fd, gag, loc, null, format, args);\n-}\n-\n-/// Overload that also stores the variable whose scope status caused the violation\n-extern (D) void reportSafeError(FuncDeclaration fd, bool gag, Loc loc,\n+private\n+void reportSafeError(FuncDeclaration fd, bool gag, Loc loc,\n VarDeclaration scopeVar, const(char)* format, RootObject[] args...)\n {\n+ ErrorSink eSink = global.errorSink;\n if (fd.type.toTypeFunction().trust == TRUST.system) // function was just inferred to be @system\n {\n if (format)\n@@ -407,7 +404,7 @@ extern (D) void reportSafeError(FuncDeclaration fd, bool gag, Loc loc,\n {\n buf.printf(\" is not allowed in a function with default safety with `-%spreview=safer`\", SwitchPrefix.ptr);\n }\n- .error(loc, \"%s\", buf.extractChars());\n+ eSink.error(loc, \"%s\", buf.extractChars());\n }\n }\n }\n@@ -451,7 +448,7 @@ extern (D) bool setUnsafeCall(FuncDeclaration fd, FuncDeclaration f)\n {\n if (setFunctionToUnsafe(fd))\n {\n- reportSafeError(fd, false, f.loc, null, f, null);\n+ reportSafeError(fd, false, f.loc, null, null, f, null);\n return fd.isSafe();\n }\n return false;\ndiff --git a/gcc/d/dmd/scope.h b/gcc/d/dmd/scope.h\nindex 6c54319e207..94eeee803dd 100644\n--- a/gcc/d/dmd/scope.h\n+++ b/gcc/d/dmd/scope.h\n@@ -131,7 +131,7 @@ struct Scope final\n \n UserAttributeDeclaration *userAttribDecl; // user defined attributes\n \n- DocComment *lastdc; // documentation comment for last symbol at this scope\n+ void *lastdc; // documentation comment for last symbol at this scope (DocComment*)\n AA *anchorCounts; // lookup duplicate anchor name count\n Identifier *prevAnchor; // qualified symbol name of last doc anchor\n \ndiff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d\nindex 2a42668cf5d..46d4a92ebc3 100644\n--- a/gcc/d/dmd/semantic2.d\n+++ b/gcc/d/dmd/semantic2.d\n@@ -320,6 +320,48 @@ private extern(C++) final class Semantic2Visitor : Visitor\n vd.semanticRun = PASS.semantic2done;\n }\n \n+ override void visit(BitFieldDeclaration bfd)\n+ {\n+ visit(cast(VarDeclaration)bfd);\n+ if (bfd.semanticRun != PASS.semantic2done)\n+ return;\n+\n+ if (bfd.fieldWidth == 0)\n+ return;\n+\n+ if (!bfd._init)\n+ return;\n+\n+ auto ei = bfd._init.isExpInitializer();\n+ if (!ei)\n+ return;\n+\n+ if (!ei.exp.isIntegerExp())\n+ return;\n+\n+ import dmd.intrange;\n+ auto value = getIntRange(ei.exp);\n+\n+ const bool isUnsigned = bfd.type.isUnsigned();\n+ auto bounds = IntRange(\n+ SignExtendedNumber(bfd.getMinMax(Id.min), !isUnsigned),\n+ SignExtendedNumber(bfd.getMinMax(Id.max), false)\n+ );\n+\n+ if (!bounds.contains(value))\n+ {\n+ const uwidth = bfd.fieldWidth;\n+ error(ei.loc, \"default initializer `%s` is not representable as bitfield type `%s:%lld`\",\n+ ei.exp.toChars(), bfd.type.toBasetype().toChars(), cast(long)uwidth);\n+ if (isUnsigned)\n+ errorSupplemental(bfd.loc, \"bitfield `%s` default initializer must be a value between `%llu..%llu`\",\n+ bfd.toChars(), bounds.imin.value, bounds.imax.value);\n+ else\n+ errorSupplemental(bfd.loc, \"bitfield `%s` default initializer must be a value between `%lld..%lld`\",\n+ bfd.toChars(), bounds.imin.value, bounds.imax.value);\n+ }\n+ }\n+\n override void visit(Module mod)\n {\n //printf(\"Module::semantic2('%s'): parent = %p\\n\", toChars(), parent);\ndiff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d\nindex 7453d4b3988..15677f1fc6f 100644\n--- a/gcc/d/dmd/semantic3.d\n+++ b/gcc/d/dmd/semantic3.d\n@@ -77,6 +77,12 @@ import dmd.templateparamsem;\n import dmd.typesem;\n import dmd.visitor;\n \n+version (IN_GCC) { /* Not using Fast DFA */ }\n+else version = FastDFA;\n+\n+version (FastDFA)\n+ import dmd.dfa.entry;\n+\n enum LOG = false;\n \n \n@@ -288,7 +294,7 @@ private extern(C++) final class Semantic3Visitor : Visitor\n return;\n funcdecl.semanticRun = PASS.semantic3;\n funcdecl.hasSemantic3Errors = false;\n- funcdecl.saferD = sc.previews.safer;\n+ funcdecl.saferD = sc.previews.safer && !sc.inCfile;\n \n if (!funcdecl.type || funcdecl.type.ty != Tfunction)\n return;\n@@ -1096,6 +1102,10 @@ private extern(C++) final class Semantic3Visitor : Visitor\n else\n {\n auto a = new Statements();\n+\n+ size_t expectedSize = (funcdecl.parameters ? funcdecl.parameters.length : 0) + 7;\n+ a.reserve(expectedSize);\n+\n // Merge in initialization of 'out' parameters\n if (funcdecl.parameters)\n {\n@@ -1420,6 +1430,16 @@ private extern(C++) final class Semantic3Visitor : Visitor\n oblive(funcdecl);\n }\n \n+ version (FastDFA)\n+ {\n+ if (global.params.useFastDFA && global.errors == oldErrors && funcdecl.fbody && funcdecl.type.ty != Terror)\n+ {\n+ // Don't run DFA if there are errors,\n+ // this is a costly enough operation that it warrents the explicit check.\n+ dfaEntry(funcdecl, sc);\n+ }\n+ }\n+\n /* If this function had instantiated with gagging, error reproduction will be\n * done by TemplateInstance::semantic.\n * Otherwise, error gagging should be temporarily ungagged by functionSemantic3.\n@@ -1872,6 +1892,10 @@ extern (D) bool checkClosure(FuncDeclaration fd)\n }\n \n FuncDeclarations a;\n+\n+ if (fd.closureVars.length > 0)\n+ a.reserve(fd.closureVars.length);\n+\n foreach (v; fd.closureVars)\n {\n foreach (f; v.nestedrefs)\ndiff --git a/gcc/d/dmd/sideeffect.d b/gcc/d/dmd/sideeffect.d\nindex 344ef054028..2e579972d35 100644\n--- a/gcc/d/dmd/sideeffect.d\n+++ b/gcc/d/dmd/sideeffect.d\n@@ -242,7 +242,41 @@ private bool lambdaHasSideEffect(Expression e, bool assumeImpureCalls = false)\n bool discardValue(Expression e)\n {\n if (lambdaHasSideEffect(e)) // check side-effect shallowly\n+ {\n+ // check for e.g. `arrayLiteral[index] = expr;`\n+ if (e.isAssignExp() || e.isBinAssignExp() || e.isPostExp())\n+ {\n+ Expression e1;\n+ if (auto be = e.isBinExp()) // includes PostExp\n+ e1 = be.e1;\n+ else if (auto ce = e.isPreExp())\n+ e1 = ce.e1;\n+\n+ if (auto ie = e1 ? e1.isIndexExp() : null)\n+ {\n+ if (ie.e1.isArrayLiteralExp())\n+ error(e.loc, \"discarded assignment to indexed array literal\");\n+ }\n+ }\n+ // check assignment to struct rvalue\n+ auto ce = e.isCallExp();\n+ if (ce && ce.fromOpAssignment)\n+ {\n+ if (auto dve = ce.e1.isDotVarExp())\n+ {\n+ auto lhs = dve.e1;\n+ auto ts = lhs.type.isTypeStruct();\n+ if (ts && !lhs.isLvalue() && !ts.sym.hasPointerField) // Don't disallow writing to data through a pointer field\n+ {\n+ error(lhs.loc, \"assignment to struct rvalue `%s` is discarded\",\n+ lhs.toChars());\n+ errorSupplemental(e.loc, \"if the assignment is needed to modify a global, call `%s` directly or use an lvalue\",\n+ dve.var.toChars());\n+ }\n+ }\n+ }\n return false;\n+ }\n switch (e.op)\n {\n case EXP.cast_:\ndiff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d\nindex 77e1b0cb365..0641c0a85ce 100644\n--- a/gcc/d/dmd/statement.d\n+++ b/gcc/d/dmd/statement.d\n@@ -383,6 +383,10 @@ extern (C++) class ExpStatement : Statement\n this.exp = exp;\n }\n \n+ /*******************************\n+ * Creates a DeclarationExp inside a statement.\n+ * Use in place of *DeclarationStatement* from D grammar.\n+ */\n final extern (D) this(Loc loc, Dsymbol declaration) @safe\n {\n super(loc, STMT.Exp);\n@@ -1416,14 +1420,16 @@ extern (C++) final class SynchronizedStatement : Statement\n */\n extern (C++) final class WithStatement : Statement\n {\n+ Parameter prm;\n Expression exp;\n Statement _body;\n VarDeclaration wthis;\n Loc endloc;\n \n- extern (D) this(Loc loc, Expression exp, Statement _body, Loc endloc) @safe\n+ extern (D) this(Loc loc, Parameter prm, Expression exp, Statement _body, Loc endloc) @safe\n {\n super(loc, STMT.With);\n+ this.prm = prm;\n this.exp = exp;\n this._body = _body;\n this.endloc = endloc;\n@@ -1431,7 +1437,11 @@ extern (C++) final class WithStatement : Statement\n \n override WithStatement syntaxCopy()\n {\n- return new WithStatement(loc, exp.syntaxCopy(), _body ? _body.syntaxCopy() : null, endloc);\n+ return new WithStatement(loc,\n+ prm ? prm.syntaxCopy() : null,\n+ exp.syntaxCopy(),\n+ _body ? _body.syntaxCopy() : null,\n+ endloc);\n }\n \n override void accept(Visitor v)\ndiff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h\nindex e184a62dada..d49f4e47dbe 100644\n--- a/gcc/d/dmd/statement.h\n+++ b/gcc/d/dmd/statement.h\n@@ -561,6 +561,7 @@ public:\n class WithStatement final : public Statement\n {\n public:\n+ Parameter *prm;\n Expression *exp;\n Statement *_body;\n VarDeclaration *wthis;\ndiff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d\nindex e5fa2a8575d..d602f8d30e6 100644\n--- a/gcc/d/dmd/statementsem.d\n+++ b/gcc/d/dmd/statementsem.d\n@@ -1019,7 +1019,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)\n if (tab.isTypeDArray())\n {\n // check if overflow is possible\n- const maxLen = IntRange.fromType(tindex).imax.value + 1;\n+ const maxLen = intRangeFromType(tindex).imax.value + 1;\n if (auto ale = fs.aggr.isArrayLiteralExp())\n err = ale.elements.length > maxLen;\n else if (auto se = fs.aggr.isSliceExp())\n@@ -1082,7 +1082,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)\n IntRange dimrange = getIntRange(ta.dim);\n // https://issues.dlang.org/show_bug.cgi?id=12504\n dimrange.imax = SignExtendedNumber(dimrange.imax.value-1);\n- if (!IntRange.fromType(fs.key.type).contains(dimrange))\n+ if (!intRangeFromType(fs.key.type).contains(dimrange))\n {\n error(fs.loc, \"index type `%s` cannot cover index range 0..%llu\",\n p.type.toChars(), ta.dim.toInteger());\n@@ -3232,6 +3232,32 @@ Statement statementSemanticVisit(Statement s, Scope* sc)\n sym.parent = sc.scopesym;\n sym.endlinnum = ws.endloc.linnum;\n }\n+ else if (ws.prm)\n+ {\n+ /* Re-write to\n+ * {\n+ * auto prm = exp\n+ * with(prm)\n+ * {\n+ * ...\n+ * }\n+ * }\n+ */\n+ auto tmp_init = new ExpInitializer(ws.loc, ws.exp);\n+ auto tmp = new VarDeclaration(ws.loc, ws.prm.type, ws.prm.ident, tmp_init);\n+ // tmp.storage_class |= STC.temp; //NOTE(mojo): idk\n+ tmp.dsymbolSemantic(sc);\n+\n+ auto es = new ExpStatement(ws.loc, tmp);\n+ ws.exp = new VarExp(ws.loc, tmp);\n+\n+ ws.prm = null;\n+ auto cs = new CompoundStatement(ws.loc, es, ws);\n+ Statement ss = new ScopeStatement(ws.loc, cs, ws.endloc);\n+ result = ss.statementSemantic(sc);\n+\n+ return;\n+ }\n else\n {\n Type texp = ws.exp.type;\n@@ -4463,7 +4489,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState\n IntRange dimrange = IntRange(SignExtendedNumber(length))._cast(Type.tsize_t);\n // https://issues.dlang.org/show_bug.cgi?id=12504\n dimrange.imax = SignExtendedNumber(dimrange.imax.value-1);\n- if (!IntRange.fromType(p.type).contains(dimrange))\n+ if (!intRangeFromType(p.type).contains(dimrange))\n {\n error(fs.loc, \"index type `%s` cannot cover index range 0..%llu\",\n p.type.toChars(), cast(ulong)length);\ndiff --git a/gcc/d/dmd/templatesem.d b/gcc/d/dmd/templatesem.d\nindex 3144c2a1397..a2bed8a7cd1 100644\n--- a/gcc/d/dmd/templatesem.d\n+++ b/gcc/d/dmd/templatesem.d\n@@ -2778,7 +2778,9 @@ private MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t\n if (!sa || si != sa)\n return matchArgNoMatch();\n }\n- dedtypes[i] = sa;\n+ // Note: Dsymbol can't have type qualifiers, so use type if it has them\n+ // https://github.com/dlang/dmd/issues/17959\n+ dedtypes[i] = ta && ta.mod ? ta : sa;\n \n if (psparam)\n {\n@@ -5569,7 +5571,7 @@ bool TemplateInstance_semanticTiargs(Loc loc, Scope* sc, Objects* tiargs, int fl\n * errorHelper = delegate to send error message to if not null\n */\n void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc, Objects* tiargs,\n- Type tthis, ArgumentList argumentList, void delegate(const(char)*) scope errorHelper = null)\n+ Type tthis, ArgumentList argumentList, void delegate(const(char)*, Loc argloc = Loc.initial) scope errorHelper = null)\n {\n version (none)\n {\n@@ -7598,7 +7600,39 @@ MATCH deduceType(scope RootObject o, scope Scope* sc, scope Type tparam,\n //printf(\"\\ttf = %s\\n\", tf.toChars());\n const dim = tf.parameterList.length;\n \n- if (tof.parameterList.length != dim || tof.parameterList.varargs != tf.parameterList.varargs)\n+ if (tof.parameterList.varargs != tf.parameterList.varargs)\n+ return;\n+\n+ // https://github.com/dlang/dmd/issues/19905\n+ // Resolve and expand TypeTuples (e.g. from AliasSeq) in tof's parameters\n+ // before comparing counts. We can't call TypeFunction.typeSemantic because\n+ // the return type may contain unresolved template parameters.\n+ Types* expandedTypes;\n+ foreach (pto; *tof.parameterList.parameters)\n+ {\n+ Type pt = pto.type;\n+ if (!reliesOnTemplateParameters(pt, parameters[inferStart .. parameters.length]))\n+ {\n+ pt = pt.syntaxCopy().typeSemantic(e.loc, sc);\n+ if (pt.ty == Terror)\n+ return;\n+ }\n+ if (auto tt = pt.isTypeTuple())\n+ {\n+ if (!expandedTypes)\n+ expandedTypes = new Types();\n+ foreach (arg; *tt.arguments)\n+ expandedTypes.push(arg.type);\n+ }\n+ else\n+ {\n+ if (!expandedTypes)\n+ expandedTypes = new Types();\n+ expandedTypes.push(pt);\n+ }\n+ }\n+\n+ if (!expandedTypes || expandedTypes.length != dim)\n return;\n \n auto tiargs = new Objects();\n@@ -7614,15 +7648,19 @@ MATCH deduceType(scope RootObject o, scope Scope* sc, scope Type tparam,\n ++u;\n }\n assert(u < dim);\n- Parameter pto = tof.parameterList[u];\n- if (!pto)\n+ Type t = (*expandedTypes)[u];\n+ if (!t)\n break;\n- Type t = pto.type.syntaxCopy(); // https://issues.dlang.org/show_bug.cgi?id=11774\n if (reliesOnTemplateParameters(t, parameters[inferStart .. parameters.length]))\n return;\n- t = t.typeSemantic(e.loc, sc);\n- if (t.ty == Terror)\n- return;\n+ // https://issues.dlang.org/show_bug.cgi?id=11774\n+ t = t.syntaxCopy();\n+ if (!t.deco)\n+ {\n+ t = t.typeSemantic(e.loc, sc);\n+ if (t.ty == Terror)\n+ return;\n+ }\n tiargs.push(t);\n }\n \ndiff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d\nindex 58674806337..ecb38c660cf 100644\n--- a/gcc/d/dmd/traits.d\n+++ b/gcc/d/dmd/traits.d\n@@ -2242,8 +2242,8 @@ private bool isSame(RootObject o1, RootObject o2, Scope* sc)\n // https://issues.dlang.org/show_bug.cgi?id=12001, allow isSame, <BasicType>, <BasicType>\n Type t1 = isType(o1);\n Type t2 = isType(o2);\n- if (t1 && t2 && t1.equals(t2))\n- return true;\n+ if (t1 && t2)\n+ return t1.equals(t2);\n \n auto s1 = getDsymbol(o1);\n auto s2 = getDsymbol(o2);\ndiff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d\nindex 49ec6984cf9..779e6bfd7f5 100644\n--- a/gcc/d/dmd/typesem.d\n+++ b/gcc/d/dmd/typesem.d\n@@ -1516,12 +1516,12 @@ private void resolveHelper(TypeQualified mt, Loc loc, Scope* sc, Dsymbol s, Dsym\n if (const n = importHint(id.toString()))\n error(loc, \"`%s` is not defined, perhaps `import %.*s;` ?\", p, cast(int)n.length, n.ptr);\n else if (auto s2 = sc.search_correct(id))\n- error(loc, \"undefined identifier `%s`, did you mean %s `%s`?\", p, s2.kind(), s2.toChars());\n+ error(mt.loc, \"undefined identifier `%s`, did you mean %s `%s`?\", p, s2.kind(), s2.toChars());\n else if (const q = search_correct_C(id))\n- error(loc, \"undefined identifier `%s`, did you mean `%s`?\", p, q);\n+ error(mt.loc, \"undefined identifier `%s`, did you mean `%s`?\", p, q);\n else if ((id == Id.This && sc.getStructClassScope()) ||\n (id == Id._super && sc.getClassScope()))\n- error(loc, \"undefined identifier `%s`, did you mean `typeof(%s)`?\", p, p);\n+ error(mt.loc, \"undefined identifier `%s`, did you mean `typeof(%s)`?\", p, p);\n else\n error(mt.loc, \"undefined identifier `%s`\", p);\n }\n@@ -1529,9 +1529,9 @@ private void resolveHelper(TypeQualified mt, Loc loc, Scope* sc, Dsymbol s, Dsym\n if (const n = cIncludeHint(id.toString()))\n error(loc, \"`%s` is not defined, perhaps `#include %.*s` ?\", p, cast(int)n.length, n.ptr);\n else if (auto s2 = sc.search_correct(id))\n- error(loc, \"undefined identifier `%s`, did you mean %s `%s`?\", p, s2.kind(), s2.toChars());\n+ error(mt.loc, \"undefined identifier `%s`, did you mean %s `%s`?\", p, s2.kind(), s2.toChars());\n else\n- error(loc, \"undefined identifier `%s`\", p);\n+ error(mt.loc, \"undefined identifier `%s`\", p);\n }\n \n pt = Type.terror;\n@@ -2165,7 +2165,7 @@ extern(D) Expressions* resolveNamedArgs(TypeFunction tf, ArgumentList argumentLi\n * MATCHxxxx\n */\n extern (D) MATCH callMatch(FuncDeclaration fd, TypeFunction tf, Type tthis, ArgumentList argumentList,\n- int flag = 0, void delegate(const(char)*) scope errorHelper = null, Scope* sc = null)\n+ int flag = 0, void delegate(const(char)*, Loc argloc = Loc.initial) scope errorHelper = null, Scope* sc = null)\n {\n //printf(\"callMatch() fd: %s, tf: %s\\n\", fd ? fd.ident.toChars() : \"null\", toChars(tf));\n MATCH match = MATCH.exact; // assume exact match\n@@ -2330,12 +2330,20 @@ extern (D) MATCH callMatch(FuncDeclaration fd, TypeFunction tf, Type tthis, Argu\n if (errorHelper)\n {\n if (u >= args.length)\n+ {\n getMatchError(buf, \"missing argument for parameter #%d: `%s`\",\n u + 1, parameterToChars(p, tf, false));\n+ }\n // If an error happened previously, `pMessage` was already filled\n else if (buf.length == 0)\n+ {\n buf.writestring(tf.getParamError(args[u], p));\n-\n+ if(args[u].loc !is Loc.initial)\n+ {\n+ errorHelper(buf.peekChars(),args[u].loc);\n+ return MATCH.nomatch;\n+ }\n+ }\n errorHelper(buf.peekChars());\n }\n return MATCH.nomatch;\n@@ -4919,7 +4927,7 @@ Expression defaultInitLiteral(Type t, Loc loc)\n return ErrorExp.get();\n \n auto structelems = new Expressions(ts.sym.nonHiddenFields());\n- uint offset = 0;\n+ ulong bitoffset = 0;\n foreach (j; 0 .. structelems.length)\n {\n VarDeclaration vd = ts.sym.fields[j];\n@@ -4929,7 +4937,11 @@ Expression defaultInitLiteral(Type t, Loc loc)\n error(loc, \"circular reference to `%s`\", vd.toPrettyChars());\n return ErrorExp.get();\n }\n- if (vd.offset < offset || vd.type.size() == 0)\n+ ulong vbitoffset = vd.offset * 8;\n+ auto vbf = vd.isBitFieldDeclaration();\n+ if (vbf)\n+ vbitoffset += vbf.bitOffset;\n+ if (vbitoffset < bitoffset || vd.type.size() == 0)\n e = null;\n else if (vd._init)\n {\n@@ -4943,7 +4955,12 @@ Expression defaultInitLiteral(Type t, Loc loc)\n if (e && e.op == EXP.error)\n return e;\n if (e)\n- offset = vd.offset + cast(uint)vd.type.size();\n+ {\n+ if (vbf)\n+ bitoffset = vbitoffset + vbf.fieldWidth;\n+ else\n+ bitoffset = vbitoffset + vd.type.size() * 8;\n+ }\n (*structelems)[j] = e;\n }\n auto structinit = new StructLiteralExp(loc, ts.sym, structelems);\ndiff --git a/gcc/testsuite/gdc.test/compilable/alias_param_qual.d b/gcc/testsuite/gdc.test/compilable/alias_param_qual.d\nnew file mode 100644\nindex 00000000000..ac902e7d2c8\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/alias_param_qual.d\n@@ -0,0 +1,7 @@\n+alias t(alias a) = a;\n+\n+static assert(is(t!(const Object) == const Object));\n+static assert(is(t!(shared(Object)) == shared Object));\n+static assert(is(t!(immutable S) == immutable(S)));\n+\n+struct S {}\ndiff --git a/gcc/testsuite/gdc.test/compilable/b12001.d b/gcc/testsuite/gdc.test/compilable/b12001.d\nindex f67c8957514..c3ef089627e 100644\n--- a/gcc/testsuite/gdc.test/compilable/b12001.d\n+++ b/gcc/testsuite/gdc.test/compilable/b12001.d\n@@ -6,4 +6,8 @@ void main()\n \n static assert(!__traits(isSame, bool*, bool[]));\n static assert(!__traits(isSame, float, double));\n+\n+ // https://github.com/dlang/dmd/issues/22442\n+ static assert(!__traits(isSame, int, const int));\n+ static assert(!__traits(isSame, Object, const Object));\n }\ndiff --git a/gcc/testsuite/gdc.test/compilable/depmsg.d b/gcc/testsuite/gdc.test/compilable/depmsg.d\nindex 2c29e05a588..ed90a62c720 100644\n--- a/gcc/testsuite/gdc.test/compilable/depmsg.d\n+++ b/gcc/testsuite/gdc.test/compilable/depmsg.d\n@@ -2,19 +2,32 @@\n REQUIRED_ARGS: -verrors=simple -dw\n TEST_OUTPUT:\n ---\n-compilable/depmsg.d(39): Deprecation: struct `depmsg.main.Inner.A` is deprecated - With message!\n-compilable/depmsg.d(39): Deprecation: struct `depmsg.main.Inner.A` is deprecated - With message!\n-compilable/depmsg.d(40): Deprecation: class `depmsg.main.Inner.B` is deprecated - With message!\n-compilable/depmsg.d(40): Deprecation: class `depmsg.main.Inner.B` is deprecated - With message!\n-compilable/depmsg.d(41): Deprecation: interface `depmsg.main.Inner.C` is deprecated - With message!\n-compilable/depmsg.d(41): Deprecation: interface `depmsg.main.Inner.C` is deprecated - With message!\n-compilable/depmsg.d(42): Deprecation: union `depmsg.main.Inner.D` is deprecated - With message!\n-compilable/depmsg.d(42): Deprecation: union `depmsg.main.Inner.D` is deprecated - With message!\n-compilable/depmsg.d(43): Deprecation: enum `depmsg.main.Inner.E` is deprecated - With message!\n-compilable/depmsg.d(43): Deprecation: enum `depmsg.main.Inner.E` is deprecated - With message!\n-compilable/depmsg.d(45): Deprecation: alias `depmsg.main.Inner.G` is deprecated - With message!\n-compilable/depmsg.d(46): Deprecation: variable `depmsg.main.Inner.H` is deprecated - With message!\n-compilable/depmsg.d(47): Deprecation: class `depmsg.main.Inner.I()` is deprecated - With message!\n+compilable/depmsg.d(52): Deprecation: struct `depmsg.main.Inner.A` is deprecated - With message!\n+compilable/depmsg.d(39): `A` is declared here\n+compilable/depmsg.d(52): Deprecation: struct `depmsg.main.Inner.A` is deprecated - With message!\n+compilable/depmsg.d(39): `A` is declared here\n+compilable/depmsg.d(53): Deprecation: class `depmsg.main.Inner.B` is deprecated - With message!\n+compilable/depmsg.d(40): `B` is declared here\n+compilable/depmsg.d(53): Deprecation: class `depmsg.main.Inner.B` is deprecated - With message!\n+compilable/depmsg.d(40): `B` is declared here\n+compilable/depmsg.d(54): Deprecation: interface `depmsg.main.Inner.C` is deprecated - With message!\n+compilable/depmsg.d(41): `C` is declared here\n+compilable/depmsg.d(54): Deprecation: interface `depmsg.main.Inner.C` is deprecated - With message!\n+compilable/depmsg.d(41): `C` is declared here\n+compilable/depmsg.d(55): Deprecation: union `depmsg.main.Inner.D` is deprecated - With message!\n+compilable/depmsg.d(42): `D` is declared here\n+compilable/depmsg.d(55): Deprecation: union `depmsg.main.Inner.D` is deprecated - With message!\n+compilable/depmsg.d(42): `D` is declared here\n+compilable/depmsg.d(56): Deprecation: enum `depmsg.main.Inner.E` is deprecated - With message!\n+compilable/depmsg.d(43): `E` is declared here\n+compilable/depmsg.d(56): Deprecation: enum `depmsg.main.Inner.E` is deprecated - With message!\n+compilable/depmsg.d(43): `E` is declared here\n+compilable/depmsg.d(58): Deprecation: alias `depmsg.main.Inner.G` is deprecated - With message!\n+compilable/depmsg.d(45): `G` is declared here\n+compilable/depmsg.d(59): Deprecation: variable `depmsg.main.Inner.H` is deprecated - With message!\n+compilable/depmsg.d(46): `H` is declared here\n+compilable/depmsg.d(60): Deprecation: class `depmsg.main.Inner.I()` is deprecated - With message!\n+compilable/depmsg.d(47): `I()` is declared here\n ---\n */\n void main()\ndiff --git a/gcc/testsuite/gdc.test/compilable/deprecationlimit.d b/gcc/testsuite/gdc.test/compilable/deprecationlimit.d\nindex 2b7d45c393f..f749d7ff32b 100644\n--- a/gcc/testsuite/gdc.test/compilable/deprecationlimit.d\n+++ b/gcc/testsuite/gdc.test/compilable/deprecationlimit.d\n@@ -2,9 +2,12 @@\n REQUIRED_ARGS: -verrors=simple -verrors=3\n TEST_OUTPUT:\n ---\n-compilable/deprecationlimit.d(18): Deprecation: function `deprecationlimit.f` is deprecated\n-compilable/deprecationlimit.d(19): Deprecation: function `deprecationlimit.f` is deprecated\n-compilable/deprecationlimit.d(20): Deprecation: function `deprecationlimit.f` is deprecated\n+compilable/deprecationlimit.d(21): Deprecation: function `deprecationlimit.f` is deprecated\n+compilable/deprecationlimit.d(15): `f` is declared here\n+compilable/deprecationlimit.d(22): Deprecation: function `deprecationlimit.f` is deprecated\n+compilable/deprecationlimit.d(15): `f` is declared here\n+compilable/deprecationlimit.d(23): Deprecation: function `deprecationlimit.f` is deprecated\n+compilable/deprecationlimit.d(15): `f` is declared here\n 1 deprecation warning omitted, use `-verrors=0` to show all\n ---\n */\ndiff --git a/gcc/testsuite/gdc.test/compilable/imports/defines.c b/gcc/testsuite/gdc.test/compilable/imports/defines.c\nindex 420679a4fcc..a805627db67 100644\n--- a/gcc/testsuite/gdc.test/compilable/imports/defines.c\n+++ b/gcc/testsuite/gdc.test/compilable/imports/defines.c\n@@ -63,3 +63,9 @@ int pr16199c()\n #define NEGATIVE_U64 -4LLU\n #define NEGATIVE_F32 -5.0f\n #define NEGATIVE_F64 -6.0\n+\n+// https://github.com/dlang/dmd/pull/22347 - bare function-like macro calls\n+#define DOUBLE(x) ((x) * 2)\n+#define BARE_CALL DOUBLE(5) // bare function-like macro call (no outer parens)\n+#define PAREN_CALL (DOUBLE(5)) // parenthesized call (already works)\n+#define WRAPPER(x) DOUBLE(x) // function-like macro calling another macro\ndiff --git a/gcc/testsuite/gdc.test/compilable/issue22254.d b/gcc/testsuite/gdc.test/compilable/issue22254.d\nnew file mode 100644\nindex 00000000000..94025c18da8\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/issue22254.d\n@@ -0,0 +1,6 @@\n+// https://github.com/dlang/dmd/issues/22254\n+\n+void main()\n+{\n+ assert(assert(0, \"\"), \"\");\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/issue22397.d b/gcc/testsuite/gdc.test/compilable/issue22397.d\nnew file mode 100644\nindex 00000000000..5e2c54c6bf5\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/issue22397.d\n@@ -0,0 +1,14 @@\n+// REQUIRED_ARGS:\n+/*\n+TEST_OUTPUT:\n+---\n+---\n+*/\n+void main()\n+{\n+ enum var = true;\n+ @var string[] list = [\"A\", \"B\", \"C\"];\n+\n+ // Also test explicitly with @(value) syntax\n+ @(1) int[] list2 = [1, 2, 3];\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/issue22448.d b/gcc/testsuite/gdc.test/compilable/issue22448.d\nnew file mode 100644\nindex 00000000000..6fa23f80dbe\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/issue22448.d\n@@ -0,0 +1,8 @@\n+// PERMUTE_ARGS: -O\n+\n+void sliceAssign()\n+{\n+ enum size_t len = 2_147_483_648UL;\n+ char* src, dst;\n+ dst[0 .. len] = src[0 .. len];\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/test19905.d b/gcc/testsuite/gdc.test/compilable/test19905.d\nnew file mode 100644\nindex 00000000000..f8c1757c865\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/test19905.d\n@@ -0,0 +1,29 @@\n+// https://github.com/dlang/dmd/issues/19905\n+// Type list (tuple) not expanded in delegate during IFTI\n+\n+alias AliasSeq(TList...) = TList;\n+\n+struct S\n+{\n+ void m() {}\n+}\n+\n+void fun1(R)(R delegate(AliasSeq!S) dg) {}\n+void fun2(R)(R delegate(AliasSeq!(S, S)) dg) {}\n+void fun3(R)(R delegate(AliasSeq!(S, S, S)) dg) {}\n+void fun0(R)(R delegate(AliasSeq!()) dg) {}\n+\n+void main()\n+{\n+ // Explicit template argument always worked\n+ fun1!void((a) { a.m(); });\n+ fun2!void((a, b) { a.m(); b.m(); });\n+ fun3!void((a, b, c) { a.m(); b.m(); c.m(); });\n+ fun0!void(() {});\n+\n+ // IFTI with tuple expansion - was broken, now fixed\n+ fun1((a) { a.m(); });\n+ fun2((a, b) { a.m(); b.m(); });\n+ fun3((a, b, c) { a.m(); b.m(); c.m(); });\n+ fun0(() {});\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/test22323.d b/gcc/testsuite/gdc.test/compilable/test22323.d\nnew file mode 100644\nindex 00000000000..e9c1899b476\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/test22323.d\n@@ -0,0 +1,12 @@\n+// REQUIRED_ARGS: -preview=dip1000\n+\n+struct Schema\n+{\n+ int[int] tables;\n+}\n+struct S(Schema s)\n+{\n+ void g() { cast(void)s.tables; }\n+}\n+auto makeSchema() => Schema([0: 0]);\n+alias Row = S!(makeSchema());\ndiff --git a/gcc/testsuite/gdc.test/compilable/test22381.d b/gcc/testsuite/gdc.test/compilable/test22381.d\nnew file mode 100644\nindex 00000000000..6554f98f14c\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/test22381.d\n@@ -0,0 +1,17 @@\n+/*\n+DISABLED: osx\n+REQUIRED_ARGS: -vasm\n+TEST_OUTPUT:\n+---\n+_D9test223814maskFPtZv:\n+0000: $r:[0-9A-F ]*$and word ptr [$r:[A-Z]*$],0FFFEh\n+0005: C3 ret\n+---\n+*/\n+\n+// https://github.com/dlang/dmd/issues/22381\n+\n+void mask(ushort* p)\n+{\n+ *p &= 0xfffe;\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/test22383.d b/gcc/testsuite/gdc.test/compilable/test22383.d\nnew file mode 100644\nindex 00000000000..8106ab18391\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/test22383.d\n@@ -0,0 +1,12 @@\n+struct T22383\n+{\n+ int a = 4;\n+ int b : 16;\n+ int c : 8;\n+ int d : 4;\n+ int e : 2;\n+ int f : 1;\n+ int g : 1;\n+ int h = 8;\n+}\n+static assert(T22383.init == T22383(4,0,0,0,0,0,0,8));\ndiff --git a/gcc/testsuite/gdc.test/compilable/test9701.d b/gcc/testsuite/gdc.test/compilable/test9701.d\nindex 81b56bdb658..39fd4da9981 100644\n--- a/gcc/testsuite/gdc.test/compilable/test9701.d\n+++ b/gcc/testsuite/gdc.test/compilable/test9701.d\n@@ -3,8 +3,10 @@\n /*\n TEST_OUTPUT:\n ---\n-compilable/test9701.d(69): Deprecation: enum member `test9701.Enum.value7` is deprecated\n-compilable/test9701.d(69): Deprecation: enum member `test9701.Enum.value8` is deprecated - message\n+compilable/test9701.d(71): Deprecation: enum member `test9701.Enum.value7` is deprecated\n+compilable/test9701.d(36): `value7` is declared here\n+compilable/test9701.d(71): Deprecation: enum member `test9701.Enum.value8` is deprecated - message\n+compilable/test9701.d(37): `value8` is declared here\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/compilable/testdefines.d b/gcc/testsuite/gdc.test/compilable/testdefines.d\nindex 58eefb7256a..ba193d2fdad 100644\n--- a/gcc/testsuite/gdc.test/compilable/testdefines.d\n+++ b/gcc/testsuite/gdc.test/compilable/testdefines.d\n@@ -39,3 +39,9 @@ static assert(is(typeof(NEGATIVE_I64) == long));\n static assert(is(typeof(NEGATIVE_U64) == ulong));\n static assert(is(typeof(NEGATIVE_F32) == float));\n static assert(is(typeof(NEGATIVE_F64) == double));\n+\n+// https://github.com/dlang/dmd/pull/22347 - bare function-like macro calls\n+static assert(DOUBLE(5) == 10);\n+static assert(BARE_CALL == 10); // bare call now works\n+static assert(PAREN_CALL == 10); // parenthesized already worked\n+static assert(WRAPPER(3) == 6); // function-like macro calling another macro\ndiff --git a/gcc/testsuite/gdc.test/compilable/zerosize2.d b/gcc/testsuite/gdc.test/compilable/zerosize2.d\nnew file mode 100644\nindex 00000000000..8f418dc4f44\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/zerosize2.d\n@@ -0,0 +1,178 @@\n+// Test zero sized fields where TargetC.contributesToAlignment\n+extern(D)\n+{\n+ struct D0 { }\n+ struct D1 { byte : 0; }\n+ struct D2 { short : 0; }\n+ struct D3 { int : 0; }\n+ struct D4 { long : 0; }\n+ struct D5 { byte[0] f; }\n+ struct D6 { short[0] f; }\n+ struct D7 { int[0] f; }\n+ struct D8 { long[0] f; }\n+ struct D9 { int : 0; short[0] f; }\n+ align(16)\n+ {\n+ struct D10 { }\n+ struct D11 { byte : 0; }\n+ struct D12 { short : 0; }\n+ struct D13 { int : 0; }\n+ struct D14 { long : 0; }\n+ struct D15 { byte[0] f; }\n+ struct D16 { short[0] f; }\n+ struct D17 { int[0] f; }\n+ struct D18 { long[0] f; }\n+ struct D19 { int : 0; short[0] f; }\n+ }\n+}\n+\n+extern(C)\n+{\n+ struct C0 { }\n+ struct C1 { byte : 0; }\n+ struct C2 { short : 0; }\n+ struct C3 { int : 0; }\n+ struct C4 { long : 0; }\n+ struct C5 { byte[0] f; }\n+ struct C6 { short[0] f; }\n+ struct C7 { int[0] f; }\n+ struct C8 { long[0] f; }\n+ struct C9 { int : 0; short[0] f; }\n+ align(16)\n+ {\n+ struct C10 { }\n+ struct C11 { byte : 0; }\n+ struct C12 { short : 0; }\n+ struct C13 { int : 0; }\n+ struct C14 { long : 0; }\n+ struct C15 { byte[0] f; }\n+ struct C16 { short[0] f; }\n+ struct C17 { int[0] f; }\n+ struct C18 { long[0] f; }\n+ struct C19 { int : 0; short[0] f; }\n+ }\n+}\n+\n+version (Posix):\n+\n+// Anonymous bitfields don't contribute to alignment.\n+version (X86_64)\n+{\n+ // Empty\n+ static assert(D0.sizeof == 1 && D0.alignof == 1);\n+ static assert(D10.sizeof == 16 && D10.alignof == 16);\n+\n+ // Zero width bitfields\n+ static assert(D1.sizeof == 1 && D1.alignof == 1);\n+ static assert(D2.sizeof == 1 && D2.alignof == 1);\n+ static assert(D3.sizeof == 1 && D3.alignof == 1);\n+ static assert(D4.sizeof == 1 && D4.alignof == 1);\n+ static assert(D11.sizeof == 16 && D11.alignof == 16);\n+ static assert(D12.sizeof == 16 && D12.alignof == 16);\n+ static assert(D13.sizeof == 16 && D13.alignof == 16);\n+ static assert(D14.sizeof == 16 && D14.alignof == 16);\n+\n+ // Zero sized arrays\n+ static assert(D5.sizeof == 1 && D5.alignof == 1);\n+ static assert(D6.sizeof == 2 && D6.alignof == 2);\n+ static assert(D7.sizeof == 4 && D7.alignof == 4);\n+ static assert(D8.sizeof == 8 && D8.alignof == 8);\n+ static assert(D15.sizeof == 16 && D15.alignof == 16);\n+ static assert(D16.sizeof == 16 && D16.alignof == 16);\n+ static assert(D17.sizeof == 16 && D17.alignof == 16);\n+ static assert(D18.sizeof == 16 && D18.alignof == 16);\n+\n+ // Mixed zero sized bitfields and arrays\n+ static assert(D9.sizeof == 2 && D9.alignof == 2);\n+ static assert(D19.sizeof == 16 && D19.alignof == 16);\n+\n+ // Empty\n+ static assert(C0.sizeof == 0 && C0.alignof == 1);\n+ static assert(C10.sizeof == 0 && C10.alignof == 16);\n+\n+ // Zero width bitfields\n+ static assert(C1.sizeof == 0 && C1.alignof == 1);\n+ static assert(C2.sizeof == 0 && C2.alignof == 1);\n+ static assert(C3.sizeof == 0 && C3.alignof == 1);\n+ static assert(C4.sizeof == 0 && C4.alignof == 1);\n+ static assert(C11.sizeof == 0 && C11.alignof == 16);\n+ static assert(C12.sizeof == 0 && C12.alignof == 16);\n+ static assert(C13.sizeof == 0 && C13.alignof == 16);\n+ static assert(C14.sizeof == 0 && C14.alignof == 16);\n+\n+ // Zero sized arrays\n+ static assert(C5.sizeof == 0 && C5.alignof == 1);\n+ static assert(C6.sizeof == 0 && C6.alignof == 2);\n+ static assert(C7.sizeof == 0 && C7.alignof == 4);\n+ static assert(C8.sizeof == 0 && C8.alignof == 8);\n+ static assert(C15.sizeof == 0 && C15.alignof == 16);\n+ static assert(C16.sizeof == 0 && C16.alignof == 16);\n+ static assert(C17.sizeof == 0 && C17.alignof == 16);\n+ static assert(C18.sizeof == 0 && C18.alignof == 16);\n+\n+ // Mixed zero sized bitfields and arrays\n+ static assert(C9.sizeof == 0 && C9.alignof == 2);\n+ static assert(C19.sizeof == 0 && C19.alignof == 16);\n+}\n+\n+// Anonymous bitfields *do* contribute to alignment.\n+version (AArch64)\n+{\n+ // Empty\n+ static assert(D0.sizeof == 1 && D0.alignof == 1);\n+ static assert(D10.sizeof == 16 && D10.alignof == 16);\n+\n+ // Zero width bitfields\n+ static assert(D1.sizeof == 1 && D1.alignof == 1);\n+ static assert(D2.sizeof == 2 && D2.alignof == 2);\n+ static assert(D3.sizeof == 4 && D3.alignof == 4);\n+ static assert(D4.sizeof == 8 && D4.alignof == 8);\n+ static assert(D11.sizeof == 16 && D11.alignof == 16);\n+ static assert(D12.sizeof == 16 && D12.alignof == 16);\n+ static assert(D13.sizeof == 16 && D13.alignof == 16);\n+ static assert(D14.sizeof == 16 && D14.alignof == 16);\n+\n+ // Zero sized arrays\n+ static assert(D5.sizeof == 1 && D5.alignof == 1);\n+ static assert(D6.sizeof == 2 && D6.alignof == 2);\n+ static assert(D7.sizeof == 3 && D7.alignof == 4);\n+ static assert(D8.sizeof == 4 && D8.alignof == 8);\n+ static assert(D15.sizeof == 16 && D15.alignof == 16);\n+ static assert(D16.sizeof == 16 && D16.alignof == 16);\n+ static assert(D17.sizeof == 16 && D17.alignof == 16);\n+ static assert(D18.sizeof == 16 && D18.alignof == 16);\n+\n+ // Mixed zero sized bitfields and arrays\n+ static assert(D9.sizeof == 4 && D9.alignof == 4);\n+ static assert(D19.sizeof == 16 && D19.alignof == 16);\n+\n+ /// extern(C):\n+\n+ // Empty\n+ static assert(C0.sizeof == 0 && C0.alignof == 1);\n+ static assert(C10.sizeof == 0 && C10.alignof == 16);\n+\n+ // Zero width bitfields\n+ static assert(C1.sizeof == 0 && C1.alignof == 1);\n+ static assert(C2.sizeof == 0 && C2.alignof == 2);\n+ static assert(C3.sizeof == 0 && C3.alignof == 4);\n+ static assert(C4.sizeof == 0 && C4.alignof == 8);\n+ static assert(C11.sizeof == 0 && C11.alignof == 16);\n+ static assert(C12.sizeof == 0 && C12.alignof == 16);\n+ static assert(C13.sizeof == 0 && C13.alignof == 16);\n+ static assert(C14.sizeof == 0 && C14.alignof == 16);\n+\n+ // Zero sized arrays\n+ static assert(C5.sizeof == 0 && C5.alignof == 1);\n+ static assert(C6.sizeof == 0 && C6.alignof == 2);\n+ static assert(C7.sizeof == 0 && C7.alignof == 4);\n+ static assert(C8.sizeof == 0 && C8.alignof == 8);\n+ static assert(C15.sizeof == 0 && C15.alignof == 16);\n+ static assert(C16.sizeof == 0 && C16.alignof == 16);\n+ static assert(C17.sizeof == 0 && C17.alignof == 16);\n+ static assert(C18.sizeof == 0 && C18.alignof == 16);\n+\n+ // Mixed zero sized bitfields and arrays\n+ static assert(C9.sizeof == 0 && C9.alignof == 4);\n+ static assert(C19.sizeof == 0 && C19.alignof == 16);\n+}\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/array_literal_assign.d b/gcc/testsuite/gdc.test/fail_compilation/array_literal_assign.d\nnew file mode 100644\nindex 00000000000..f10b5d63c12\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/array_literal_assign.d\n@@ -0,0 +1,22 @@\n+/*\n+TEST_OUTPUT:\n+---\n+fail_compilation/array_literal_assign.d(13): Error: discarded assignment to indexed array literal\n+fail_compilation/array_literal_assign.d(15): Error: discarded assignment to indexed array literal\n+fail_compilation/array_literal_assign.d(16): Error: discarded assignment to indexed array literal\n+fail_compilation/array_literal_assign.d(17): Error: discarded assignment to indexed array literal\n+---\n+*/\n+\n+void main()\n+{\n+\t[1, 2, 3][2] = 4;\n+\tenum e = [1, 2];\n+\te[0]++;\n+\t++e[0];\n+\te[0] += 1;\n+\n+\tref x = (e[0] = 4); // OK\n+\tx++;\n+\tassert(x == 5);\n+}\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/b23686.d b/gcc/testsuite/gdc.test/fail_compilation/b23686.d\nindex 5838f5c8e10..680c91a1009 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/b23686.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/b23686.d\n@@ -1,7 +1,7 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/b23686.d(107): Error: undefined identifier `eFN1`, did you mean template `eFN0()()`?\n+fail_compilation/b23686.d-mixin-107(107): Error: undefined identifier `eFN1`, did you mean template `eFN0()()`?\n fail_compilation/b23686.d(107): Error: `mixin(_error_)` does not give a valid type\n fail_compilation/b23686.d(115): while looking for match for `eload!(int, 1)`\n fail_compilation/b23686.d-mixin-121(121): Error: undefined identifier `FNwtf`\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/biterrors.d b/gcc/testsuite/gdc.test/fail_compilation/biterrors.d\nindex e14001b1b9a..91a067295a0 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/biterrors.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/biterrors.d\n@@ -1,7 +1,6 @@\n /*\n * TEST_OUTPUT:\n ---\n-fail_compilation/biterrors.d(103): Error: initializer not allowed for bitfield declaration\n fail_compilation/biterrors.d(104): Error: storage class not allowed for bitfield declaration\n ---\n */\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/biterrors2.d b/gcc/testsuite/gdc.test/fail_compilation/biterrors2.d\nindex 7c7de339461..2c240b53d1a 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/biterrors2.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/biterrors2.d\n@@ -1,9 +1,15 @@\n-/*\n+/* REQUIRED_ARGS: -verrors=context\n * TEST_OUTPUT:\n ---\n fail_compilation/biterrors2.d(100): Error: variable `biterrors2.a` - bitfield must be member of struct, union, or class\n-fail_compilation/biterrors2.d(104): Error: bitfield `b` has zero width\n-fail_compilation/biterrors2.d(105): Error: bitfield type `float` is not an integer type\n+int a : 2;\n+ ^\n+fail_compilation/biterrors2.d(104): Error: bitfield `b` cannot have zero width\n+ int b:0;\n+ ^\n+fail_compilation/biterrors2.d(105): Error: bitfield `c` cannot be of non-integral type `float`\n+ float c:3;\n+ ^\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/biterrors6.d b/gcc/testsuite/gdc.test/fail_compilation/biterrors6.d\nnew file mode 100644\nindex 00000000000..d10c1e1b213\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/biterrors6.d\n@@ -0,0 +1,24 @@\n+/* REQUIRED_ARGS: -verrors=context\n+ * TEST_OUTPUT:\n+---\n+fail_compilation/biterrors6.d(20): Error: anonymous bitfield cannot be of non-integral type `noreturn`\n+ noreturn : -1;\n+ ^\n+fail_compilation/biterrors6.d(21): Error: anonymous bitfield has negative width `-1`\n+ int : -1;\n+ ^\n+fail_compilation/biterrors6.d(22): Error: bitfield `n` cannot be of non-integral type `noreturn`\n+ noreturn n : -500;\n+ ^\n+fail_compilation/biterrors6.d(23): Error: bitfield `i` has negative width `-500`\n+ int i : -500;\n+ ^\n+---\n+*/\n+struct S\n+{\n+ noreturn : -1;\n+ int : -1;\n+ noreturn n : -500;\n+ int i : -500;\n+}\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/biterrors7.d b/gcc/testsuite/gdc.test/fail_compilation/biterrors7.d\nnew file mode 100644\nindex 00000000000..2ecb91530d4\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/biterrors7.d\n@@ -0,0 +1,15 @@\n+/* REQUIRED_ARGS: -verrors=context\n+ * TEST_OUTPUT:\n+---\n+fail_compilation/biterrors7.d(14): Error: struct `biterrors7.S` cannot have anonymous field with same struct type\n+ S : S();\n+ ^\n+fail_compilation/biterrors7.d(14): Error: anonymous bitfield cannot be of non-integral type `S`\n+ S : S();\n+ ^\n+---\n+*/\n+struct S\n+{\n+ S : S();\n+}\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/dep_d1_ops.d b/gcc/testsuite/gdc.test/fail_compilation/dep_d1_ops.d\nindex 83e700632a8..2b51051a00d 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/dep_d1_ops.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/dep_d1_ops.d\n@@ -5,23 +5,23 @@ TEST_OUTPUT:\n fail_compilation/dep_d1_ops.d(281): Error: operator `+` is not defined for type `S`\n fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : \"+\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(282): Error: operator `+` is not defined for type `S`\n-fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"+\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"+\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(283): Error: operator `-` is not defined for type `S`\n fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : \"-\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(284): Error: operator `-` is not defined for type `S`\n-fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"-\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"-\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(285): Error: operator `*` is not defined for type `S`\n fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : \"*\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(286): Error: operator `*` is not defined for type `S`\n-fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"*\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"*\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(287): Error: operator `/` is not defined for type `S`\n fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : \"/\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(288): Error: operator `/` is not defined for type `S`\n-fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"/\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"/\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(289): Error: operator `%` is not defined for type `S`\n fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : \"%\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(290): Error: operator `%` is not defined for type `S`\n-fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"%\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"%\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(292): Error: operator `&` is not defined for type `S`\n fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : \"&\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(293): Error: operator `|` is not defined for type `S`\n@@ -31,19 +31,19 @@ fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `a\n fail_compilation/dep_d1_ops.d(296): Error: operator `<<` is not defined for type `S`\n fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : \"<<\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(297): Error: operator `<<` is not defined for type `S`\n-fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"<<\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"<<\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(298): Error: operator `>>` is not defined for type `S`\n fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : \">>\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(299): Error: operator `>>` is not defined for type `S`\n-fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \">>\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \">>\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(300): Error: operator `>>>` is not defined for type `S`\n fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : \">>>\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(301): Error: operator `>>>` is not defined for type `S`\n-fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \">>>\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \">>>\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(303): Error: operator `~` is not defined for type `S`\n fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : \"~\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(304): Error: operator `~` is not defined for type `S`\n-fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"~\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"~\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(306): Error: operator `+` is not defined for `S`\n fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opUnary(string op : \"+\")() {}`\n fail_compilation/dep_d1_ops.d(307): Error: operator `-` is not defined for `S`\n@@ -59,7 +59,7 @@ fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `a\n fail_compilation/dep_d1_ops.d(313): Error: operator `in` is not defined for type `S`\n fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinary(string op : \"in\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(314): Error: operator `in` is not defined for type `S`\n-fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"in\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(174): perhaps overload the operator with `auto opBinaryRight(string op : \"in\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(316): Error: operator `+=` not supported for `s` of type `S`\n fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(string op : \"+\")(int) {}`\n fail_compilation/dep_d1_ops.d(317): Error: operator `-=` not supported for `s` of type `S`\n@@ -87,23 +87,23 @@ fail_compilation/dep_d1_ops.d(174): perhaps implement `auto opOpAssign(st\n fail_compilation/dep_d1_ops.d(331): Error: operator `+` is not defined for type `dep_d1_ops.C`\n fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : \"+\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(332): Error: operator `+` is not defined for type `dep_d1_ops.C`\n-fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"+\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"+\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(333): Error: operator `-` is not defined for type `dep_d1_ops.C`\n fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : \"-\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(334): Error: operator `-` is not defined for type `dep_d1_ops.C`\n-fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"-\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"-\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(335): Error: operator `*` is not defined for type `dep_d1_ops.C`\n fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : \"*\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(336): Error: operator `*` is not defined for type `dep_d1_ops.C`\n-fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"*\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"*\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(337): Error: operator `/` is not defined for type `dep_d1_ops.C`\n fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : \"/\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(338): Error: operator `/` is not defined for type `dep_d1_ops.C`\n-fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"/\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"/\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(339): Error: operator `%` is not defined for type `dep_d1_ops.C`\n fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : \"%\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(340): Error: operator `%` is not defined for type `dep_d1_ops.C`\n-fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"%\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"%\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(342): Error: operator `&` is not defined for type `dep_d1_ops.C`\n fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : \"&\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(343): Error: operator `|` is not defined for type `dep_d1_ops.C`\n@@ -113,19 +113,19 @@ fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `a\n fail_compilation/dep_d1_ops.d(346): Error: operator `<<` is not defined for type `dep_d1_ops.C`\n fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : \"<<\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(347): Error: operator `<<` is not defined for type `dep_d1_ops.C`\n-fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"<<\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"<<\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(348): Error: operator `>>` is not defined for type `dep_d1_ops.C`\n fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : \">>\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(349): Error: operator `>>` is not defined for type `dep_d1_ops.C`\n-fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \">>\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \">>\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(350): Error: operator `>>>` is not defined for type `dep_d1_ops.C`\n fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : \">>>\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(351): Error: operator `>>>` is not defined for type `dep_d1_ops.C`\n-fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \">>>\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \">>>\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(353): Error: operator `~` is not defined for type `dep_d1_ops.C`\n fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : \"~\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(354): Error: operator `~` is not defined for type `dep_d1_ops.C`\n-fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"~\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"~\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(356): Error: operator `+` is not defined for `C`\n fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opUnary(string op : \"+\")() {}`\n fail_compilation/dep_d1_ops.d(357): Error: operator `-` is not defined for `C`\n@@ -141,7 +141,7 @@ fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `a\n fail_compilation/dep_d1_ops.d(363): Error: operator `in` is not defined for type `dep_d1_ops.C`\n fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinary(string op : \"in\")(int rhs) {}`\n fail_compilation/dep_d1_ops.d(364): Error: operator `in` is not defined for type `dep_d1_ops.C`\n-fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"in\")(int rhs) {}`\n+fail_compilation/dep_d1_ops.d(225): perhaps overload the operator with `auto opBinaryRight(string op : \"in\")(int lhs) {}`\n fail_compilation/dep_d1_ops.d(366): Error: operator `+=` not supported for `c` of type `C`\n fail_compilation/dep_d1_ops.d(225): perhaps implement `auto opOpAssign(string op : \"+\")(int) {}`\n fail_compilation/dep_d1_ops.d(367): Error: operator `-=` not supported for `c` of type `C`\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/depmsg.d b/gcc/testsuite/gdc.test/fail_compilation/depmsg.d\nindex b0c2b2e6a8e..01437d1f735 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/depmsg.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/depmsg.d\n@@ -2,19 +2,32 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/depmsg.d(40): Deprecation: struct `depmsg.main.Inner.A` is deprecated - With message!\n-fail_compilation/depmsg.d(40): Deprecation: struct `depmsg.main.Inner.A` is deprecated - With message!\n-fail_compilation/depmsg.d(41): Deprecation: class `depmsg.main.Inner.B` is deprecated - With message!\n-fail_compilation/depmsg.d(41): Deprecation: class `depmsg.main.Inner.B` is deprecated - With message!\n-fail_compilation/depmsg.d(42): Deprecation: interface `depmsg.main.Inner.C` is deprecated - With message!\n-fail_compilation/depmsg.d(42): Deprecation: interface `depmsg.main.Inner.C` is deprecated - With message!\n-fail_compilation/depmsg.d(43): Deprecation: union `depmsg.main.Inner.D` is deprecated - With message!\n-fail_compilation/depmsg.d(43): Deprecation: union `depmsg.main.Inner.D` is deprecated - With message!\n-fail_compilation/depmsg.d(44): Deprecation: enum `depmsg.main.Inner.E` is deprecated - With message!\n-fail_compilation/depmsg.d(44): Deprecation: enum `depmsg.main.Inner.E` is deprecated - With message!\n-fail_compilation/depmsg.d(46): Deprecation: alias `depmsg.main.Inner.G` is deprecated - With message!\n-fail_compilation/depmsg.d(47): Deprecation: variable `depmsg.main.Inner.H` is deprecated - With message!\n-fail_compilation/depmsg.d(48): Deprecation: class `depmsg.main.Inner.I()` is deprecated - With message!\n+fail_compilation/depmsg.d(53): Deprecation: struct `depmsg.main.Inner.A` is deprecated - With message!\n+fail_compilation/depmsg.d(40): `A` is declared here\n+fail_compilation/depmsg.d(53): Deprecation: struct `depmsg.main.Inner.A` is deprecated - With message!\n+fail_compilation/depmsg.d(40): `A` is declared here\n+fail_compilation/depmsg.d(54): Deprecation: class `depmsg.main.Inner.B` is deprecated - With message!\n+fail_compilation/depmsg.d(41): `B` is declared here\n+fail_compilation/depmsg.d(54): Deprecation: class `depmsg.main.Inner.B` is deprecated - With message!\n+fail_compilation/depmsg.d(41): `B` is declared here\n+fail_compilation/depmsg.d(55): Deprecation: interface `depmsg.main.Inner.C` is deprecated - With message!\n+fail_compilation/depmsg.d(42): `C` is declared here\n+fail_compilation/depmsg.d(55): Deprecation: interface `depmsg.main.Inner.C` is deprecated - With message!\n+fail_compilation/depmsg.d(42): `C` is declared here\n+fail_compilation/depmsg.d(56): Deprecation: union `depmsg.main.Inner.D` is deprecated - With message!\n+fail_compilation/depmsg.d(43): `D` is declared here\n+fail_compilation/depmsg.d(56): Deprecation: union `depmsg.main.Inner.D` is deprecated - With message!\n+fail_compilation/depmsg.d(43): `D` is declared here\n+fail_compilation/depmsg.d(57): Deprecation: enum `depmsg.main.Inner.E` is deprecated - With message!\n+fail_compilation/depmsg.d(44): `E` is declared here\n+fail_compilation/depmsg.d(57): Deprecation: enum `depmsg.main.Inner.E` is deprecated - With message!\n+fail_compilation/depmsg.d(44): `E` is declared here\n+fail_compilation/depmsg.d(59): Deprecation: alias `depmsg.main.Inner.G` is deprecated - With message!\n+fail_compilation/depmsg.d(46): `G` is declared here\n+fail_compilation/depmsg.d(60): Deprecation: variable `depmsg.main.Inner.H` is deprecated - With message!\n+fail_compilation/depmsg.d(47): `H` is declared here\n+fail_compilation/depmsg.d(61): Deprecation: class `depmsg.main.Inner.I()` is deprecated - With message!\n+fail_compilation/depmsg.d(48): `I()` is declared here\n ---\n */\n \n@@ -52,13 +65,20 @@ void main()\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/depmsg.d(94): Deprecation: function `depmsg.test12954.Foo.bar1` is deprecated - [C] Use Foo.bar42 instead\n-fail_compilation/depmsg.d(95): Deprecation: function `depmsg.test12954.Foo.bar2` is deprecated - [E] Use Foo.bar42 instead\n-fail_compilation/depmsg.d(96): Deprecation: function `depmsg.test12954.Foo.bar3` is deprecated - [S] Use Foo.bar42 instead\n-fail_compilation/depmsg.d(97): Deprecation: function `depmsg.test12954.Foo.bar4` is deprecated - [F] Use Foo.bar42 instead\n-fail_compilation/depmsg.d(98): Deprecation: variable `depmsg.test12954.Foo.v2` is deprecated - Forward reference\n-fail_compilation/depmsg.d(105): Deprecation: class `depmsg.test12954.Obsolete` is deprecated\n-fail_compilation/depmsg.d(105): Deprecation: function `depmsg.test12954.Obsolete.obs` is deprecated - Function is obsolete\n+fail_compilation/depmsg.d(114): Deprecation: function `depmsg.test12954.Foo.bar1` is deprecated - [C] Use Foo.bar42 instead\n+fail_compilation/depmsg.d(98): `bar1` is declared here\n+fail_compilation/depmsg.d(115): Deprecation: function `depmsg.test12954.Foo.bar2` is deprecated - [E] Use Foo.bar42 instead\n+fail_compilation/depmsg.d(101): `bar2` is declared here\n+fail_compilation/depmsg.d(116): Deprecation: function `depmsg.test12954.Foo.bar3` is deprecated - [S] Use Foo.bar42 instead\n+fail_compilation/depmsg.d(104): `bar3` is declared here\n+fail_compilation/depmsg.d(117): Deprecation: function `depmsg.test12954.Foo.bar4` is deprecated - [F] Use Foo.bar42 instead\n+fail_compilation/depmsg.d(107): `bar4` is declared here\n+fail_compilation/depmsg.d(118): Deprecation: variable `depmsg.test12954.Foo.v2` is deprecated - Forward reference\n+fail_compilation/depmsg.d(109): `v2` is declared here\n+fail_compilation/depmsg.d(125): Deprecation: class `depmsg.test12954.Obsolete` is deprecated\n+fail_compilation/depmsg.d(120): `Obsolete` is declared here\n+fail_compilation/depmsg.d(125): Deprecation: function `depmsg.test12954.Obsolete.obs` is deprecated - Function is obsolete\n+fail_compilation/depmsg.d(122): `obs` is declared here\n ---\n */\n void test12954()\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/depmsg15814.d b/gcc/testsuite/gdc.test/fail_compilation/depmsg15814.d\nindex 613576c256f..19f49a24714 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/depmsg15814.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/depmsg15814.d\n@@ -2,7 +2,8 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/depmsg15814.d(9): Deprecation: function `depmsg15814.get15814` is deprecated - bug15814\n+fail_compilation/depmsg15814.d(10): Deprecation: function `depmsg15814.get15814` is deprecated - bug15814\n+fail_compilation/depmsg15814.d(9): `get15814` is declared here\n ---\n */\n deprecated(\"bug15814\") int get15814() { return 0; }\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/depmsg15815.d b/gcc/testsuite/gdc.test/fail_compilation/depmsg15815.d\nindex 0b19687ad52..f98d4f255bb 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/depmsg15815.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/depmsg15815.d\n@@ -2,7 +2,8 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/depmsg15815.d(23): Deprecation: template `depmsg15815.Alias(T)` is deprecated - message\n+fail_compilation/depmsg15815.d(24): Deprecation: template `depmsg15815.Alias(T)` is deprecated - message\n+fail_compilation/depmsg15815.d(18): `Alias(T)` is declared here\n Foo\n ---\n */\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/deprecatedImports.d b/gcc/testsuite/gdc.test/fail_compilation/deprecatedImports.d\nindex bd68a9d4e3c..b50e2981f10 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/deprecatedImports.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/deprecatedImports.d\n@@ -4,13 +4,20 @@ EXTRA_FILES: imports/deprecatedImporta.d imports/deprecatedImportb.d\n \n TEST_OUTPUT:\n ----\n-fail_compilation/deprecatedImports.d(19): Deprecation: alias `deprecatedImporta.foo` is deprecated - Please import deprecatedImportb directly!\n-fail_compilation/deprecatedImports.d(21): Deprecation: alias `deprecatedImporta.bar` is deprecated - Please import deprecatedImportb directly!\n-fail_compilation/deprecatedImports.d(23): Deprecation: alias `deprecatedImporta.AliasSeq` is deprecated - Please import deprecatedImportb directly!\n-fail_compilation/deprecatedImports.d(27): Deprecation: alias `deprecatedImporta.S` is deprecated - Please import deprecatedImportb directly!\n-fail_compilation/deprecatedImports.d(29): Deprecation: alias `deprecatedImporta.C` is deprecated - Please import deprecatedImportb directly!\n-fail_compilation/deprecatedImports.d(31): Deprecation: alias `deprecatedImporta.I` is deprecated - Please import deprecatedImportb directly!\n-fail_compilation/deprecatedImports.d(25): Deprecation: alias `deprecatedImporta.E` is deprecated - Please import deprecatedImportb directly!\n+fail_compilation/deprecatedImports.d(26): Deprecation: alias `deprecatedImporta.foo` is deprecated - Please import deprecatedImportb directly!\n+fail_compilation/imports/deprecatedImporta.d(2): `foo` is declared here\n+fail_compilation/deprecatedImports.d(28): Deprecation: alias `deprecatedImporta.bar` is deprecated - Please import deprecatedImportb directly!\n+fail_compilation/imports/deprecatedImporta.d(2): `bar` is declared here\n+fail_compilation/deprecatedImports.d(30): Deprecation: alias `deprecatedImporta.AliasSeq` is deprecated - Please import deprecatedImportb directly!\n+fail_compilation/imports/deprecatedImporta.d(2): `AliasSeq` is declared here\n+fail_compilation/deprecatedImports.d(34): Deprecation: alias `deprecatedImporta.S` is deprecated - Please import deprecatedImportb directly!\n+fail_compilation/imports/deprecatedImporta.d(2): `S` is declared here\n+fail_compilation/deprecatedImports.d(36): Deprecation: alias `deprecatedImporta.C` is deprecated - Please import deprecatedImportb directly!\n+fail_compilation/imports/deprecatedImporta.d(2): `C` is declared here\n+fail_compilation/deprecatedImports.d(38): Deprecation: alias `deprecatedImporta.I` is deprecated - Please import deprecatedImportb directly!\n+fail_compilation/imports/deprecatedImporta.d(2): `I` is declared here\n+fail_compilation/deprecatedImports.d(32): Deprecation: alias `deprecatedImporta.E` is deprecated - Please import deprecatedImportb directly!\n+fail_compilation/imports/deprecatedImporta.d(2): `E` is declared here\n ----\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/deprecatedTemplates.d b/gcc/testsuite/gdc.test/fail_compilation/deprecatedTemplates.d\nindex d9054798661..e735c9004f7 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/deprecatedTemplates.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/deprecatedTemplates.d\n@@ -4,8 +4,11 @@ REQUIRED_ARGS: -de\n TEST_OUTPUT:\n ----\n fail_compilation/deprecatedTemplates.d(103): Deprecation: template `deprecatedTemplates.AliasSeq(V...)` is deprecated\n+fail_compilation/deprecatedTemplates.d(101): `AliasSeq(V...)` is declared here\n fail_compilation/deprecatedTemplates.d(107): Deprecation: struct `deprecatedTemplates.S1(V...)` is deprecated\n+fail_compilation/deprecatedTemplates.d(105): `S1(V...)` is declared here\n fail_compilation/deprecatedTemplates.d(115): Deprecation: template `deprecatedTemplates.C(V...)` is deprecated\n+fail_compilation/deprecatedTemplates.d(109): `C(V...)` is declared here\n ----\n */\n #line 100\n@@ -30,6 +33,7 @@ alias D = C!();\n TEST_OUTPUT:\n ----\n fail_compilation/deprecatedTemplates.d(202): Deprecation: template `deprecatedTemplates.AliasSeqMsg(V...)` is deprecated - Reason\n+fail_compilation/deprecatedTemplates.d(200): `AliasSeqMsg(V...)` is declared here\n ----\n */\n #line 200\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/deprecations.d b/gcc/testsuite/gdc.test/fail_compilation/deprecations.d\nindex 19adab7e3ac..85ca0b83a40 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/deprecations.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/deprecations.d\n@@ -2,12 +2,15 @@\n REQUIRED_ARGS: -de\n TEST_OUTPUT:\n ---\n-fail_compilation/deprecations.d(43): Deprecation: struct `deprecations.S` is deprecated\n-fail_compilation/deprecations.d(64): instantiated from here: `otherPar!()`\n-fail_compilation/deprecations.d(55): Deprecation: struct `deprecations.S` is deprecated\n-fail_compilation/deprecations.d(65): instantiated from here: `otherVar!()`\n-fail_compilation/deprecations.d(55): Deprecation: struct `deprecations.S` is deprecated\n-fail_compilation/deprecations.d(65): instantiated from here: `otherVar!()`\n+fail_compilation/deprecations.d(46): Deprecation: struct `deprecations.S` is deprecated\n+fail_compilation/deprecations.d(19): `S` is declared here\n+fail_compilation/deprecations.d(67): instantiated from here: `otherPar!()`\n+fail_compilation/deprecations.d(58): Deprecation: struct `deprecations.S` is deprecated\n+fail_compilation/deprecations.d(19): `S` is declared here\n+fail_compilation/deprecations.d(68): instantiated from here: `otherVar!()`\n+fail_compilation/deprecations.d(58): Deprecation: struct `deprecations.S` is deprecated\n+fail_compilation/deprecations.d(19): `S` is declared here\n+fail_compilation/deprecations.d(68): instantiated from here: `otherVar!()`\n ---\n \n https://issues.dlang.org/show_bug.cgi?id=20474\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/diag14235.d b/gcc/testsuite/gdc.test/fail_compilation/diag14235.d\nindex 8c563ba44c9..51ffa47a186 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/diag14235.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/diag14235.d\n@@ -2,9 +2,10 @@\n EXTRA_FILES: imports/a14235.d\n TEST_OUTPUT:\n ---\n-fail_compilation/diag14235.d(12): Error: undefined identifier `Undefined` in module `imports.a14235`\n-fail_compilation/diag14235.d(13): Error: undefined identifier `Something` in module `imports.a14235`, did you mean struct `SomeThing(T...)`?\n-fail_compilation/diag14235.d(14): Error: `SomeClass` isn't a template\n+fail_compilation/diag14235.d(13): Error: undefined identifier `Undefined` in module `imports.a14235`\n+fail_compilation/diag14235.d(14): Error: undefined identifier `Something` in module `imports.a14235`, did you mean struct `SomeThing(T...)`?\n+fail_compilation/imports/a14235.d(3): `imports.a14235.SomeThing(T...)` located here\n+fail_compilation/diag14235.d(15): Error: `SomeClass` isn't a template\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/diag14875.d b/gcc/testsuite/gdc.test/fail_compilation/diag14875.d\nindex a4d4abe9e19..b6ef8c77e4e 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/diag14875.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/diag14875.d\n@@ -6,7 +6,8 @@ deprecated immutable int depVar = 10;\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/diag14875.d(16): Deprecation: class `diag14875.Dep` is deprecated\n+fail_compilation/diag14875.d(17): Deprecation: class `diag14875.Dep` is deprecated\n+fail_compilation/diag14875.d(3): `Dep` is declared here\n 1: Dep\n 2: Dep\n 3: Dep\n@@ -36,16 +37,20 @@ template Baz(T)\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/diag14875.d(52): Deprecation: class `diag14875.Dep` is deprecated\n-fail_compilation/diag14875.d(56): Deprecation: variable `diag14875.depVar` is deprecated\n-fail_compilation/diag14875.d(52): instantiated from here: `Voo!(Dep)`\n+fail_compilation/diag14875.d(57): Deprecation: class `diag14875.Dep` is deprecated\n+fail_compilation/diag14875.d(3): `Dep` is declared here\n+fail_compilation/diag14875.d(61): Deprecation: variable `diag14875.depVar` is deprecated\n+fail_compilation/diag14875.d(4): `depVar` is declared here\n+fail_compilation/diag14875.d(57): instantiated from here: `Voo!(Dep)`\n 4: Dep\n-fail_compilation/diag14875.d(63): Deprecation: variable `diag14875.depVar` is deprecated\n-fail_compilation/diag14875.d(59): instantiated from here: `Var!(Dep)`\n-fail_compilation/diag14875.d(52): instantiated from here: `Voo!(Dep)`\n-fail_compilation/diag14875.d(64): Deprecation: template `diag14875.Vaz(T)` is deprecated\n-fail_compilation/diag14875.d(59): instantiated from here: `Var!(Dep)`\n-fail_compilation/diag14875.d(52): instantiated from here: `Voo!(Dep)`\n+fail_compilation/diag14875.d(68): Deprecation: variable `diag14875.depVar` is deprecated\n+fail_compilation/diag14875.d(4): `depVar` is declared here\n+fail_compilation/diag14875.d(64): instantiated from here: `Var!(Dep)`\n+fail_compilation/diag14875.d(57): instantiated from here: `Voo!(Dep)`\n+fail_compilation/diag14875.d(69): Deprecation: template `diag14875.Vaz(T)` is deprecated\n+fail_compilation/diag14875.d(71): `Vaz(T)` is declared here\n+fail_compilation/diag14875.d(64): instantiated from here: `Var!(Dep)`\n+fail_compilation/diag14875.d(57): instantiated from here: `Voo!(Dep)`\n ---\n */\n \n@@ -72,7 +77,7 @@ deprecated template Vaz(T)\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/diag14875.d(80): Error: static assert: `0` is false\n+fail_compilation/diag14875.d(85): Error: static assert: `0` is false\n ---\n */\n void main()\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/diag14876.d b/gcc/testsuite/gdc.test/fail_compilation/diag14876.d\nindex 4beea959001..9579467eaf7 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/diag14876.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/diag14876.d\n@@ -1,14 +1,21 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/diag14876.d(17): Deprecation: class `diag14876.Dep` is deprecated\n-fail_compilation/diag14876.d(18): Deprecation: class `diag14876.Dep` is deprecated\n-fail_compilation/diag14876.d(19): Deprecation: class `diag14876.Dep` is deprecated\n-fail_compilation/diag14876.d(20): Deprecation: class `diag14876.Dep` is deprecated\n-fail_compilation/diag14876.d(21): Deprecation: class `diag14876.Dep` is deprecated\n-fail_compilation/diag14876.d(22): Deprecation: class `diag14876.Dep` is deprecated\n-fail_compilation/diag14876.d(23): Deprecation: class `diag14876.Dep` is deprecated\n-fail_compilation/diag14876.d(23): Error: can only slice type sequences, not `diag14876.Dep`\n+fail_compilation/diag14876.d(24): Deprecation: class `diag14876.Dep` is deprecated\n+fail_compilation/diag14876.d(22): `Dep` is declared here\n+fail_compilation/diag14876.d(25): Deprecation: class `diag14876.Dep` is deprecated\n+fail_compilation/diag14876.d(22): `Dep` is declared here\n+fail_compilation/diag14876.d(26): Deprecation: class `diag14876.Dep` is deprecated\n+fail_compilation/diag14876.d(22): `Dep` is declared here\n+fail_compilation/diag14876.d(27): Deprecation: class `diag14876.Dep` is deprecated\n+fail_compilation/diag14876.d(22): `Dep` is declared here\n+fail_compilation/diag14876.d(28): Deprecation: class `diag14876.Dep` is deprecated\n+fail_compilation/diag14876.d(22): `Dep` is declared here\n+fail_compilation/diag14876.d(29): Deprecation: class `diag14876.Dep` is deprecated\n+fail_compilation/diag14876.d(22): `Dep` is declared here\n+fail_compilation/diag14876.d(30): Deprecation: class `diag14876.Dep` is deprecated\n+fail_compilation/diag14876.d(22): `Dep` is declared here\n+fail_compilation/diag14876.d(30): Error: can only slice type sequences, not `diag14876.Dep`\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/diag16499.d b/gcc/testsuite/gdc.test/fail_compilation/diag16499.d\nindex f3757954d4a..34de73523b0 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/diag16499.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/diag16499.d\n@@ -2,9 +2,9 @@\n TEST_OUTPUT:\n ---\n fail_compilation/diag16499.d(24): Error: operator `in` is not defined for type `A`\n-fail_compilation/diag16499.d(11): perhaps overload the operator with `auto opBinaryRight(string op : \"in\")(int rhs) {}`\n+fail_compilation/diag16499.d(11): perhaps overload the operator with `auto opBinaryRight(string op : \"in\")(int lhs) {}`\n fail_compilation/diag16499.d(26): Error: operator `in` is not defined for type `B`\n-fail_compilation/diag16499.d(12): perhaps overload the operator with `auto opBinaryRight(string op : \"in\")(double rhs) {}`\n+fail_compilation/diag16499.d(12): perhaps overload the operator with `auto opBinaryRight(string op : \"in\")(double lhs) {}`\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/diag21167.d b/gcc/testsuite/gdc.test/fail_compilation/diag21167.d\nnew file mode 100644\nindex 00000000000..f400a194e8c\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/diag21167.d\n@@ -0,0 +1,21 @@\n+/*\n+TEST_OUTPUT:\n+---\n+fail_compilation\\diag21167.d(15): Error: function `f` is not callable using argument types `(int, string, int)`\n+fail_compilation\\diag21167.d(17): cannot pass argument `\"foo\"` of type `string` to parameter `int __param_1`\n+fail_compilation\\diag21167.d(11): `diag21167.f(int __param_0, int __param_1, int __param_2)` declared here\n+---\n+*/\n+// https://github.com/dlang/dmd/issues/21167\n+\n+void f(int, int, int){}\n+\n+void main()\n+{\n+\tf(\n+\t\t1,\n+\t\t\"foo\",\n+\t\t3\n+\t);\n+\n+}\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/diag21381.d b/gcc/testsuite/gdc.test/fail_compilation/diag21381.d\nnew file mode 100644\nindex 00000000000..1a36ec584a5\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/diag21381.d\n@@ -0,0 +1,15 @@\n+/*\n+TEST_OUTPUT:\n+---\n+fail_compilation/diag21381.d(15): Error: undefined identifier `xyx`, did you mean struct `xyz`?\n+---\n+*/\n+// https://github.com/dlang/dmd/issues/21381\n+\n+enum plusOne(int x) = x + 1;\n+struct xyz{}\n+\n+alias PlusOne =\n+ plusOne\n+ !\n+ xyx;\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/diag21413.d b/gcc/testsuite/gdc.test/fail_compilation/diag21413.d\nnew file mode 100644\nindex 00000000000..9f7c8e9e0ff\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/diag21413.d\n@@ -0,0 +1,15 @@\n+/*\n+TEST_OUTPUT:\n+---\n+fail_compilation\\diag21413.d(13): Error: undefined identifier `Potato`\n+---\n+*/\n+// https://github.com/dlang/dmd/issues/21413\n+\n+void main()\n+{\n+\tthrow\n+\tnew\n+\tPotato\n+\t();\n+}\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19202.d b/gcc/testsuite/gdc.test/fail_compilation/fail19202.d\nindex f19bc181f41..a5b773fc065 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail19202.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19202.d\n@@ -2,7 +2,8 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/fail19202.d(11): Deprecation: variable `fail19202.X!().X` is deprecated\n+fail_compilation/fail19202.d(12): Deprecation: variable `fail19202.X!().X` is deprecated\n+fail_compilation/fail19202.d(17): `X` is declared here\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail199.d b/gcc/testsuite/gdc.test/fail_compilation/fail199.d\nindex 9cb14b801c9..ab57b3401d0 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail199.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail199.d\n@@ -2,8 +2,10 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/fail199.d(20): Deprecation: class `fail199.DepClass` is deprecated\n-fail_compilation/fail199.d(20): Deprecation: class `fail199.DepClass` is deprecated\n+fail_compilation/fail199.d(22): Deprecation: class `fail199.DepClass` is deprecated\n+fail_compilation/fail199.d(14): `DepClass` is declared here\n+fail_compilation/fail199.d(22): Deprecation: class `fail199.DepClass` is deprecated\n+fail_compilation/fail199.d(14): `DepClass` is declared here\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail200.d b/gcc/testsuite/gdc.test/fail_compilation/fail200.d\nindex 9d804a916b3..07ea04371f9 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail200.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail200.d\n@@ -2,8 +2,10 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/fail200.d(17): Deprecation: interface `fail200.DepClass` is deprecated\n-fail_compilation/fail200.d(17): Deprecation: interface `fail200.DepClass` is deprecated\n+fail_compilation/fail200.d(19): Deprecation: interface `fail200.DepClass` is deprecated\n+fail_compilation/fail200.d(14): `DepClass` is declared here\n+fail_compilation/fail200.d(19): Deprecation: interface `fail200.DepClass` is deprecated\n+fail_compilation/fail200.d(14): `DepClass` is declared here\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail20779.d b/gcc/testsuite/gdc.test/fail_compilation/fail20779.d\nindex 945803d53f1..7b3b07af1ee 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail20779.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail20779.d\n@@ -3,7 +3,7 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/fail20779.d(12): Error: struct `fail20779.X` cannot have field `x` with same struct type\n+fail_compilation/fail20779.d(14): Error: struct `fail20779.X` cannot have field `x` with same struct type\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail21830.d b/gcc/testsuite/gdc.test/fail_compilation/fail21830.d\nindex 2e0f84b7777..dda0140aad4 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail21830.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail21830.d\n@@ -2,8 +2,11 @@\n TEST_OUTPUT:\n ---\n fail_compilation/fail21830.d(24): Deprecation: struct `fail21830.OldS21830` is deprecated - Deprecated type\n+fail_compilation/fail21830.d(2): `OldS21830` is declared here\n fail_compilation/fail21830.d(24): Deprecation: template `fail21830.test21830(T)(T t) if (is(T == OldS21830))` is deprecated - Deprecated template\n+fail_compilation/fail21830.d(16): `test21830(T)(T t) if (is(T == OldS21830))` is declared here\n fail_compilation/fail21830.d(24): Deprecation: struct `fail21830.OldS21830` is deprecated - Deprecated type\n+fail_compilation/fail21830.d(2): `OldS21830` is declared here\n ---\n */\n #line 1\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail21831.d b/gcc/testsuite/gdc.test/fail_compilation/fail21831.d\nindex 39551332e93..642c6d3f49f 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail21831.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail21831.d\n@@ -2,8 +2,11 @@\n TEST_OUTPUT:\n ---\n fail_compilation/fail21831.d(19): Deprecation: struct `fail21831.S21831` is deprecated - Deprecated type\n+fail_compilation/fail21831.d(2): `S21831` is declared here\n fail_compilation/fail21831.d(19): Deprecation: template `fail21831.test21831(T)(T t) if (__traits(isDeprecated, T))` is deprecated - Deprecated template\n+fail_compilation/fail21831.d(11): `test21831(T)(T t) if (__traits(isDeprecated, T))` is declared here\n fail_compilation/fail21831.d(19): Deprecation: struct `fail21831.S21831` is deprecated - Deprecated type\n+fail_compilation/fail21831.d(2): `S21831` is declared here\n ---\n */\n #line 1\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail21832.d b/gcc/testsuite/gdc.test/fail_compilation/fail21832.d\nindex 98f3df71a15..690dbdae8de 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail21832.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail21832.d\n@@ -4,7 +4,9 @@\n TEST_OUTPUT:\n ---\n fail_compilation/fail21832.d(4): Deprecation: function `imports.imp21832.fun` is deprecated\n+fail_compilation/imports/imp21832.d(16): `fun` is declared here\n fail_compilation/fail21832.d(10): Deprecation: template `imports.imp21832.tpl()(char a)` is deprecated\n+fail_compilation/imports/imp21832.d(20): `tpl()(char a)` is declared here\n ---\n */\n #line 1\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22384.d b/gcc/testsuite/gdc.test/fail_compilation/fail22384.d\nnew file mode 100644\nindex 00000000000..71881f41930\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22384.d\n@@ -0,0 +1,51 @@\n+/*\n+TEST_OUTPUT:\n+---\n+fail_compilation/fail22384.d(36): Error: bitfield `z` cannot have zero width\n+fail_compilation/fail22384.d(40): Error: bitfield `f` cannot be of non-integral type `float`\n+fail_compilation/fail22384.d(41): Error: bitfield `f2` cannot be of non-integral type `float`\n+fail_compilation/fail22384.d(42): Error: bitfield `f3` cannot be of non-integral type `float`\n+fail_compilation/fail22384.d(43): Error: bitfield `f4` cannot be of non-integral type `float`\n+fail_compilation/fail22384.d(48): Error: anonymous bitfield cannot have default initializer\n+fail_compilation/fail22384.d(25): Error: default initializer `4294967295u` is not representable as bitfield type `uint:4`\n+fail_compilation/fail22384.d(25): bitfield `d` default initializer must be a value between `0..15`\n+fail_compilation/fail22384.d(30): Error: default initializer `E.B` is not representable as bitfield type `int:2`\n+fail_compilation/fail22384.d(30): bitfield `b` default initializer must be a value between `-2..1`\n+fail_compilation/fail22384.d(34): Error: default initializer `4` is not representable as bitfield type `int:3`\n+fail_compilation/fail22384.d(34): bitfield `x` default initializer must be a value between `-4..3`\n+fail_compilation/fail22384.d(35): Error: default initializer `65` is not representable as bitfield type `int:7`\n+fail_compilation/fail22384.d(35): bitfield `y` default initializer must be a value between `-64..63`\n+fail_compilation/fail22384.d(47): Error: cannot implicitly convert expression `4.2F` of type `float` to `int`\n+fail_compilation/fail22384.d(49): Error: default initializer `65` is not representable as bitfield type `int:7`\n+fail_compilation/fail22384.d(49): bitfield `j` default initializer must be a value between `-64..63`\n+fail_compilation/fail22384.d(50): Error: cannot implicitly convert expression `42` of type `int` to `bool`\n+---\n+*/\n+struct S {\n+ uint d : 4 = -1;\n+}\n+\n+enum E : int { A = 1, B = 2 }\n+struct EFail {\n+ E b : 2 = E.B;\n+}\n+\n+struct IFail {\n+ int x : 3 = 4;\n+ int y : 7 = 65;\n+ int z : 0 = 1;\n+}\n+\n+struct FloatFail {\n+ float f : 0;\n+ float f2 : 7;\n+ float f3 : 7 = 4;\n+ float f4 : 7 = 4.2f;\n+}\n+\n+struct InitFail {\n+ int i : 7 = 4.2f;\n+ ubyte : 8 = 4.2f;\n+ int j : 7 = 'A';\n+ bool b : 7 = 42;\n+}\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23822.d b/gcc/testsuite/gdc.test/fail_compilation/fail23822.d\nindex 5cdd1fe0503..57e6bc035aa 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail23822.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23822.d\n@@ -5,7 +5,8 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/fail23822.d(21): Deprecation: alias `fail23822.S.value` is deprecated\n+fail_compilation/fail23822.d(22): Deprecation: alias `fail23822.S.value` is deprecated\n+fail_compilation/fail23822.d(17): `value` is declared here\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23826.d b/gcc/testsuite/gdc.test/fail_compilation/fail23826.d\nindex 3db243a3ce8..d66f941fdcb 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail23826.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23826.d\n@@ -5,7 +5,8 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/fail23826.d(23): Deprecation: alias `fail23826.S.value` is deprecated\n+fail_compilation/fail23826.d(24): Deprecation: alias `fail23826.S.value` is deprecated\n+fail_compilation/fail23826.d(17): `value` is declared here\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail243.d b/gcc/testsuite/gdc.test/fail_compilation/fail243.d\nindex d9852ffc471..46cfa52ee42 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail243.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail243.d\n@@ -2,11 +2,16 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/fail243.d(23): Deprecation: class `fail243.DepClass` is deprecated\n-fail_compilation/fail243.d(24): Deprecation: struct `fail243.DepStruct` is deprecated\n-fail_compilation/fail243.d(25): Deprecation: union `fail243.DepUnion` is deprecated\n-fail_compilation/fail243.d(26): Deprecation: enum `fail243.DepEnum` is deprecated\n-fail_compilation/fail243.d(27): Deprecation: alias `fail243.DepAlias` is deprecated\n+fail_compilation/fail243.d(28): Deprecation: class `fail243.DepClass` is deprecated\n+fail_compilation/fail243.d(20): `DepClass` is declared here\n+fail_compilation/fail243.d(29): Deprecation: struct `fail243.DepStruct` is deprecated\n+fail_compilation/fail243.d(21): `DepStruct` is declared here\n+fail_compilation/fail243.d(30): Deprecation: union `fail243.DepUnion` is deprecated\n+fail_compilation/fail243.d(22): `DepUnion` is declared here\n+fail_compilation/fail243.d(31): Deprecation: enum `fail243.DepEnum` is deprecated\n+fail_compilation/fail243.d(23): `DepEnum` is declared here\n+fail_compilation/fail243.d(32): Deprecation: alias `fail243.DepAlias` is deprecated\n+fail_compilation/fail243.d(24): `DepAlias` is declared here\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail244.d b/gcc/testsuite/gdc.test/fail_compilation/fail244.d\nindex 757eb2bdbb1..a9bb36549f5 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail244.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail244.d\n@@ -2,16 +2,26 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/fail244.d(27): Deprecation: variable `fail244.StructWithDeps.value` is deprecated\n-fail_compilation/fail244.d(28): Deprecation: variable `fail244.StructWithDeps.value` is deprecated\n-fail_compilation/fail244.d(29): Deprecation: variable `fail244.StructWithDeps.value` is deprecated\n-fail_compilation/fail244.d(30): Deprecation: variable `fail244.StructWithDeps.value` is deprecated\n-fail_compilation/fail244.d(32): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\n-fail_compilation/fail244.d(33): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\n-fail_compilation/fail244.d(34): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\n-fail_compilation/fail244.d(35): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\n-fail_compilation/fail244.d(36): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\n-fail_compilation/fail244.d(37): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\n+fail_compilation/fail244.d(37): Deprecation: variable `fail244.StructWithDeps.value` is deprecated\n+fail_compilation/fail244.d(32): `value` is declared here\n+fail_compilation/fail244.d(38): Deprecation: variable `fail244.StructWithDeps.value` is deprecated\n+fail_compilation/fail244.d(32): `value` is declared here\n+fail_compilation/fail244.d(39): Deprecation: variable `fail244.StructWithDeps.value` is deprecated\n+fail_compilation/fail244.d(32): `value` is declared here\n+fail_compilation/fail244.d(40): Deprecation: variable `fail244.StructWithDeps.value` is deprecated\n+fail_compilation/fail244.d(32): `value` is declared here\n+fail_compilation/fail244.d(42): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\n+fail_compilation/fail244.d(33): `staticValue` is declared here\n+fail_compilation/fail244.d(43): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\n+fail_compilation/fail244.d(33): `staticValue` is declared here\n+fail_compilation/fail244.d(44): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\n+fail_compilation/fail244.d(33): `staticValue` is declared here\n+fail_compilation/fail244.d(45): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\n+fail_compilation/fail244.d(33): `staticValue` is declared here\n+fail_compilation/fail244.d(46): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\n+fail_compilation/fail244.d(33): `staticValue` is declared here\n+fail_compilation/fail244.d(47): Deprecation: variable `fail244.StructWithDeps.staticValue` is deprecated\n+fail_compilation/fail244.d(33): `staticValue` is declared here\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail245.d b/gcc/testsuite/gdc.test/fail_compilation/fail245.d\nindex 927f9413205..90b6f7c47fb 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail245.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail245.d\n@@ -2,16 +2,26 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/fail245.d(27): Deprecation: variable `fail245.ClassWithDeps.value` is deprecated\n-fail_compilation/fail245.d(28): Deprecation: variable `fail245.ClassWithDeps.value` is deprecated\n-fail_compilation/fail245.d(29): Deprecation: variable `fail245.ClassWithDeps.value` is deprecated\n-fail_compilation/fail245.d(30): Deprecation: variable `fail245.ClassWithDeps.value` is deprecated\n-fail_compilation/fail245.d(32): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\n-fail_compilation/fail245.d(33): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\n-fail_compilation/fail245.d(34): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\n-fail_compilation/fail245.d(35): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\n-fail_compilation/fail245.d(36): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\n-fail_compilation/fail245.d(37): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\n+fail_compilation/fail245.d(37): Deprecation: variable `fail245.ClassWithDeps.value` is deprecated\n+fail_compilation/fail245.d(32): `value` is declared here\n+fail_compilation/fail245.d(38): Deprecation: variable `fail245.ClassWithDeps.value` is deprecated\n+fail_compilation/fail245.d(32): `value` is declared here\n+fail_compilation/fail245.d(39): Deprecation: variable `fail245.ClassWithDeps.value` is deprecated\n+fail_compilation/fail245.d(32): `value` is declared here\n+fail_compilation/fail245.d(40): Deprecation: variable `fail245.ClassWithDeps.value` is deprecated\n+fail_compilation/fail245.d(32): `value` is declared here\n+fail_compilation/fail245.d(42): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\n+fail_compilation/fail245.d(33): `staticValue` is declared here\n+fail_compilation/fail245.d(43): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\n+fail_compilation/fail245.d(33): `staticValue` is declared here\n+fail_compilation/fail245.d(44): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\n+fail_compilation/fail245.d(33): `staticValue` is declared here\n+fail_compilation/fail245.d(45): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\n+fail_compilation/fail245.d(33): `staticValue` is declared here\n+fail_compilation/fail245.d(46): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\n+fail_compilation/fail245.d(33): `staticValue` is declared here\n+fail_compilation/fail245.d(47): Deprecation: variable `fail245.ClassWithDeps.staticValue` is deprecated\n+fail_compilation/fail245.d(33): `staticValue` is declared here\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4206.d b/gcc/testsuite/gdc.test/fail_compilation/fail4206.d\nindex b9c1671d781..4db260bc89c 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail4206.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail4206.d\n@@ -1,7 +1,8 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/fail4206.d(9): Error: initializer must be an expression, not `s`\n+fail_compilation/fail4206.d(10): Error: initializer must be an expression, not `s`\n+fail_compilation/fail4206.d(10): perhaps use `s()` to construct a value of the type\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail8262.d b/gcc/testsuite/gdc.test/fail_compilation/fail8262.d\nindex 2df1bca4fe3..aeb5ad226d0 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail8262.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail8262.d\n@@ -1,8 +1,9 @@\n /* TEST_OUTPUT:\n ---\n-fail_compilation/fail8262.d(32): Error: initializer must be an expression, not `Tuple8262!1`\n-fail_compilation/fail8262.d(27): Error: template instance `fail8262.T8262!(Tuple8262!1)` error instantiating\n-fail_compilation/fail8262.d(19): Error: cannot implicitly convert expression `S(0)` of type `S` to `int`\n+fail_compilation/fail8262.d(33): Error: initializer must be an expression, not `Tuple8262!1`\n+fail_compilation/fail8262.d(33): perhaps use `Tuple8262!1()` to construct a value of the type\n+fail_compilation/fail8262.d(28): Error: template instance `fail8262.T8262!(Tuple8262!1)` error instantiating\n+fail_compilation/fail8262.d(20): Error: cannot implicitly convert expression `S(0)` of type `S` to `int`\n ---\n * https://issues.dlang.org/show_bug.cgi?id=8262\n */\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail8691.d b/gcc/testsuite/gdc.test/fail_compilation/fail8691.d\nindex 8e46023d3bd..043039911ff 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail8691.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail8691.d\n@@ -1,7 +1,7 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/fail8691.d(7): Error: struct `fail8691.Foo` cannot have field `f` with static array of same struct type\n+fail_compilation/fail8691.d(9): Error: struct `fail8691.Foo` cannot have field `f` with static array of same struct type\n ---\n */\n struct Foo\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_opover.d b/gcc/testsuite/gdc.test/fail_compilation/fail_opover.d\nindex 1a0c9e1ac15..a58b2bdd902 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail_opover.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail_opover.d\n@@ -4,7 +4,7 @@\n TEST_OUTPUT:\n ---\n fail_compilation/fail_opover.d(39): Error: no `[]` operator overload for type `object.Object`\n-$p:object.d$(110): perhaps define `auto opIndex() {}` for `object.Object`\n+$p:object.d$(111): perhaps define `auto opIndex() {}` for `object.Object`\n fail_compilation/fail_opover.d(43): Error: no `[]` operator overload for type `TestS`\n fail_compilation/fail_opover.d(41): perhaps define `auto opIndex() {}` for `fail_opover.test1.TestS`\n fail_compilation/fail_opover.d(55): Error: no `[]` operator overload for type `S`\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11822.d b/gcc/testsuite/gdc.test/fail_compilation/ice11822.d\nindex a673a6b2dda..632571feb30 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/ice11822.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/ice11822.d\n@@ -4,10 +4,11 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/ice11822.d(33): Deprecation: function `ice11822.d` is deprecated\n-fail_compilation/ice11822.d(16): instantiated from here: `__lambda_L33_C15!int`\n-fail_compilation/ice11822.d(22): instantiated from here: `S!(__lambda_L33_C15)`\n-fail_compilation/ice11822.d(33): instantiated from here: `g!((n) => d(i))`\n+fail_compilation/ice11822.d(34): Deprecation: function `ice11822.d` is deprecated\n+fail_compilation/ice11822.d(26): `d` is declared here\n+fail_compilation/ice11822.d(17): instantiated from here: `__lambda_L34_C15!int`\n+fail_compilation/ice11822.d(23): instantiated from here: `S!(__lambda_L34_C15)`\n+fail_compilation/ice11822.d(34): instantiated from here: `g!((n) => d(i))`\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11850.d b/gcc/testsuite/gdc.test/fail_compilation/ice11850.d\nindex 510fe0aae82..6e88ff95f53 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/ice11850.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/ice11850.d\n@@ -1,8 +1,8 @@\n /*\n-EXTRA_FILES: imports/a11850.d\n TEST_OUTPUT:\n ---\n fail_compilation/ice11850.d(15): Error: incompatible types for `(a) < ([0])`: `uint[]` and `int[]`\n+fail_compilation/imports/a11850.d(23): instantiated from here: `__lambda_L15_C13!(uint[])`\n fail_compilation/imports/a11850.d(9): instantiated from here: `FilterResult!(__lambda_L15_C13, uint[][])`\n fail_compilation/ice11850.d(15): instantiated from here: `filter!(uint[][])`\n ---\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11919.d b/gcc/testsuite/gdc.test/fail_compilation/ice11919.d\nindex e6b4f708846..43190203914 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/ice11919.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/ice11919.d\n@@ -2,10 +2,11 @@\n EXTRA_FILES: imports/a11919.d\n TEST_OUTPUT:\n ---\n-fail_compilation/ice11919.d(18): Error: initializer must be an expression, not `foo`\n+fail_compilation/ice11919.d(19): Error: initializer must be an expression, not `foo`\n+fail_compilation/imports/a11919.d(16): used in initialization here\n fail_compilation/imports/a11919.d(4): Error: template instance `a11919.doBar!(Foo).doBar.zoo!(t)` error instantiating\n fail_compilation/imports/a11919.d(11): instantiated from here: `doBar!(Foo)`\n-fail_compilation/ice11919.d(26): instantiated from here: `doBar!(Bar)`\n+fail_compilation/ice11919.d(27): instantiated from here: `doBar!(Bar)`\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/issue22394.d b/gcc/testsuite/gdc.test/fail_compilation/issue22394.d\nnew file mode 100644\nindex 00000000000..cc37adf72ee\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/issue22394.d\n@@ -0,0 +1,16 @@\n+/*\n+TEST_OUTPUT:\n+---\n+fail_compilation/issue22394.d(11): Error: incompatible types for `(a) + (1)`: `string` and `int`\n+fail_compilation/issue22394.d(15): instantiated from here: `__lambda_L11_C1!string`\n+---\n+*/\n+\n+// https://issues.dlang.org/show_bug.cgi?id=22394\n+\n+alias l = a => a + 1;\n+\n+void f()\n+{\n+ l(\"\");\n+}\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/obsolete_body.d b/gcc/testsuite/gdc.test/fail_compilation/obsolete_body.d\nindex 86d8bbc5d32..d4296359281 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/obsolete_body.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/obsolete_body.d\n@@ -2,10 +2,12 @@\n TEST_OUTPUT:\n ---\n fail_compilation/obsolete_body.d(11): Error: usage of identifer `body` as a keyword is obsolete. Use `do` instead.\n+fail_compilation/obsolete_body.d(13): Error: use `alias i32 = ...;` syntax instead of `alias ... i32;`\n ---\n */\n-@__edition_latest_do_not_use\n-module m;\n+module m 2024;\n \n void test()\n in { } body { }\n+\n+alias int i32;\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/struct_rvalue_assign.d b/gcc/testsuite/gdc.test/fail_compilation/struct_rvalue_assign.d\nnew file mode 100644\nindex 00000000000..42451768645\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/struct_rvalue_assign.d\n@@ -0,0 +1,62 @@\n+/*\n+TEST_OUTPUT:\n+---\n+fail_compilation/struct_rvalue_assign.d(16): Error: assignment to struct rvalue `foo()` is discarded\n+fail_compilation/struct_rvalue_assign.d(16): if the assignment is needed to modify a global, call `opAssign` directly or use an lvalue\n+fail_compilation/struct_rvalue_assign.d(17): Error: assignment to struct rvalue `foo()` is discarded\n+fail_compilation/struct_rvalue_assign.d(17): if the assignment is needed to modify a global, call `opOpAssign` directly or use an lvalue\n+fail_compilation/struct_rvalue_assign.d(18): Error: assignment to struct rvalue `foo()` is discarded\n+fail_compilation/struct_rvalue_assign.d(18): if the assignment is needed to modify a global, call `opUnary` directly or use an lvalue\n+---\n+*/\n+module sra 2024;\n+\n+void main()\n+{\n+ foo() = S.init;\n+ foo() += 5;\n+ ++foo();\n+ *foo(); // other unary ops may be OK\n+\n+ // allowed\n+ foo().opAssign(S.init);\n+ foo().opOpAssign!\"+\"(5);\n+ foo().opUnary!\"++\"();\n+}\n+\n+S foo() => S.init;\n+\n+struct S\n+{\n+ int i;\n+\n+ void opAssign(S s);\n+ void opOpAssign(string op : \"+\")(int);\n+ void opUnary(string op : \"++\")();\n+ void opUnary(string op : \"*\")();\n+}\n+\n+void test()\n+{\n+\tint i;\n+\n+\tstatic struct Ptr\n+\t{\n+\t\tint* p;\n+\t\tvoid opAssign(int rhs) { *p = rhs; }\n+\t}\n+\tPtr(&i) = 1; // allowed\n+\n+\tstruct Nested\n+\t{\n+\t\tvoid opAssign(int rhs) { i = rhs; }\n+\t}\n+\tNested() = 1; // allowed\n+\n+\tstatic struct StaticOp\n+\t{\n+\t\tstatic si = 0;\n+\t\tstatic void opAssign(int rhs) { si = rhs; }\n+\t}\n+\tStaticOp() = 1; // allowed\n+}\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/test19193.d b/gcc/testsuite/gdc.test/fail_compilation/test19193.d\nindex e75d90e5a92..9c4d7e4979f 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/test19193.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/test19193.d\n@@ -2,7 +2,8 @@\n REQUIRED_ARGS: -de\n TEST_OUTPUT:\n ---\n-fail_compilation/test19193.d(13): Deprecation: enum member `test19193.T19193!int.A.b` is deprecated\n+fail_compilation/test19193.d(14): Deprecation: enum member `test19193.T19193!int.A.b` is deprecated\n+fail_compilation/test19193.d(21): `b` is declared here\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/test20515.d b/gcc/testsuite/gdc.test/fail_compilation/test20515.d\nindex cf4bbde58d9..b753db3a5de 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/test20515.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/test20515.d\n@@ -2,8 +2,9 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/test20515.d:16: Deprecation: function `test20515.foo` is deprecated\n-fail_compilation/test20515.d:17: Error: undefined identifier `bar`\n+fail_compilation/test20515.d:17: Deprecation: function `test20515.foo` is deprecated\n+fail_compilation/test20515.d:13: `foo` is declared here\n+fail_compilation/test20515.d:18: Error: undefined identifier `bar`\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/test21259.d b/gcc/testsuite/gdc.test/fail_compilation/test21259.d\nindex 31dba3d52ca..c928bab7e7d 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/test21259.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/test21259.d\n@@ -3,10 +3,14 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/test21259.d(39): Deprecation: alias `test21259.Foo.width` is deprecated\n-fail_compilation/test21259.d(40): Deprecation: alias `test21259.Foo2.width` is deprecated\n-fail_compilation/test21259.d(41): Deprecation: variable `test21259.Foo3.bar` is deprecated\n-fail_compilation/test21259.d(42): Deprecation: alias `test21259.Foo4.width` is deprecated\n+fail_compilation/test21259.d(43): Deprecation: alias `test21259.Foo.width` is deprecated\n+fail_compilation/test21259.d(20): `width` is declared here\n+fail_compilation/test21259.d(44): Deprecation: alias `test21259.Foo2.width` is deprecated\n+fail_compilation/test21259.d(26): `width` is declared here\n+fail_compilation/test21259.d(45): Deprecation: variable `test21259.Foo3.bar` is deprecated\n+fail_compilation/test21259.d(31): `bar` is declared here\n+fail_compilation/test21259.d(46): Deprecation: alias `test21259.Foo4.width` is deprecated\n+fail_compilation/test21259.d(38): `width` is declared here\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/test21634.d b/gcc/testsuite/gdc.test/fail_compilation/test21634.d\nindex 2cf2a7b4acb..30bce991914 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/test21634.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/test21634.d\n@@ -7,7 +7,7 @@ fail_compilation/test21634.d(22): Error: function literal `(int x) { }` is not c\n ^\n fail_compilation/test21634.d(22): cannot pass argument `\"%s\"` of type `string` to parameter `int x`\n (int x) {} (\"%s\");\n- ^\n+ ^\n fail_compilation/test21634.d(24): Error: declaration `test21634.main.foo` is already defined\n int foo;\n ^\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/test22397.d b/gcc/testsuite/gdc.test/fail_compilation/test22397.d\nnew file mode 100644\nindex 00000000000..a1a89799bfc\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/test22397.d\n@@ -0,0 +1,16 @@\n+/*\n+TEST_OUTPUT:\n+---\n+fail_compilation/test22397.d(13): Error: this array literal causes a GC allocation in `@nogc` function `main`\n+fail_compilation/test22397.d(14): Error: this array literal causes a GC allocation in `@nogc` function `main`\n+fail_compilation/test22397.d(15): Error: this array literal causes a GC allocation in `@nogc` function `main`\n+---\n+*/\n+\n+// https://issues.dlang.org/show_bug.cgi?id=22397\n+@nogc void main()\n+{\n+ @(\"uda\") int[] a = [1, 2]; // should error\n+ align(8) int[] b = [3, 4]; // should error\n+ extern(C) int[] c = [5, 6]; // should error\n+}\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/test23968.d b/gcc/testsuite/gdc.test/fail_compilation/test23968.d\nindex 4456e75c707..f371618f603 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/test23968.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/test23968.d\n@@ -5,7 +5,8 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/test23968.d(22): Deprecation: alias `test23968.a` is deprecated\n+fail_compilation/test23968.d(23): Deprecation: alias `test23968.a` is deprecated\n+fail_compilation/test23968.d(18): `a` is declared here\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/test9701b.d b/gcc/testsuite/gdc.test/fail_compilation/test9701b.d\nindex 725a4cd0ea6..ce2e54c3ef6 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/test9701b.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/test9701b.d\n@@ -2,8 +2,10 @@\n REQUIRED_ARGS: -de\n TEST_OUTPUT:\n ---\n-fail_compilation/test9701b.d(20): Deprecation: enum member `test9701b.Enum.e0` is deprecated\n-fail_compilation/test9701b.d(21): Deprecation: enum member `test9701b.Enum.e1` is deprecated - message\n+fail_compilation/test9701b.d(22): Deprecation: enum member `test9701b.Enum.e0` is deprecated\n+fail_compilation/test9701b.d(16): `e0` is declared here\n+fail_compilation/test9701b.d(23): Deprecation: enum member `test9701b.Enum.e1` is deprecated - message\n+fail_compilation/test9701b.d(17): `e1` is declared here\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/type_as_initializer.d b/gcc/testsuite/gdc.test/fail_compilation/type_as_initializer.d\nnew file mode 100644\nindex 00000000000..57be109ba0b\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/type_as_initializer.d\n@@ -0,0 +1,52 @@\n+/* TEST_OUTPUT:\n+---\n+fail_compilation/type_as_initializer.d(40): Error: initializer must be an expression, not `S1`\n+fail_compilation/type_as_initializer.d(40): perhaps use `S1()` to construct a value of the type\n+fail_compilation/type_as_initializer.d(43): Error: initializer must be an expression, not `S2`\n+fail_compilation/type_as_initializer.d(46): Error: initializer must be an expression, not `S3`\n+fail_compilation/type_as_initializer.d(46): perhaps use `S3(...)` to construct a value of the type\n+fail_compilation/type_as_initializer.d(49): Error: initializer must be an expression, not `C1`\n+fail_compilation/type_as_initializer.d(49): perhaps use `new C1()` to construct a value of the type\n+fail_compilation/type_as_initializer.d(52): Error: initializer must be an expression, not `C2`\n+fail_compilation/type_as_initializer.d(52): perhaps use `new C2(...)` to construct a value of the type\n+---\n+*/\n+\n+// Struct with no constructors - hint with ()\n+struct S1 {}\n+\n+// Struct with copy constructor - no hint (can't default construct)\n+struct S2\n+{\n+ this(ref S2) {}\n+}\n+\n+// Struct with required-arg constructor only - hint with (...)\n+struct S3\n+{\n+ this(int x) {}\n+}\n+\n+// Class with no constructors - hint with new ()\n+class C1 {}\n+\n+// Class with required-arg constructor only - hint with new (...)\n+class C2\n+{\n+ this(int x) {}\n+}\n+\n+// Test cases\n+enum e1 = S1; // line 44\n+\n+// Copy constructor - no hint\n+enum e2 = S2; // line 47\n+\n+// Required args - hint with (...)\n+enum e3 = S3; // line 50\n+\n+// Class with no ctor - hint with new ()\n+enum e4 = C1; // line 53\n+\n+// Class with required args - hint with new (...)\n+enum e5 = C2; // line 56\ndiff --git a/gcc/testsuite/gdc.test/runnable/imports/pragmainline_a.d b/gcc/testsuite/gdc.test/runnable/imports/pragmainline_a.d\nindex f8d2480bc01..cc87fbba7dc 100644\n--- a/gcc/testsuite/gdc.test/runnable/imports/pragmainline_a.d\n+++ b/gcc/testsuite/gdc.test/runnable/imports/pragmainline_a.d\n@@ -37,3 +37,9 @@ int value()\n {\n return 10;\n }\n+\n+pragma(inline, true)\n+noreturn throws(T)(T param)\n+{\n+ throw new Exception(\"\");\n+}\ndiff --git a/gcc/testsuite/gdc.test/runnable/issue20578.d b/gcc/testsuite/gdc.test/runnable/issue20578.d\nnew file mode 100644\nindex 00000000000..899dc3a8eb9\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/runnable/issue20578.d\n@@ -0,0 +1,14 @@\n+// REQUIRED_ARGS: -inline\n+\n+int fun(string[])\n+{\n+ if (false)\n+ static foreach(m; [1,2,3] ) { }\n+\n+ return 0;\n+}\n+\n+int main(string[] args)\n+{\n+ return fun(args);\n+}\ndiff --git a/gcc/testsuite/gdc.test/runnable/issue22481.d b/gcc/testsuite/gdc.test/runnable/issue22481.d\nnew file mode 100644\nindex 00000000000..bbd0338f0e2\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/runnable/issue22481.d\n@@ -0,0 +1,18 @@\n+// REQUIRED_ARGS: -inline\n+\n+int v;\n+\n+void f()\n+{\n+ for (int i = 1; i < 5; i++)\n+ {\n+ v = i;\n+ return;\n+ }\n+}\n+\n+void main()\n+{\n+ f();\n+ assert(v == 1);\n+}\ndiff --git a/gcc/testsuite/gdc.test/runnable/noreturn2.d b/gcc/testsuite/gdc.test/runnable/noreturn2.d\nindex ef0627202ca..c25ab984c3b 100644\n--- a/gcc/testsuite/gdc.test/runnable/noreturn2.d\n+++ b/gcc/testsuite/gdc.test/runnable/noreturn2.d\n@@ -102,20 +102,30 @@ void testAccess()\n {\n enum msg = \"Accessed expression of type `noreturn`\";\n \n- // FIXME: Another assertion failure in the backend trying to generate noreturn.sizeof = 0 byte assignment\n- version (FIXME)\n- testAssertFailure(__LINE__ + 3, msg, function noreturn()\n+ testAssertFailure(__LINE__ + 3, msg,\n {\n noreturn a;\n noreturn b = a;\n });\n \n- if (false) // read does not assert!\n- testAssertFailure(__LINE__ + 3, msg, function noreturn()\n+ testAssertFailure(__LINE__ + 3, msg,\n {\n noreturn a;\n int b = a;\n- assert(false, \"Unreachable!\"); // Statement above not detected as noreturn\n+ });\n+\n+ testAssertFailure(__LINE__ + 4, msg,\n+ {\n+ noreturn a;\n+ auto p = &a; // OK\n+ int b = *p;\n+ });\n+\n+ testAssertFailure(__LINE__ + 4, msg,\n+ {\n+ noreturn a;\n+ ref r = a; // OK, reads &a\n+ int b = r; // asserts\n });\n \n testAssertFailure(__LINE__ + 2, msg, function noreturn()\n@@ -123,21 +133,21 @@ void testAccess()\n cast(noreturn) 1;\n });\n \n- version (FIXME)\n- testAssertFailure(__LINE__ + 3, msg, function noreturn()\n+ testAssertFailure(__LINE__ + 3, msg,\n {\n noreturn a;\n noreturn b = cast(noreturn) 1;\n });\n \n- if (false) // Read does not assert\n testAssertFailure(__LINE__ + 3, msg, function noreturn()\n {\n noreturn a;\n return a;\n });\n \n- if (false) // Read does not assert\n+ // FIXME: assertion failure in the backend in paramsize() - noreturn.sizeof = 0\n+ // https://github.com/dlang/dmd/issues/20286\n+ version (FIXME)\n testAssertFailure(__LINE__ + 4, msg, function noreturn()\n {\n static void foo(noreturn) {}\n@@ -145,6 +155,38 @@ void testAccess()\n foo(a);\n assert(false, \"Unreachable!\"); // Ditto\n });\n+\n+ testAssertFailure(__LINE__ + 5, msg,\n+ {\n+ static fv(int) {}\n+ static fr(ref noreturn a)\n+ {\n+ fv(a); // asserts\n+ }\n+ noreturn a;\n+ fr(a); // OK, passes &a\n+ });\n+\n+ testAssertFailure(__LINE__ + 3, msg,\n+ {\n+ noreturn v;\n+ auto id = typeid(v);\n+ });\n+\n+ // test condition\n+ testAssertFailure(__LINE__ + 3, msg,\n+ {\n+ noreturn v;\n+ if (v)\n+ return;\n+ });\n+\n+ // https://github.com/dlang/dmd/issues/22430\n+ testAssertFailure(__LINE__ + 3, msg,\n+ {\n+ noreturn a;\n+ auto b = true ? a : 1;\n+ });\n }\n \n /*****************************************/\ndiff --git a/gcc/testsuite/gdc.test/runnable/pragmainline.d b/gcc/testsuite/gdc.test/runnable/pragmainline.d\nindex f1b132f969c..f71c4b08c0a 100644\n--- a/gcc/testsuite/gdc.test/runnable/pragmainline.d\n+++ b/gcc/testsuite/gdc.test/runnable/pragmainline.d\n@@ -51,4 +51,11 @@ void main()\n assert(bar()() == baz());\n \n testAlwaysInline();\n+\n+ bool caught = false;\n+ try\n+ throws(throws(1));\n+ catch (Exception e)\n+ caught = true;\n+ assert(caught);\n }\ndiff --git a/gcc/testsuite/gdc.test/runnable/real_to_float.d b/gcc/testsuite/gdc.test/runnable/real_to_float.d\nindex 8b5c9701b99..7d42b52f32a 100644\n--- a/gcc/testsuite/gdc.test/runnable/real_to_float.d\n+++ b/gcc/testsuite/gdc.test/runnable/real_to_float.d\n@@ -3,8 +3,9 @@\n * \"converting real to float uses double rounding for 64-bit code\n * causing unexpected results\"\n */\n+\n pragma(inline, false)\n-void test(real r)\n+void test22322(real r)\n {\n assert(r == 0x1.000002fffffffcp-1);\n double d = r;\n@@ -19,10 +20,51 @@ void test(real r)\n assert(frd == 0x1.000004p-1);\n }\n \n+// https://github.com/dlang/dmd/issues/18316\n+pragma(inline, false)\n+void test18316(real closest)\n+{\n+ // Approximations to pi^2, accurate to 18 digits:\n+ // real closest = 0x9.de9e64df22ef2d2p+0L;\n+ real next = 0x9.de9e64df22ef2d3p+0L;\n+ assert(closest != next);\n+\n+ // A literal with 23 digits maps to the correct\n+ // representation.\n+ real dig23 = 9.86960_44010_89358_61883_45L;\n+ assert (dig23 == closest);\n+\n+ // 22 digits should also be (more than) sufficient,\n+ // but no...\n+ real dig22 = 9.86960_44010_89358_61883_5L;\n+ assert (dig22 == closest); // Fails; should pass\n+}\n+\n+// https://github.com/dlang/dmd/issues/19733\n+pragma(inline, false)\n+void test19733(real r)\n+{\n+ assert(r == 0x1FFFFFFFFFFFFFFFDp0L);\n+}\n+\n+pragma(inline, false)\n+void testDenormal(real rx)\n+{\n+ enum rd = 8.4052578577802337657e-4933L;\n+ real r1 = rx;\n+ real r2 = rd;\n+ assert(r1 > 0);\n+ assert(r1 == r2);\n+}\n+\n void main()\n {\n- static if (real.sizeof > 8)\n+ static if (real.mant_dig == 64)\n {\n- test(0x1.000002fffffffcp-1);\n+ // values must be passed to non-inlineable function to avoid \"optimization\" to double\n+ test22322(0.5000000894069671353303618843710864894092082977294921875);\n+ test18316(0x9.de9e64df22ef2d2p+0L);\n+ test19733(36893488147419103229.0L);\n+ testDenormal(0x1p-16384L);\n }\n }\ndiff --git a/gcc/testsuite/gdc.test/runnable/stress.d b/gcc/testsuite/gdc.test/runnable/stress.d\nindex 66373c4270d..078041aced0 100644\n--- a/gcc/testsuite/gdc.test/runnable/stress.d\n+++ b/gcc/testsuite/gdc.test/runnable/stress.d\n@@ -2,8 +2,6 @@\n // PERMUTE_ARGS:\n \n import core.stdc.stdio : printf;\n-import std.string : splitLines;\n-import std.utf : toUTF16, toUTF32;\n \n /***********************************************/\n \n@@ -106,19 +104,6 @@ void MDCHAR()\n foreach(char[] s; str) {\n tmp = tmp ~ s;\n }\n-\n- foreach(s; splitLines(cast(string)tmp)) {\n- size_t lstart;\n- foreach(size_t idx, char c; s) {\n- if(c == '\\n') {\n- if(s[lstart..idx] != \"TEST LINE\") {\n- printf(\"Error testing character array\\n\");\n- break;\n- }\n- lstart = idx + 1;\n- }\n- }\n- }\n }\n \n void CHAR()\n@@ -151,24 +136,6 @@ void WCHAR()\n const int ITERS = 1000;\n alias wchar typ;\n typ[] str;\n-\n- for(int idx = 0; idx < ITERS; idx++) {\n- str = str ~ toUTF16(cast(char[])\"TEST LINE\\n\");\n- }\n-\n- if(str.length != (ITERS * 10)) printf(\"Length Error: %zd\\n\",str.length);\n- if(str.sizeof != (typ[]).sizeof) printf(\"Size Error: %zd\\n\",str.sizeof);\n-\n- size_t lstart;\n- foreach(size_t idx, char c; str) {\n- if(c == '\\n') {\n- if(str[lstart..idx] != toUTF16(cast(char[])\"TEST LINE\")) {\n- printf(\"Error testing character array\\n\");\n- break;\n- }\n- lstart = idx + 1;\n- }\n- }\n }\n \n void DCHAR()\n@@ -176,24 +143,6 @@ void DCHAR()\n const int ITERS = 1000;\n alias dchar typ;\n typ[] str;\n-\n- for(int idx = 0; idx < ITERS; idx++) {\n- str = str ~ toUTF32(cast(char[])\"TEST LINE\\n\");\n- }\n-\n- if(str.length != (ITERS * 10)) printf(\"Length Error: %zd\\n\",str.length);\n- if(str.sizeof != (typ[]).sizeof) printf(\"Size Error: %zd\\n\",str.sizeof);\n-\n- size_t lstart;\n- foreach(size_t idx, char c; str) {\n- if(c == '\\n') {\n- if(str[lstart..idx] != toUTF32(cast(char[])\"TEST LINE\")) {\n- printf(\"Error testing character array\\n\");\n- break;\n- }\n- lstart = idx + 1;\n- }\n- }\n }\n \n void BYTE()\ndiff --git a/gcc/testsuite/gdc.test/runnable/test22384.d b/gcc/testsuite/gdc.test/runnable/test22384.d\nnew file mode 100644\nindex 00000000000..9a48263e383\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/runnable/test22384.d\n@@ -0,0 +1,49 @@\n+//https://github.com/dlang/dmd/issues/22384\n+struct S\n+{\n+ int a = 1;\n+ int b : 16 = 2;\n+ int c : 16 = 3;\n+ int d = 4;\n+}\n+\n+struct T\n+{\n+ int a = 1; // .long 1\n+ int b : 4 = 2; // .byte 0x32 (b=2, c=3 merged)\n+ int c : 4 = 3;\n+ int d : 8 = 4; // .byte 0x04\n+ int e : 4 = 5; // .byte 0x65 (e=5, f_low=6 merged)\n+ int f : 12 = 6; // .byte 0x00 (f_high)\n+ int g = 7; // .long 7\n+}\n+\n+struct M\n+{\n+ int a : 4 = 1;\n+ int : 4;\n+ int b : 4 = 2;\n+}\n+\n+S s;\n+T t;\n+M m;\n+\n+void main()\n+{\n+ assert(s.a == 1);\n+ assert(s.b == 2);\n+ assert(s.c == 3);\n+ assert(s.d == 4);\n+\n+ assert(t.a == 1);\n+ assert(t.b == 2);\n+ assert(t.c == 3);\n+ assert(t.d == 4);\n+ assert(t.e == 5);\n+ assert(t.f == 6);\n+ assert(t.g == 7);\n+\n+ assert(m.a == 1);\n+ assert(m.b == 2);\n+}\ndiff --git a/gcc/testsuite/gdc.test/runnable/test22427.d b/gcc/testsuite/gdc.test/runnable/test22427.d\nnew file mode 100644\nindex 00000000000..15d9fc00375\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/runnable/test22427.d\n@@ -0,0 +1,40 @@\n+// https://github.com/dlang/dmd/issues/22427\n+\n+noreturn exit1()\n+{\n+ throw new Exception(\"exit(1)\");\n+}\n+\n+noreturn exit0()\n+{\n+ throw new Exception(\"exit(0)\");\n+}\n+\n+void main()\n+{\n+ try\n+ {\n+ scope exitProgram = (bool failure) @trusted {\n+ return failure\n+ ? throw new Exception(\"exit(1)\")\n+ : throw new Exception(\"exit(0)\");\n+ };\n+ exitProgram(false);\n+ }\n+ catch (Exception e)\n+ {\n+ assert(e.message == \"exit(0)\");\n+ }\n+\n+ try\n+ {\n+ scope exitProgram = (bool failure) @trusted {\n+ return failure ? exit1() : exit0();\n+ };\n+ exitProgram(false);\n+ }\n+ catch (Exception e)\n+ {\n+ assert(e.message == \"exit(0)\");\n+ }\n+}\ndiff --git a/gcc/testsuite/gdc.test/runnable/test22489.d b/gcc/testsuite/gdc.test/runnable/test22489.d\nnew file mode 100644\nindex 00000000000..e0bfee39460\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/runnable/test22489.d\n@@ -0,0 +1,20 @@\n+// REQUIRED_ARGS: -inline -O\n+\n+real f(real r)\n+{\n+ return r - real.infinity;\n+}\n+\n+void main()\n+{\n+ assert(f(real.infinity) != f(real.infinity));\n+\n+ version (D_SIMD)\n+ {\n+ import core.simd;\n+ float4 v1 = float.infinity;\n+ float4 v2 = v1 - v1;\n+ static foreach (i; 0 .. 4)\n+ assert(v2[i] != v2[i]);\n+ }\n+}\ndiff --git a/gcc/testsuite/gdc.test/runnable/test28.d b/gcc/testsuite/gdc.test/runnable/test28.d\nindex 06c77467c2e..5491474f13b 100644\n--- a/gcc/testsuite/gdc.test/runnable/test28.d\n+++ b/gcc/testsuite/gdc.test/runnable/test28.d\n@@ -1287,7 +1287,6 @@ struct S67\n @disable this(this);\n }\n \n-pragma(inline, false)\n S67 make67()\n {\n return S67(1);\n@@ -1306,6 +1305,10 @@ void test67()\n {\n S67 s = f67();\n assert(s.ptr == &s);\n+\n+ S67 s2 = make67();\n+ auto closure = () { assert(s2.ptr == &s2); };\n+ closure();\n }\n \n /*******************************************/\ndiff --git a/gcc/testsuite/gdc.test/runnable/testaa3.d b/gcc/testsuite/gdc.test/runnable/testaa3.d\nindex 1d7cc616cfd..734c0c4cba0 100644\n--- a/gcc/testsuite/gdc.test/runnable/testaa3.d\n+++ b/gcc/testsuite/gdc.test/runnable/testaa3.d\n@@ -384,6 +384,15 @@ void test21066()\n aa2[[getValue()]] = \"a\"; // no problem because key type is automatically const(int)[]\n }\n \n+void test22354()\n+{\n+ int[][][string] aa; // AA with nested array value type\n+ int[] elem;\n+ aa[\"x\"] = null;\n+ aa[\"x\"] ~= null; // This append is silently lost!\n+ assert(aa[\"x\"].length == 1); // FAILS: length is still 0\n+}\n+\n /***************************************************/\n \n void main()\n@@ -411,4 +420,5 @@ void main()\n test12220();\n test12403();\n test21066();\n+ test22354();\n }\ndiff --git a/gcc/testsuite/gdc.test/runnable/uda.d b/gcc/testsuite/gdc.test/runnable/uda.d\nindex 133ae054573..713f36405aa 100644\n--- a/gcc/testsuite/gdc.test/runnable/uda.d\n+++ b/gcc/testsuite/gdc.test/runnable/uda.d\n@@ -749,6 +749,22 @@ template test15804()\n \n alias a15804 = test15804!();\n \n+/************************************************/\n+// https://github.com/dlang/dmd/issues/22282\n+\n+struct S22282\n+{\n+ int a,b;\n+ this(string a, string b) { }\n+ ~this() { }\n+}\n+\n+void issue22282()\n+{\n+\tenum var;\n+\t@var S22282 file = S22282(\"tmp\", \"w\");\n+}\n+\n /************************************************/\n \n int main()\n@@ -773,6 +789,7 @@ int main()\n test18();\n test19();\n test20();\n+ issue22282();\n \n printf(\"Success\\n\");\n return 0;\ndiff --git a/gcc/testsuite/gdc.test/runnable/with.d b/gcc/testsuite/gdc.test/runnable/with.d\nnew file mode 100644\nindex 00000000000..2f946622d2e\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/runnable/with.d\n@@ -0,0 +1,15 @@\n+\n+struct S\n+{\n+ int x;\n+}\n+S s;\n+void main()\n+{\n+ with(auto ss = S())\n+ {\n+ x = 42;\n+ s.x = x;\n+ }\n+ assert(s.x == 42);\n+}\ndiff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE\nindex 423f245b753..434ad554b84 100644\n--- a/libphobos/libdruntime/MERGE\n+++ b/libphobos/libdruntime/MERGE\n@@ -1,4 +1,4 @@\n-24a41073c2dbf456d4f7a6fe6a7965d6ce6fc5cb\n+e7c34c13de2930f2becc484e12b2c2cf1a16f6e8\n \n The first line of this file holds the git revision number of the last\n merge done from the dlang/dmd repository.\ndiff --git a/libphobos/libdruntime/__importc_builtins.di b/libphobos/libdruntime/__importc_builtins.di\nindex d0c173c694a..e24b535d452 100644\n--- a/libphobos/libdruntime/__importc_builtins.di\n+++ b/libphobos/libdruntime/__importc_builtins.di\n@@ -1,5 +1,5 @@\n /* GDC -- D front-end for GCC\n- Copyright (C) 2025 Free Software Foundation, Inc.\n+ Copyright (C) 2025-2026 Free Software Foundation, Inc.\n \n GCC is free software; you can redistribute it and/or modify it under\n the terms of the GNU General Public License as published by the Free\ndiff --git a/libphobos/libdruntime/core/bitop.d b/libphobos/libdruntime/core/bitop.d\nindex cc05247d6ca..2888a523e19 100644\n--- a/libphobos/libdruntime/core/bitop.d\n+++ b/libphobos/libdruntime/core/bitop.d\n@@ -292,13 +292,44 @@ int bt(const scope size_t* p, size_t bitnum) pure @system\n /**\n * Tests and complements the bit.\n */\n-int btc(size_t* p, size_t bitnum) pure @system;\n-\n+int btc(size_t* p, size_t bitnum) pure @system\n+{\n+ static if (size_t.sizeof == 8)\n+ {\n+ int result = ((p[bitnum >> 6] & (1L << (bitnum & 63)))) != 0;\n+ p[bitnum >> 6] ^= (1L << (bitnum & 63));\n+ return result;\n+ }\n+ else static if (size_t.sizeof == 4)\n+ {\n+ int result = ((p[bitnum >> 5] & (1L << (bitnum & 31)))) != 0;\n+ p[bitnum >> 5] ^= (1L << (bitnum & 31));\n+ return result;\n+ }\n+ else\n+ static assert(0);\n+}\n \n /**\n * Tests and resets (sets to 0) the bit.\n */\n-int btr(size_t* p, size_t bitnum) pure @system;\n+int btr(size_t* p, size_t bitnum) pure @system\n+{\n+ static if (size_t.sizeof == 8)\n+ {\n+ int result = ((p[bitnum >> 6] & (1L << (bitnum & 63)))) != 0;\n+ p[bitnum >> 6] &= ~(1L << (bitnum & 63));\n+ return result;\n+ }\n+ else static if (size_t.sizeof == 4)\n+ {\n+ int result = ((p[bitnum >> 5] & (1L << (bitnum & 31)))) != 0;\n+ p[bitnum >> 5] &= ~(1L << (bitnum & 31));\n+ return result;\n+ }\n+ else\n+ static assert(0);\n+}\n \n \n /**\n@@ -314,7 +345,23 @@ p[index / (size_t.sizeof*8)] & (1 << (index & ((size_t.sizeof*8) - 1)))\n * A non-zero value if the bit was set, and a zero\n * if it was clear.\n */\n-int bts(size_t* p, size_t bitnum) pure @system;\n+int bts(size_t* p, size_t bitnum) pure @system\n+{\n+ static if (size_t.sizeof == 8)\n+ {\n+ int result = ((p[bitnum >> 6] & (1L << (bitnum & 63)))) != 0;\n+ p[bitnum >> 6] |= (1L << (bitnum & 63));\n+ return result;\n+ }\n+ else static if (size_t.sizeof == 4)\n+ {\n+ int result = ((p[bitnum >> 5] & (1L << (bitnum & 31)))) != 0;\n+ p[bitnum >> 5] |= (1L << (bitnum & 31));\n+ return result;\n+ }\n+ else\n+ static assert(0);\n+}\n \n ///\n @system pure unittest\ndiff --git a/libphobos/libdruntime/core/exception.d b/libphobos/libdruntime/core/exception.d\nindex e1b69583e0f..cf9289c292d 100644\n--- a/libphobos/libdruntime/core/exception.d\n+++ b/libphobos/libdruntime/core/exception.d\n@@ -275,6 +275,49 @@ unittest\n }\n }\n \n+/**\n+ * When an unmapped pointer is accessed this may be thrown via a signal handler.\n+ */\n+class InvalidPointerError : Error\n+{\n+ @safe pure nothrow @nogc this(string file, size_t line)\n+ {\n+ this(file, line, cast(Throwable)null);\n+ }\n+\n+ @safe pure nothrow @nogc this(string file = __FILE__, size_t line = __LINE__, Throwable next = null)\n+ {\n+ this(\"Invalid pointer access\", file, line, next);\n+ }\n+\n+ @safe pure nothrow @nogc this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)\n+ {\n+ super(msg, file, line, next);\n+ }\n+}\n+\n+/**\n+ * Thrown when a null dereference may occur.\n+ *\n+ * Depends upon null dereference check, or a signal handler to throw.\n+ */\n+class NullPointerError : InvalidPointerError\n+{\n+ @safe pure nothrow @nogc this(string file, size_t line)\n+ {\n+ this(file, line, cast(Throwable)null);\n+ }\n+\n+ @safe pure nothrow @nogc this(string file = __FILE__, size_t line = __LINE__, Throwable next = null)\n+ {\n+ this(\"Null pointer dereference\", file, line, next);\n+ }\n+\n+ @safe pure nothrow @nogc this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)\n+ {\n+ super(msg, file, line, next);\n+ }\n+}\n \n /**\n * Thrown on finalize error.\n@@ -532,6 +575,7 @@ private __gshared\n {\n AssertHandler _assertHandler = null;\n FilterThreadThrowableHandler _filterThreadThrowableHandler = null;\n+ NullDerefHandler _nullDerefHandler = null;\n }\n \n \n@@ -569,6 +613,23 @@ alias FilterThreadThrowableHandler = void function(ref Throwable) @system nothro\n _filterThreadThrowableHandler = handler;\n }\n \n+/**\n+Gets/sets null dereference handler. null means the default handler is used.\n+*/\n+alias NullDerefHandler = void function(string file, size_t line) nothrow;\n+\n+/// ditto\n+@property NullDerefHandler nullDerefHandler() @trusted nothrow @nogc\n+{\n+ return _nullDerefHandler;\n+}\n+\n+/// ditto\n+@property void nullDerefHandler(NullDerefHandler handler) @trusted nothrow @nogc\n+{\n+ _nullDerefHandler = handler;\n+}\n+\n ///////////////////////////////////////////////////////////////////////////////\n // Overridable Callbacks\n ///////////////////////////////////////////////////////////////////////////////\n@@ -608,6 +669,21 @@ extern (C) void onAssertErrorMsg( string file, size_t line, string msg ) nothrow\n _assertHandler( file, line, msg );\n }\n \n+/**\n+ * A callback for null dereference errors in D.\n+ * The user-supplied dereference handler will be called if one has been supplied,\n+ * otherwise an $(LREF NullPointerError) will be thrown.\n+ *\n+ * Params:\n+ * file = The name of the file that signaled this error.\n+ * line = The line number on which this error occured.\n+ */\n+extern(C) void onNullPointerError(string file = __FILE__, size_t line = __LINE__) nothrow\n+{\n+ if (_nullDerefHandler is null)\n+ throw staticError!NullPointerError(file, line);\n+ _nullDerefHandler(file, line);\n+}\n \n /**\n * A callback for unittest errors in D. The user-supplied unittest handler\n@@ -884,6 +960,12 @@ extern (C)\n {\n onArrayIndexError(index, length, file, line);\n }\n+\n+ void _d_nullpointerp(immutable(char*) file, uint line)\n+ {\n+ import core.stdc.string : strlen;\n+ onNullPointerError(file[0 .. strlen(file)], line);\n+ }\n }\n \n // TLS storage shared for all errors, chaining might create circular reference\ndiff --git a/libphobos/libdruntime/core/sys/freebsd/config.d b/libphobos/libdruntime/core/sys/freebsd/config.d\nindex c57d2e4aa8e..932f166d2d0 100644\n--- a/libphobos/libdruntime/core/sys/freebsd/config.d\n+++ b/libphobos/libdruntime/core/sys/freebsd/config.d\n@@ -14,7 +14,8 @@ public import core.sys.posix.config;\n // NOTE: When adding newer versions of FreeBSD, verify all current versioned\n // bindings are still compatible with the release.\n \n- version (FreeBSD_15) enum __FreeBSD_version = 1500063;\n+ version (FreeBSD_16) enum __FreeBSD_version = 1600011;\n+else version (FreeBSD_15) enum __FreeBSD_version = 1500063;\n else version (FreeBSD_14) enum __FreeBSD_version = 1400097;\n else version (FreeBSD_13) enum __FreeBSD_version = 1301000;\n else version (FreeBSD_12) enum __FreeBSD_version = 1203000;\ndiff --git a/libphobos/libdruntime/core/sys/linux/hdlc/ioctl.d b/libphobos/libdruntime/core/sys/linux/hdlc/ioctl.d\nindex f879aae70a8..78992964b64 100644\n--- a/libphobos/libdruntime/core/sys/linux/hdlc/ioctl.d\n+++ b/libphobos/libdruntime/core/sys/linux/hdlc/ioctl.d\n@@ -1,9 +1,9 @@\n /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */\n module core.sys.linux.hdlc.ioctl;\n \n+version (linux):\n import core.sys.linux.net.if_ : IFNAMSIZ;\n \n-version (linux):\n extern(C):\n @nogc:\n nothrow:\ndiff --git a/libphobos/libdruntime/core/sys/linux/net/if_.d b/libphobos/libdruntime/core/sys/linux/net/if_.d\nindex 62d247f1250..ba6fc84f130 100644\n--- a/libphobos/libdruntime/core/sys/linux/net/if_.d\n+++ b/libphobos/libdruntime/core/sys/linux/net/if_.d\n@@ -6,10 +6,10 @@\n +/\n module core.sys.linux.net.if_;\n \n+version (linux):\n public import core.sys.posix.sys.socket : sockaddr;\n public import core.sys.linux.hdlc.ioctl;\n \n-version (linux):\n extern(C):\n @nogc:\n nothrow:\ndiff --git a/libphobos/libdruntime/core/sys/posix/signal.d b/libphobos/libdruntime/core/sys/posix/signal.d\nindex aed6ca7bcad..73da7607c57 100644\n--- a/libphobos/libdruntime/core/sys/posix/signal.d\n+++ b/libphobos/libdruntime/core/sys/posix/signal.d\n@@ -133,9 +133,8 @@ union sigval\n \n version (Solaris)\n {\n- import core.sys.posix.unistd;\n-\n @property int SIGRTMIN() nothrow @nogc {\n+ import core.sys.posix.unistd : sysconf, _SC_SIGRT_MIN;\n __gshared int sig = -1;\n if (sig == -1) {\n sig = cast(int)sysconf(_SC_SIGRT_MIN);\n@@ -144,6 +143,7 @@ version (Solaris)\n }\n \n @property int SIGRTMAX() nothrow @nogc {\n+ import core.sys.posix.unistd : sysconf, _SC_SIGRT_MAX;\n __gshared int sig = -1;\n if (sig == -1) {\n sig = cast(int)sysconf(_SC_SIGRT_MAX);\ndiff --git a/libphobos/libdruntime/core/sys/posix/sys/stat.d b/libphobos/libdruntime/core/sys/posix/sys/stat.d\nindex a2548037b9d..ad59019e181 100644\n--- a/libphobos/libdruntime/core/sys/posix/sys/stat.d\n+++ b/libphobos/libdruntime/core/sys/posix/sys/stat.d\n@@ -655,39 +655,29 @@ version (linux)\n {\n // Matches struct stat from musl arch/arm/bits/stat.h\n // See: https://git.musl-libc.org/cgit/musl/tree/arch/arm/bits/stat.h?h=v1.2.3\n- //\n- // Type definitions from https://git.musl-libc.org/cgit/musl/tree/include/alltypes.h.in?h=v1.2.3\n- // with ARM-specific _Int64=long long and _Reg=int from\n- // https://git.musl-libc.org/cgit/musl/tree/arch/arm/bits/alltypes.h.in?h=v1.2.3#n3\n- //\n- // Key 64-bit LFS types (always 64-bit on musl):\n- // dev_t = unsigned _Int64 = unsigned long long (line 31)\n- // off_t = _Int64 = long long (line 29)\n- // ino_t = unsigned _Int64 = unsigned long long (line 30)\n- // blkcnt_t = _Int64 = long long (line 33)\n- // blksize_t = long = long (32-bit) (line 32)\n- // nlink_t = unsigned _Reg = unsigned int (line 28)\n struct stat_t\n {\n- ulong st_dev;\n+ dev_t st_dev;\n int __st_dev_padding;\n c_long __st_ino_truncated;\n mode_t st_mode;\n- uint st_nlink;\n+ nlink_t st_nlink;\n uid_t st_uid;\n gid_t st_gid;\n- ulong st_rdev;\n+ dev_t st_rdev;\n int __st_rdev_padding;\n- long st_size;\n- c_long st_blksize;\n- long st_blocks;\n- struct __timespec32\n+ off_t st_size;\n+ blksize_t st_blksize;\n+ blkcnt_t st_blocks;\n+ private struct __timespec32\n {\n c_long tv_sec;\n c_long tv_nsec;\n }\n- __timespec32 __st_atim32, __st_mtim32, __st_ctim32;\n- ulong st_ino;\n+ __timespec32 __st_atim32;\n+ __timespec32 __st_mtim32;\n+ __timespec32 __st_ctim32;\n+ ino_t st_ino;\n timespec st_atim;\n timespec st_mtim;\n timespec st_ctim;\ndiff --git a/libphobos/libdruntime/core/sys/posix/sys/types.d b/libphobos/libdruntime/core/sys/posix/sys/types.d\nindex 2b65f7a986b..b6febde7136 100644\n--- a/libphobos/libdruntime/core/sys/posix/sys/types.d\n+++ b/libphobos/libdruntime/core/sys/posix/sys/types.d\n@@ -87,19 +87,7 @@ uid_t\n \n version (linux)\n {\n- // Musl always uses 64-bit off_t, blkcnt_t, ino_t on all arches (LFS by default).\n- // See: https://git.musl-libc.org/cgit/musl/tree/include/alltypes.h.in?h=v1.2.3#n29\n- // off_t: _Int64 -> long long (signed 64-bit)\n- // ino_t: unsigned _Int64 -> unsigned long long (64-bit)\n- // blkcnt_t: _Int64 -> long long (signed 64-bit)\n- // For ARM, _Int64 = long long: https://git.musl-libc.org/cgit/musl/tree/arch/arm/bits/alltypes.h.in?h=v1.2.3#n3\n- version (CRuntime_Musl)\n- {\n- alias long blkcnt_t;\n- alias ulong ino_t;\n- alias long off_t;\n- }\n- else static if ( __USE_FILE_OFFSET64 )\n+ static if ( __USE_FILE_OFFSET64 )\n {\n alias blkcnt_t = long;\n alias ino_t = ulong;\n@@ -360,17 +348,7 @@ useconds_t\n \n version (linux)\n {\n- // Musl always uses 64-bit fsblkcnt_t, fsfilcnt_t on all arches (LFS by default).\n- // See: https://git.musl-libc.org/cgit/musl/tree/include/alltypes.h.in?h=v1.2.3#n34\n- // fsblkcnt_t: unsigned _Int64 -> unsigned long long (64-bit)\n- // fsfilcnt_t: unsigned _Int64 -> unsigned long long (64-bit)\n- // For ARM, _Int64 = long long: https://git.musl-libc.org/cgit/musl/tree/arch/arm/bits/alltypes.h.in?h=v1.2.3#n3\n- version (CRuntime_Musl)\n- {\n- alias ulong fsblkcnt_t;\n- alias ulong fsfilcnt_t;\n- }\n- else static if ( __USE_FILE_OFFSET64 )\n+ static if ( __USE_FILE_OFFSET64 )\n {\n alias fsblkcnt_t = ulong;\n alias fsfilcnt_t = ulong;\ndiff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d\nindex 7464f648827..6827dad6199 100644\n--- a/libphobos/libdruntime/core/thread/osthread.d\n+++ b/libphobos/libdruntime/core/thread/osthread.d\n@@ -2777,43 +2777,38 @@ private\n \n version (CRuntime_Microsoft)\n extern(C) extern __gshared ubyte msvcUsesUCRT; // from rt/msvc.d\n+ extern(C) extern __gshared void* __ImageBase; // symbol at the beginning of module, added by linker\n+ enum HMODULE runtimeModule = &__ImageBase;\n \n /// set during termination of a DLL on Windows, i.e. while executing DllMain(DLL_PROCESS_DETACH)\n public __gshared bool thread_DLLProcessDetaching;\n \n- __gshared HMODULE ll_dllModule;\n __gshared ThreadID ll_dllMonitorThread;\n \n- int ll_countLowLevelThreadsWithDLLUnloadCallback() nothrow\n+ int ll_countLowLevelThreadsWithDLLUnloadCallback(HMODULE hMod) nothrow\n {\n lowlevelLock.lock_nothrow();\n scope(exit) lowlevelLock.unlock_nothrow();\n \n int cnt = 0;\n foreach (i; 0 .. ll_nThreads)\n- if (ll_pThreads[i].cbDllUnload)\n+ if (ll_pThreads[i].cbDllUnload && ll_pThreads[i].hMod == hMod)\n cnt++;\n return cnt;\n }\n \n- bool ll_dllHasExternalReferences() nothrow\n+ bool ll_dllHasExternalReferences(HMODULE hMod) nothrow\n {\n- int internalReferences = msvcUsesUCRT ? 1 + ll_countLowLevelThreadsWithDLLUnloadCallback() : 1;\n- int refcnt = dll_getRefCount(ll_dllModule);\n+ int unloadCallbacks = ll_countLowLevelThreadsWithDLLUnloadCallback(hMod);\n+ int internalReferences = hMod != runtimeModule ? unloadCallbacks\n+ : (ll_dllMonitorThread ? 1 : 0) + (msvcUsesUCRT ? unloadCallbacks : 0);\n+ int refcnt = dll_getRefCount(hMod);\n return refcnt > internalReferences;\n }\n \n- private void monitorDLLRefCnt() nothrow\n+ void notifyUnloadLowLevelThreads(HMODULE hMod) nothrow\n {\n- // this thread keeps the DLL alive until all external references are gone\n- while (ll_dllHasExternalReferences())\n- {\n- Thread.sleep(100.msecs);\n- }\n-\n- // the current thread will be terminated below\n- ll_removeThread(GetCurrentThreadId());\n-\n+ HMODULE toFree;\n for (;;)\n {\n ThreadID tid;\n@@ -2823,36 +2818,70 @@ private\n scope(exit) lowlevelLock.unlock_nothrow();\n \n foreach (i; 0 .. ll_nThreads)\n- if (ll_pThreads[i].cbDllUnload)\n+ if (ll_pThreads[i].cbDllUnload && ll_pThreads[i].hMod == hMod)\n {\n+ if (!toFree)\n+ toFree = ll_getModuleHandle(hMod, true); // keep the module alive until the callback returns\n cbDllUnload = ll_pThreads[i].cbDllUnload;\n- tid = ll_pThreads[0].tid;\n+ tid = ll_pThreads[i].tid;\n+ break;\n }\n }\n if (!cbDllUnload)\n break;\n- cbDllUnload();\n+ cbDllUnload(); // must wait for thread termination\n assert(!findLowLevelThread(tid));\n }\n+ if (toFree)\n+ FreeLibrary(toFree);\n+ }\n+\n+ private void monitorDLLRefCnt() nothrow\n+ {\n+ // this thread keeps the DLL alive until all external references are gone\n+ // (including those from DLLs using druntime in a shared DLL)\n+ while (ll_dllHasExternalReferences(runtimeModule))\n+ {\n+ // find and unload module that only has internal references left\n+ HMODULE hMod;\n+ {\n+ lowlevelLock.lock_nothrow();\n+ scope(exit) lowlevelLock.unlock_nothrow();\n+\n+ foreach (i; 0 .. ll_nThreads)\n+ if (ll_pThreads[i].cbDllUnload && ll_pThreads[i].hMod != runtimeModule)\n+ if (!ll_dllHasExternalReferences(ll_pThreads[i].hMod))\n+ {\n+ hMod = ll_pThreads[i].hMod;\n+ break;\n+ }\n+ }\n+ if (hMod)\n+ notifyUnloadLowLevelThreads(hMod);\n+ else\n+ Thread.sleep(100.msecs);\n+ }\n+\n+ notifyUnloadLowLevelThreads(runtimeModule);\n+\n+ // the current thread will be terminated without cleanup within the thread\n+ ll_removeThread(GetCurrentThreadId());\n \n- FreeLibraryAndExitThread(ll_dllModule, 0);\n+ FreeLibraryAndExitThread(runtimeModule, 0);\n }\n \n- int ll_getDLLRefCount() nothrow @nogc\n+ HMODULE ll_getModuleHandle(void* funcptr, bool addref = false) nothrow @nogc\n {\n- if (!ll_dllModule &&\n- !GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,\n- cast(const(wchar)*) &ll_getDLLRefCount, &ll_dllModule))\n- return -1;\n- return dll_getRefCount(ll_dllModule);\n+ HMODULE hmod;\n+ DWORD refflag = addref ? 0 : GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;\n+ if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | refflag,\n+ cast(const(wchar)*) funcptr, &hmod))\n+ return null;\n+ return hmod;\n }\n \n bool ll_startDLLUnloadThread() nothrow @nogc\n {\n- int refcnt = ll_getDLLRefCount();\n- if (refcnt < 0)\n- return false; // not a dynamically loaded DLL\n-\n if (ll_dllMonitorThread !is ThreadID.init)\n return true;\n \n@@ -2860,13 +2889,10 @@ private\n // to avoid the DLL being unloaded while the thread is still running. Mimick this behavior here for all\n // runtimes not doing this\n bool needRef = !msvcUsesUCRT;\n-\n if (needRef)\n- {\n- HMODULE hmod;\n- GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, cast(const(wchar)*) &ll_getDLLRefCount, &hmod);\n- }\n+ ll_getModuleHandle(runtimeModule, true);\n \n+ // the monitor thread must be a low-level thread so the runtime does not attach to it\n ll_dllMonitorThread = createLowLevelThread(() { monitorDLLRefCnt(); });\n return ll_dllMonitorThread != ThreadID.init;\n }\n@@ -2890,8 +2916,15 @@ private\n ThreadID createLowLevelThread(void delegate() nothrow dg, uint stacksize = 0,\n void delegate() nothrow cbDllUnload = null) nothrow @nogc\n {\n- void delegate() nothrow* context = cast(void delegate() nothrow*)malloc(dg.sizeof);\n- *context = dg;\n+ static struct Context\n+ {\n+ void delegate() nothrow dg;\n+ version (Windows)\n+ HMODULE cbMod;\n+ }\n+ auto context = cast(Context*)malloc(Context.sizeof);\n+ scope(exit) free(context);\n+ context.dg = dg;\n \n ThreadID tid;\n version (Windows)\n@@ -2899,14 +2932,30 @@ ThreadID createLowLevelThread(void delegate() nothrow dg, uint stacksize = 0,\n // the thread won't start until after the DLL is unloaded\n if (thread_DLLProcessDetaching)\n return ThreadID.init;\n+ context.cbMod = cbDllUnload ? ll_getModuleHandle(cbDllUnload.funcptr) : null;\n+ if (context.cbMod)\n+ {\n+ int refcnt = dll_getRefCount(context.cbMod);\n+ if (refcnt < 0)\n+ {\n+ // not a dynamically loaded DLL, so never unloaded\n+ cbDllUnload = null;\n+ context.cbMod = null;\n+ }\n+ if (refcnt == 0)\n+ return ThreadID.init; // createLowLevelThread called while DLL is unloading\n+ }\n \n static extern (Windows) uint thread_lowlevelEntry(void* ctx) nothrow\n {\n- auto dg = *cast(void delegate() nothrow*)ctx;\n+ auto context = *cast(Context*)ctx;\n free(ctx);\n \n- dg();\n+ context.dg();\n+\n ll_removeThread(GetCurrentThreadId());\n+ if (context.cbMod && context.cbMod != runtimeModule)\n+ FreeLibrary(context.cbMod);\n return 0;\n }\n \n@@ -2922,11 +2971,20 @@ ThreadID createLowLevelThread(void delegate() nothrow dg, uint stacksize = 0,\n \n ll_nThreads++;\n ll_pThreads = cast(ll_ThreadData*)realloc(ll_pThreads, ll_ThreadData.sizeof * ll_nThreads);\n+ ll_pThreads[ll_nThreads - 1] = ll_ThreadData.init;\n \n version (Windows)\n {\n ll_pThreads[ll_nThreads - 1].tid = tid;\n- ll_pThreads[ll_nThreads - 1].cbDllUnload = cbDllUnload;\n+ // ignore callback if not a dynamically loaded DLL\n+ if (cbDllUnload)\n+ {\n+ ll_pThreads[ll_nThreads - 1].cbDllUnload = cbDllUnload;\n+ ll_pThreads[ll_nThreads - 1].hMod = context.cbMod;\n+ if (context.cbMod != runtimeModule)\n+ ll_getModuleHandle(context.cbMod, true); // increment ref count\n+ }\n+\n if (ResumeThread(hThread) == -1)\n onThreadError(\"Error resuming thread\");\n CloseHandle(hThread);\n@@ -2938,10 +2996,10 @@ ThreadID createLowLevelThread(void delegate() nothrow dg, uint stacksize = 0,\n {\n static extern (C) void* thread_lowlevelEntry(void* ctx) nothrow\n {\n- auto dg = *cast(void delegate() nothrow*)ctx;\n+ auto context = *cast(Context*)ctx;\n free(ctx);\n \n- dg();\n+ context.dg();\n ll_removeThread(pthread_self());\n return null;\n }\n@@ -2957,11 +3015,12 @@ ThreadID createLowLevelThread(void delegate() nothrow dg, uint stacksize = 0,\n return ThreadID.init;\n if ((rc = pthread_create(&tid, &attr, &thread_lowlevelEntry, context)) != 0)\n return ThreadID.init;\n- if ((rc = pthread_attr_destroy(&attr)) != 0)\n- return ThreadID.init;\n+ rc = pthread_attr_destroy(&attr);\n+ assert(rc == 0);\n \n ll_pThreads[ll_nThreads - 1].tid = tid;\n }\n+ context = null; // free'd in thread\n return tid;\n }\n \ndiff --git a/libphobos/libdruntime/core/thread/types.d b/libphobos/libdruntime/core/thread/types.d\nindex 4d0b3649ec7..c816010e5ce 100644\n--- a/libphobos/libdruntime/core/thread/types.d\n+++ b/libphobos/libdruntime/core/thread/types.d\n@@ -29,7 +29,10 @@ struct ll_ThreadData\n {\n ThreadID tid;\n version (Windows)\n+ {\n void delegate() nothrow cbDllUnload;\n+ void* hMod; // HMODULE containing the unload callback\n+ }\n }\n \n version (GNU)\ndiff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d\nindex 96fd06b59eb..bb0c3d3c273 100644\n--- a/libphobos/libdruntime/object.d\n+++ b/libphobos/libdruntime/object.d\n@@ -97,7 +97,8 @@ else version (X86_64)\n else version (AArch64)\n {\n // Apple uses a trivial varargs implementation\n- version (OSX) {}\n+ version (DigitalMars) version = WithArgTypes; // is this needed?\n+ else version (OSX) {}\n else version (iOS) {}\n else version (TVOS) {}\n else version (WatchOS) {}\ndiff --git a/libphobos/src/MERGE b/libphobos/src/MERGE\nindex 620ac77e117..d5e9b11a68c 100644\n--- a/libphobos/src/MERGE\n+++ b/libphobos/src/MERGE\n@@ -1,4 +1,4 @@\n-f7249cf45c476a8b31ef89e1793c2768da0fdc27\n+0c5c9e98443de1bb75c7c3560f58baa6ce725209\n \n The first line of this file holds the git revision number of the last\n merge done from the dlang/phobos repository.\ndiff --git a/libphobos/src/std/format/spec.d b/libphobos/src/std/format/spec.d\nindex b828bb65b8a..623fd06b7f2 100644\n--- a/libphobos/src/std/format/spec.d\n+++ b/libphobos/src/std/format/spec.d\n@@ -375,7 +375,8 @@ if (is(Unqual!Char == Char))\n case '0': flZero = true; ++i; break;\n case ' ': flSpace = true; ++i; break;\n case '*':\n- if (isDigit(trailing[++i]))\n+ ++i;\n+ if (i < trailing.length && isDigit(trailing[i]))\n {\n // a '*' followed by digits and '$' is a\n // positional format\n@@ -427,17 +428,17 @@ if (is(Unqual!Char == Char))\n }\n break;\n case ',':\n- // Precision\n+ // Separator (default 3 digits)\n ++i;\n flSeparator = true;\n \n- if (trailing[i] == '*')\n+ if (i < trailing.length && trailing[i] == '*')\n {\n ++i;\n // read result\n separators = DYNAMIC;\n }\n- else if (isDigit(trailing[i]))\n+ else if (i < trailing.length && isDigit(trailing[i]))\n {\n auto tmp = trailing[i .. $];\n separators = parse!int(tmp);\n@@ -449,7 +450,7 @@ if (is(Unqual!Char == Char))\n separators = 3;\n }\n \n- if (trailing[i] == '?')\n+ if (i < trailing.length && trailing[i] == '?')\n {\n dynamicSeparatorChar = true;\n ++i;\n@@ -458,9 +459,11 @@ if (is(Unqual!Char == Char))\n break;\n case '.':\n // Precision\n- if (trailing[++i] == '*')\n+ ++i;\n+ if (i < trailing.length && trailing[i] == '*')\n {\n- if (isDigit(trailing[++i]))\n+ ++i;\n+ if (i < trailing.length && isDigit(trailing[i]))\n {\n // a '.*' followed by digits and '$' is a\n // positional precision\n@@ -476,7 +479,7 @@ if (is(Unqual!Char == Char))\n precision = DYNAMIC;\n }\n }\n- else if (trailing[i] == '-')\n+ else if (i < trailing.length && trailing[i] == '-')\n {\n // negative precision, as good as 0\n precision = 0;\n@@ -484,7 +487,7 @@ if (is(Unqual!Char == Char))\n parse!int(tmp); // skip digits\n i = trailing.length - tmp.length;\n }\n- else if (isDigit(trailing[i]))\n+ else if (i < trailing.length && isDigit(trailing[i]))\n {\n auto tmp = trailing[i .. $];\n precision = parse!int(tmp);\n@@ -938,6 +941,11 @@ FormatSpec!Char singleSpec(Char)(Char[] fmt)\n assertThrown!FormatException(singleSpec(\"Test%2.3e\"));\n assertThrown!FormatException(singleSpec(\"%2.3eTest\"));\n assertThrown!FormatException(singleSpec(\"%%\"));\n+ assertThrown!FormatException(singleSpec(\"%.\"));\n+ assertThrown!FormatException(singleSpec(\"%.*\"));\n+ assertThrown!FormatException(singleSpec(\"%*\"));\n+ assertThrown!FormatException(singleSpec(\"%,\"));\n+ assertThrown!FormatException(singleSpec(\"%,*\"));\n }\n \n // @@@DEPRECATED_[2.107.0]@@@\ndiff --git a/libphobos/src/std/functional.d b/libphobos/src/std/functional.d\nindex 12c261bd0bd..1c2e6dda5fc 100644\n--- a/libphobos/src/std/functional.d\n+++ b/libphobos/src/std/functional.d\n@@ -16,11 +16,21 @@ $(TR $(TH Function Name) $(TH Description)\n $(TD Joins a couple of functions into one that executes the original\n functions independently and returns a tuple with all the results.\n ))\n+ $(TR $(TD $(LREF bind))\n+ $(TD Passes the fields of a struct as arguments to a function.\n+ ))\n $(TR $(TD $(LREF compose), $(LREF pipe))\n $(TD Join a couple of functions into one that executes the original\n functions one after the other, using one function's result for the next\n function's argument.\n ))\n+ $(TR $(TD $(LREF ctEval))\n+ $(TD Enforces the evaluation of an expression during compile-time.\n+ ))\n+ $(TR $(TD $(LREF curry))\n+ $(TD Converts a multi-argument function into a series of single-argument\n+ functions. `f(x, y) == curry(f)(x)(y)`\n+ ))\n $(TR $(TD $(LREF lessThan), $(LREF greaterThan), $(LREF equalTo))\n $(TD Ready-made predicate functions to compare two values.\n ))\n@@ -34,10 +44,6 @@ $(TR $(TH Function Name) $(TH Description)\n $(TD Creates a function that binds the first argument of a given function\n to a given value.\n ))\n- $(TR $(TD $(LREF curry))\n- $(TD Converts a multi-argument function into a series of single-argument\n- functions. f(x, y) == curry(f)(x)(y)\n- ))\n $(TR $(TD $(LREF reverseArgs))\n $(TD Predicate that reverses the order of its arguments.\n ))\n@@ -48,12 +54,6 @@ $(TR $(TH Function Name) $(TH Description)\n $(TD Create a unary or binary function from a string. Most often\n used when defining algorithms on ranges.\n ))\n- $(TR $(TD $(LREF bind))\n- $(TD Passes the fields of a struct as arguments to a function.\n- ))\n- $(TR $(TD $(LREF ctEval))\n- $(TD Enforces the evaluation of an expression during compile-time.\n- ))\n ))\n \n Copyright: Copyright Andrei Alexandrescu 2008 - 2009.\n@@ -911,7 +911,7 @@ template partial(alias fun, alias arg)\n \n /**\n Takes a function of (potentially) many arguments, and returns a function taking\n-one argument and returns a callable taking the rest. f(x, y) == curry(f)(x)(y)\n+one argument and returns a callable taking the rest. `f(x, y) == curry(f)(x)(y)`\n \n Params:\n F = a function taking at least one argument\ndiff --git a/libphobos/src/std/internal/math/gammafunction.d b/libphobos/src/std/internal/math/gammafunction.d\nindex 468f7eff8f5..d4e51f5653a 100644\n--- a/libphobos/src/std/internal/math/gammafunction.d\n+++ b/libphobos/src/std/internal/math/gammafunction.d\n@@ -22,6 +22,9 @@ module std.internal.math.gammafunction;\n import std.internal.math.errorfunction;\n import std.math;\n import core.math : fabs, sin, sqrt;\n+import std.algorithm.iteration : fold;\n+import std.algorithm.searching : any;\n+import std.range : only;\n \n pure:\n nothrow:\n@@ -77,6 +80,34 @@ immutable real[8] logGammaDenominator = [\n -0x1.00f95ced9e5f54eep+9L, 1.0L\n ];\n \n+\n+/* Given a set of real values where at least one of them is NaN, it returns the\n+ * NaN with the largest payload. This implements the NaN handling policy\n+ * followed by D operators that accept multiple floating point arguments.\n+ *\n+ * It preserves the sign of the NaN. Also, when multiple NaNs have the largest\n+ * payload, it returns the leftmost one. This means that\n+ * largestNaNPayload(-NaN(1), NaN(1)) returns -NaN(1), and\n+ * largestNaNPayload(NaN(1), -NaN(1)) returns NaN(1).\n+ *\n+ * When none of the provided values are NaN, the result is undefined.\n+ */\n+real largestNaNPayload(real first, real[] rest ...)\n+{\n+ return fold!((a, b) => cmp(abs(a), abs(b)) >= 0 ? a : b)(rest, first);\n+}\n+\n+@safe unittest\n+{\n+ assert(largestNaNPayload(NaN(0)) is NaN(0));\n+ assert(largestNaNPayload(NaN(1), NaN(0)) is NaN(1));\n+ assert(largestNaNPayload(NaN(2), NaN(3), NaN(1)) is NaN(3));\n+ assert(largestNaNPayload(-10.0L, -real.nan, 1.0L) is -real.nan);\n+ assert(largestNaNPayload(-NaN(1), NaN(1)) is -NaN(1));\n+ assert(largestNaNPayload(NaN(1), -NaN(1)) is NaN(1));\n+}\n+\n+\n /*\n * Helper function: Gamma function computed by Stirling's formula.\n *\n@@ -1012,14 +1043,7 @@ enum real BETA_BIGINV = 1.084202172485504434007e-19L;\n */\n real betaIncomplete(real aa, real bb, real xx )\n {\n- // If any parameters are NaN, return the NaN with the largest payload.\n- if (isNaN(aa) || isNaN(bb) || isNaN(xx))\n- {\n- // With cmp,\n- // -NaN(larger) < -NaN(smaller) < -inf < inf < NaN(smaller) < NaN(larger).\n- const largerParam = cmp(abs(aa), abs(bb)) >= 0 ? aa : bb;\n- return cmp(abs(xx), abs(largerParam)) >= 0 ? xx : largerParam;\n- }\n+ if (only(aa, bb, xx).any!isNaN) return largestNaNPayload(xx, aa, bb);\n \n // domain errors\n if (signbit(aa) == 1 || signbit(bb) == 1) return real.nan;\n@@ -1762,14 +1786,6 @@ real betaDistPowerSeries(real a, real b, real x )\n /***************************************\n * Incomplete gamma integral and its complement\n *\n- * These functions are defined by\n- *\n- * gammaIncomplete = ( $(INTEGRATE 0, x) $(POWER e, -t) $(POWER t, a-1) dt )/ $(GAMMA)(a)\n- *\n- * gammaIncompleteCompl(a,x) = 1 - gammaIncomplete(a,x)\n- * = ($(INTEGRATE x, ∞) $(POWER e, -t) $(POWER t, a-1) dt )/ $(GAMMA)(a)\n- *\n- * In this implementation both arguments must be positive.\n * The integral is evaluated by either a power series or\n * continued fraction expansion, depending on the relative\n * values of a and x.\n@@ -1777,22 +1793,26 @@ real betaDistPowerSeries(real a, real b, real x )\n real gammaIncomplete(real a, real x )\n in\n {\n- assert(x >= 0);\n- assert(a > 0);\n+ if (!any!isNaN(only(a, x)))\n+ {\n+ assert(x >= 0);\n+ assert(signbit(a) == 0);\n+ }\n }\n do\n {\n- /* left tail of incomplete gamma function:\n- *\n- * inf. k\n- * a -x - x\n- * x e > ----------\n- * - -\n- * k=0 | (a+k+1)\n- *\n- */\n- if (x == 0)\n- return 0.0L;\n+ // pass x first, so that if x and a are NaNs with the same payload but with\n+ // opposite signs, return x.\n+ if (any!isNaN(only(a, x))) return largestNaNPayload(x, a);\n+\n+ // domain violation\n+ if (signbit(a) == 1 || x < 0.0L) return real.nan;\n+\n+ // edge cases\n+ if (x == 0.0L) return 0.0L;\n+ if (x is real.infinity) return 1.0L;\n+ if (a is +0.0L) return 1.0L;\n+ if (a is real.infinity) return 0.0L;\n \n if ( (x > 1.0L) && (x > a ) )\n return 1.0L - gammaIncompleteCompl(a,x);\n@@ -1823,13 +1843,27 @@ do\n real gammaIncompleteCompl(real a, real x )\n in\n {\n- assert(x >= 0);\n- assert(a > 0);\n+ if (!any!isNaN(only(a, x)))\n+ {\n+ assert(x >= 0);\n+ assert(signbit(a) == 0);\n+ }\n }\n do\n {\n- if (x == 0)\n- return 1.0L;\n+ // pass x first, so that if x and a are NaNs with the same payload but with\n+ // opposite signs, return x.\n+ if (any!isNaN(only(a, x))) return largestNaNPayload(x, a);\n+\n+ // domain violation\n+ if (signbit(a) == 1 || x < 0.0L) return real.nan;\n+\n+ // edge cases\n+ if (x == 0.0L) return 1.0L;\n+ if (x is real.infinity) return 0.0L;\n+ if (a is +0.0L) return 0.0L;\n+ if (a is real.infinity) return 1.0L;\n+\n if ( (x < 1.0L) || (x < a) )\n return 1.0L - gammaIncomplete(a,x);\n \n@@ -2039,6 +2073,18 @@ ihalve:\n \n @safe unittest\n {\n+assert(gammaIncomplete(NaN(4), -NaN(4)) is -NaN(4));\n+assert(!isNaN(gammaIncomplete(+0.0L, 1.0L)));\n+assert(!isNaN(gammaIncomplete(1.0L, -0.0L)));\n+assert(gammaIncomplete(+0.0L, 0.0L) == 0.0L);\n+assert(gammaIncomplete(real.infinity, real.infinity) == 1.0L);\n+\n+assert(gammaIncompleteCompl(NaN(4), -NaN(4)) is -NaN(4));\n+assert(!isNaN(gammaIncompleteCompl(+0.0L, 1.0L)));\n+assert(!isNaN(gammaIncompleteCompl(1.0L, -0.0L)));\n+assert(gammaIncompleteCompl(+0.0L, 0.0L) == 1.0L);\n+assert(gammaIncompleteCompl(real.infinity, real.infinity) == 0.0L);\n+\n //Values from Excel's GammaInv(1-p, x, 1)\n assert(fabs(gammaIncompleteComplInv(1, 0.5L) - 0.693147188044814L) < 0.00000005L);\n assert(fabs(gammaIncompleteComplInv(12, 0.99L) - 5.42818075054289L) < 0.00000005L);\ndiff --git a/libphobos/src/std/mathspecial.d b/libphobos/src/std/mathspecial.d\nindex 8889cbf6c67..fc33c921191 100644\n--- a/libphobos/src/std/mathspecial.d\n+++ b/libphobos/src/std/mathspecial.d\n@@ -29,6 +29,7 @@\n * NAN = $(RED NAN)\n * SUP = <span style=\"vertical-align:super;font-size:smaller\">$0</span>\n * GAMMA = Γ\n+ * LGAMMA =γ\n * PSI = Ψ\n * THETA = θ\n * INTEGRAL = ∫\n@@ -47,9 +48,11 @@\n * LT = <\n * LE = ≤\n * GT = >\n+ * GE = ≥\n * SQRT = √\n * HALF = ½\n * COMPLEX = ℂ\n+ * NOBR = <nobr>$1</nobr>\n *\n * Copyright: Based on the CEPHES math library, which is\n * Copyright (C) 1994 Stephen L. Moshier (moshier@world.std.com).\n@@ -396,43 +399,112 @@ real betaIncompleteInverse(real a, real b, real y )\n return std.internal.math.gammafunction.betaIncompleteInv(a, b, y);\n }\n \n-/** Incomplete gamma integral and its complement\n+/** Regularized lower incomplete gamma function P(a,x)\n *\n- * These functions are defined by\n+ * Mathematically, P(a,x) = $(LGAMMA)(a,x)/$(GAMMA)(a), where $(LGAMMA)(a,x) is the lower incomplete\n+ * gamma function, $(LGAMMA)(a,x) = $(INTEGRATE 0, x)$(POWER t, a-1)$(POWER e, -t)dt, a $(GT) 0, and\n+ * x $(GE) 0.\n *\n- * gammaIncomplete = ( $(INTEGRATE 0, x) $(POWER e, -t) $(POWER t, a-1) dt )/ $(GAMMA)(a)\n+ * Params:\n+ * a = the shape parameter, must be positive\n+ * x = the fraction of integration completion from below, must be non-negative\n+ *\n+ * Returns:\n+ * It returns P(a,x), an element of [0,1].\n *\n- * gammaIncompleteCompl(a,x) = 1 - gammaIncomplete(a,x)\n- * = ($(INTEGRATE x, $(INFIN)) $(POWER e, -t) $(POWER t, a-1) dt )/ $(GAMMA)(a)\n+ * $(TABLE_SV\n+ * $(TR $(TH a) $(TH x) $(TH gammaIncomplete(a, x)) )\n+ * $(TR $(TD negative) $(TD) $(TD $(NAN)) )\n+ * $(TR $(TD) $(TD $(LT) 0) $(TD $(NAN)) )\n+ * $(TR $(TD positive) $(TD 0) $(TD 0) )\n+ * $(TR $(TD positive) $(TD $(INFIN)) $(TD 1) )\n+ * $(TR $(TD +0) $(TD $(GT) 0) $(TD 1) )\n+ * $(TR $(TD $(INFIN)) $(TD (0, $(INFIN))) $(TD 0) )\n+ * )\n *\n- * In this implementation both arguments must be positive.\n- * The integral is evaluated by either a power series or\n- * continued fraction expansion, depending on the relative\n- * values of a and x.\n+ * See_Also: $(LREF gamma) and $(LREF gammaIncompleteCompl)\n */\n real gammaIncomplete(real a, real x )\n in\n {\n- assert(x >= 0);\n- assert(a > 0);\n+ // allow NaN input to pass through so that it can be addressed by the\n+ // internal NaN payload propagation logic\n+ if (!isNaN(a) && !isNaN(x))\n+ {\n+ assert(signbit(a) == 0, \"a must be positive\");\n+ assert(x >= 0, \"x must be non-negative\");\n+ }\n }\n+out(p; isNaN(p) || (p >= 0 && p <= 1))\n do\n {\n return std.internal.math.gammafunction.gammaIncomplete(a, x);\n }\n \n-/** ditto */\n-real gammaIncompleteCompl(real a, real x )\n+///\n+@safe unittest\n+{\n+ assert(isClose(gammaIncomplete(1, 1), 1 - 1/E));\n+ assert(gammaIncomplete(1, 0) == 0);\n+ assert(gammaIncomplete(1, real.infinity) == 1);\n+ assert(gammaIncomplete(+0., 1) == 1);\n+ assert(gammaIncomplete(real.infinity, 1) == 0);\n+}\n+\n+/** Regularized upper incomplete gamma function Q(a,x)\n+ *\n+ * Mathematically, Q(a,x) = $(GAMMA)(a,x)/$(GAMMA)(a), where $(GAMMA)(a,x) is the upper incomplete\n+ * gamma function, $(GAMMA)(a,x) = $(INTEGRATE x, $(INFIN))$(POWER t, a-1)$(POWER e, -t)dt,\n+ * $(NOBR a $(GT) 0), and x $(GE) 0. Note that P(a,x) + Q(a,x) = 1 or Q(a,x) = 1 - P(a,x), so Q is\n+ * the complement of P.\n+ *\n+ * Params:\n+ * a = the shape parameter, must be positive\n+ * x = the fraction of integration completion from above, must be non-negative\n+ *\n+ * Returns:\n+ * It returns Q(a,x), an element of [0,1].\n+ *\n+ * $(TABLE_SV\n+ * $(TR $(TH a) $(TH x) $(TH gammaIncompleteCompl(a, x)) )\n+ * $(TR $(TD negative) $(TD) $(TD $(NAN)) )\n+ * $(TR $(TD) $(TD $(LT) 0) $(TD $(NAN)) )\n+ * $(TR $(TD positive) $(TD 0) $(TD 1) )\n+ * $(TR $(TD positive) $(TD $(INFIN)) $(TD 0) )\n+ * $(TR $(TD +0) $(TD $(GT) 0) $(TD 0) )\n+ * $(TR $(TD $(INFIN)) $(TD (0, $(INFIN))) $(TD 1) )\n+ * )\n+ *\n+ * See_Also: $(LREF gamma) and $(LREF gammaIncomplete)\n+ */\n+ real gammaIncompleteCompl(real a, real x )\n in\n {\n- assert(x >= 0);\n- assert(a > 0);\n+ // allow NaN input to pass through so that it can be addressed by the\n+ // internal NaN payload propagation logic\n+ if (!isNaN(a) && !isNaN(x))\n+ {\n+ assert(signbit(a) == 0, \"a must be positive\");\n+ assert(x >= 0, \"x must be non-negative\");\n+ }\n }\n+out(q; isNaN(q) || (q >= 0 && q <= 1))\n do\n {\n return std.internal.math.gammafunction.gammaIncompleteCompl(a, x);\n }\n \n+///\n+@safe unittest\n+{\n+ assert(isClose(gammaIncompleteCompl(2, 1), 2/E));\n+ assert(gammaIncompleteCompl(1, 0) == 1);\n+ assert(gammaIncompleteCompl(1, real.infinity) == 0);\n+ assert(gammaIncompleteCompl(+0., 1) == 0);\n+ assert(gammaIncompleteCompl(real.infinity, 1) == 1);\n+ assert(isClose(gammaIncompleteCompl(1, 2), 1-gammaIncomplete(1, 2)));\n+}\n+\n /** Inverse of complemented incomplete gamma integral\n *\n * Given a and p, the function finds x such that\ndiff --git a/libphobos/src/std/meta.d b/libphobos/src/std/meta.d\nindex 2db341da85e..2ab00e7a355 100644\n--- a/libphobos/src/std/meta.d\n+++ b/libphobos/src/std/meta.d\n@@ -175,9 +175,6 @@ alias AliasSeq(TList...) = TList;\n */\n alias Alias(alias a) = a;\n \n-/// Ditto\n-alias Alias(T) = T;\n-\n ///\n @safe unittest\n {\n@@ -222,44 +219,17 @@ alias Alias(T) = T;\n assert(g == 7);\n }\n \n-package template OldAlias(alias a)\n-{\n- static if (__traits(compiles, { alias x = a; }))\n- alias OldAlias = a;\n- else static if (__traits(compiles, { enum x = a; }))\n- enum OldAlias = a;\n- else\n- static assert(0, \"Cannot alias \" ~ a.stringof);\n-}\n-\n-package template OldAlias(T)\n-if (!isAggregateType!T || is(Unqual!T == T))\n-{\n- alias OldAlias = T;\n-}\n-\n-@safe unittest\n-{\n- static struct Foo {}\n- //static assert(is(OldAlias!(const(Foo)) == const Foo));\n- static assert(is(OldAlias!(const(int)) == const(int)));\n- static assert(OldAlias!123 == 123);\n- enum abc = 123;\n- static assert(OldAlias!abc == 123);\n-}\n-\n /**\n- * Returns the index of the first occurrence of `args[0]` in the\n- * sequence `args[1 .. $]`. `args` may be types or compile-time values.\n+ * Returns the index of the first occurrence of `A` in the\n+ * sequence `args`. `A` and `args` may be types or compile-time values.\n * If not found, `-1` is returned.\n */\n-template staticIndexOf(args...)\n-if (args.length >= 1)\n+template staticIndexOf(alias A, args...)\n {\n enum staticIndexOf =\n {\n- static foreach (idx, arg; args[1 .. $])\n- static if (isSame!(args[0], arg))\n+ static foreach (idx, arg; args)\n+ static if (isSame!(A, arg))\n // `if (__ctfe)` is redundant here but avoids the \"Unreachable code\" warning.\n if (__ctfe) return idx;\n return -1;\n@@ -269,14 +239,9 @@ if (args.length >= 1)\n ///\n @safe unittest\n {\n- import std.stdio;\n-\n- void foo()\n- {\n- writefln(\"The index of long is %s\",\n- staticIndexOf!(long, AliasSeq!(int, long, double)));\n- // prints: The index of long is 1\n- }\n+ alias Types = AliasSeq!(int, long, double);\n+ static assert(staticIndexOf!(long, Types) == 1);\n+ static assert(staticIndexOf!(void, 0, \"void\", void) == 2);\n }\n \n @safe unittest\n@@ -302,17 +267,16 @@ if (args.length >= 1)\n }\n \n /**\n- * Returns an `AliasSeq` created from `args[1 .. $]` with the first occurrence,\n- * if any, of `args[0]` removed.\n+ * Returns an `AliasSeq` created from `args` with the first occurrence,\n+ * if any, of `A` removed.\n */\n-template Erase(args...)\n-if (args.length >= 1)\n+template Erase(alias A, args...)\n {\n- private enum pos = staticIndexOf!(args[0], args[1 .. $]);\n+ private enum pos = staticIndexOf!(A, args);\n static if (pos < 0)\n- alias Erase = args[1 .. $];\n+ alias Erase = args;\n else\n- alias Erase = AliasSeq!(args[1 .. pos + 1], args[pos + 2 .. $]);\n+ alias Erase = AliasSeq!(args[0 .. pos], args[pos + 1 .. $]);\n }\n \n ///\n@@ -336,15 +300,14 @@ if (args.length >= 1)\n \n \n /**\n- * Returns an `AliasSeq` created from `args[1 .. $]` with all occurrences,\n- * if any, of `args[0]` removed.\n+ * Returns an `AliasSeq` created from `args` with all occurrences,\n+ * if any, of `A` removed.\n */\n-template EraseAll(args...)\n-if (args.length >= 1)\n+template EraseAll(alias A, args...)\n {\n alias EraseAll = AliasSeq!();\n- static foreach (arg; args[1 .. $])\n- static if (!isSame!(args[0], arg))\n+ static foreach (arg; args)\n+ static if (!isSame!(A, arg))\n EraseAll = AliasSeq!(EraseAll, arg);\n }\n \n@@ -431,30 +394,26 @@ template NoDuplicates(args...)\n \n \n /**\n- * Returns an `AliasSeq` created from TList with the first occurrence\n+ * Returns an `AliasSeq` created from `Args` with the first occurrence\n * of T, if found, replaced with U.\n */\n-template Replace(T, U, TList...)\n-{\n- alias Replace = GenericReplace!(T, U, TList).result;\n-}\n-\n-/// Ditto\n-template Replace(alias T, U, TList...)\n+template Replace(alias T, alias U, Args...)\n {\n- alias Replace = GenericReplace!(T, U, TList).result;\n-}\n-\n-/// Ditto\n-template Replace(T, alias U, TList...)\n-{\n- alias Replace = GenericReplace!(T, U, TList).result;\n-}\n+ static if (Args.length)\n+ {\n+ alias head = Args[0 .. 1]; // use unary sequence instead of Alias\n+ alias tail = Args[1 .. $];\n \n-/// Ditto\n-template Replace(alias T, alias U, TList...)\n-{\n- alias Replace = GenericReplace!(T, U, TList).result;\n+ static if (isSame!(T, head))\n+ alias Replace = AliasSeq!(U, tail);\n+ else\n+ alias Replace = AliasSeq!(head,\n+ Replace!(T, U, tail));\n+ }\n+ else\n+ {\n+ alias Replace = AliasSeq!();\n+ }\n }\n \n ///\n@@ -466,31 +425,6 @@ template Replace(alias T, alias U, TList...)\n static assert(is(TL == AliasSeq!(int, char, long, int, float)));\n }\n \n-// [internal]\n-private template GenericReplace(args...)\n-if (args.length >= 2)\n-{\n- alias from = OldAlias!(args[0]);\n- alias to = OldAlias!(args[1]);\n- alias tuple = args[2 .. $];\n-\n- static if (tuple.length)\n- {\n- alias head = OldAlias!(tuple[0]);\n- alias tail = tuple[1 .. $];\n-\n- static if (isSame!(from, head))\n- alias result = AliasSeq!(to, tail);\n- else\n- alias result = AliasSeq!(head,\n- GenericReplace!(from, to, tail).result);\n- }\n- else\n- {\n- alias result = AliasSeq!();\n- }\n- }\n-\n @safe unittest\n {\n static assert(Pack!(Replace!(byte, ubyte,\n@@ -511,16 +445,16 @@ if (args.length >= 2)\n }\n \n /**\n- * Returns an `AliasSeq` created from `args[2 .. $]` with all occurrences\n- * of `args[0]`, if any, replaced with `args[1]`.\n+ * Returns an `AliasSeq` created from `args` with all occurrences\n+ * of T, if found, replaced with U.\n */\n-template ReplaceAll(args...)\n+template ReplaceAll(alias T, alias U, args...)\n {\n alias ReplaceAll = AliasSeq!();\n- static foreach (arg; args[2 .. $])\n+ static foreach (arg; args)\n {\n- static if (isSame!(args[0], arg))\n- ReplaceAll = AliasSeq!(ReplaceAll, args[1]);\n+ static if (isSame!(T, arg))\n+ ReplaceAll = AliasSeq!(ReplaceAll, U);\n else\n ReplaceAll = AliasSeq!(ReplaceAll, arg);\n }\n@@ -1297,10 +1231,9 @@ private template staticMerge(alias cmp, uint mid, items...)\n staticMerge!(cmp, mid - run, items[run .. mid], items[mid + 1 .. $]));\n }\n \n-private template isLessEq(alias cmp, Seq...)\n-if (Seq.length == 2)\n+private template isLessEq(alias cmp, alias A, alias B)\n {\n- private enum Result = cmp!(Seq[1], Seq[0]);\n+ private enum Result = cmp!(B, A);\n static if (is(typeof(Result) == bool))\n enum isLessEq = !Result;\n else static if (is(typeof(Result) : int))\n@@ -1452,11 +1385,6 @@ private template isSame(alias a, alias b)\n enum isSame = __traits(isSame, a, b);\n }\n }\n-// TODO: remove after https://github.com/dlang/dmd/pull/11320 and https://issues.dlang.org/show_bug.cgi?id=21889 are fixed\n-private template isSame(A, B)\n-{\n- enum isSame = is(A == B);\n-}\n \n @safe unittest\n {\ndiff --git a/libphobos/src/std/range/package.d b/libphobos/src/std/range/package.d\nindex 16bf0bf9ee9..3d4ec7a9109 100644\n--- a/libphobos/src/std/range/package.d\n+++ b/libphobos/src/std/range/package.d\n@@ -1807,7 +1807,7 @@ pure @safe nothrow unittest\n /**\n Choose one of two ranges at runtime depending on a Boolean condition.\n \n-The ranges may be different, but they must have compatible element types (i.e.\n+The ranges may have different capabilities, but they must have compatible element types (i.e.\n `CommonType` must exist for the two element types). The result is a range\n that offers the weakest capabilities of the two (e.g. `ForwardRange` if $(D\n R1) is a random-access range and `R2` is a forward range).\n@@ -1914,7 +1914,7 @@ private struct ChooseResult(Ranges...)\n break sw;\n }\n \n- default: assert(false);\n+ default: assert(false, \"index exceeds `Ranges.length`\");\n }\n }\n \n@@ -2280,7 +2280,7 @@ pure @safe nothrow unittest\n /**\n Choose one of multiple ranges at runtime.\n \n-The ranges may be different, but they must have compatible element types. The\n+The ranges may have different capabilities, but they must have compatible element types. The\n result is a range that offers the weakest capabilities of all `Ranges`.\n \n Params:\n@@ -2288,9 +2288,8 @@ Params:\n rs = two or more ranges\n \n Returns:\n- The indexed range. If rs consists of only one range, the return type is an\n- alias of that range's type.\n- */\n+ A range type dependent on `Ranges`.\n+*/\n auto chooseAmong(Ranges...)(size_t index, return scope Ranges rs)\n if (Ranges.length >= 2\n && allSatisfy!(isInputRange, staticMap!(Unqual, Ranges))\n@@ -2306,12 +2305,9 @@ if (Ranges.length >= 2\n {\n import std.algorithm.comparison : equal;\n \n- int[4] sarr1 = [1, 2, 3, 4];\n- int[2] sarr2 = [5, 6];\n- int[1] sarr3 = [7];\n- auto arr1 = sarr1[];\n- auto arr2 = sarr2[];\n- auto arr3 = sarr3[];\n+ scope arr1 = [1, 2, 3, 4];\n+ scope arr2 = [5, 6];\n+ scope arr3 = [7];\n \n {\n auto s = chooseAmong(0, arr1, arr2, arr3);\n@@ -2321,23 +2317,43 @@ if (Ranges.length >= 2\n s.popFront();\n assert(equal(t, only(1, 2, 3, 4)));\n }\n+ // result elements can be modified\n {\n auto s = chooseAmong(1, arr1, arr2, arr3);\n assert(s.length == 2);\n s.front = 8;\n assert(equal(s, only(8, 6)));\n- }\n- {\n- auto s = chooseAmong(1, arr1, arr2, arr3);\n- assert(s.length == 2);\n s[1] = 9;\n assert(equal(s, only(8, 9)));\n+ // original range was mutated\n+ assert(equal(s, arr2));\n }\n+ return 0;\n+ }\n+ // works at runtime\n+ auto a = test();\n+ // and at compile time\n+ static b = test();\n+}\n+\n+/// Result has minimum capabilities of all given ranges\n+@safe nothrow pure @nogc unittest\n+{\n+ auto test()\n+ {\n+ import std.algorithm.comparison : equal;\n+\n+ scope arr1 = [1, 2, 3, 4];\n+ scope arr2 = [8, 9];\n+ scope arr3 = [10];\n+\n+ // slicing\n {\n auto s = chooseAmong(1, arr2, arr1, arr3)[1 .. 3];\n assert(s.length == 2);\n assert(equal(s, only(2, 3)));\n }\n+ // bidirectional\n {\n auto s = chooseAmong(0, arr1, arr2, arr3);\n assert(s.length == 4);\n@@ -2348,6 +2364,7 @@ if (Ranges.length >= 2\n s.back = 3;\n assert(equal(s, only(1, 2, 3)));\n }\n+ // range primitives\n {\n uint[5] foo = [1, 2, 3, 4, 5];\n uint[5] bar = [6, 7, 8, 9, 10];\n@@ -2359,6 +2376,7 @@ if (Ranges.length >= 2\n assert(c.moveBack() == 10);\n assert(c.moveAt(4) == 10);\n }\n+ // composability\n {\n import std.range : cycle;\n auto s = chooseAmong(0, cycle(arr2), cycle(arr3));\ndiff --git a/libphobos/src/std/regex/internal/backtracking.d b/libphobos/src/std/regex/internal/backtracking.d\nindex 605ec03c481..9d3c1034244 100644\n--- a/libphobos/src/std/regex/internal/backtracking.d\n+++ b/libphobos/src/std/regex/internal/backtracking.d\n@@ -657,9 +657,10 @@ final:\n break;\n case IR.Backref:\n immutable n = re.ir[pc].data;\n- auto referenced = re.ir[pc].localRef\n- ? s[matches[n].begin .. matches[n].end]\n- : s[backrefed[n].begin .. backrefed[n].end];\n+ auto g = re.ir[pc].localRef ? matches[n] : backrefed[n];\n+ if (!g)\n+ goto L_backtrack;\n+ auto referenced = s[g.begin .. g.end];\n while (!atEnd && !referenced.empty && front == referenced.front)\n {\n next();\n@@ -1430,14 +1431,13 @@ struct CtContext\n $$`, ir[0].data, nextInstr);\n break;\n case IR.Backref:\n- string mStr = \"auto referenced = \";\n- mStr ~= ir[0].localRef\n- ? ctSub(\"s[matches[$$].begin .. matches[$$].end];\",\n- ir[0].data, ir[0].data)\n- : ctSub(\"s[backrefed[$$].begin .. backrefed[$$].end];\",\n- ir[0].data, ir[0].data);\n+ string gStr = ir[0].localRef\n+ ? ctSub(\"matches[$$]\", ir[0].data)\n+ : ctSub(\"backrefed[$$]\", ir[0].data);\n code ~= ctSub( `\n- $$\n+ if (!$$)\n+ $$\n+ auto referenced = s[$$.begin .. $$.end];\n while (!atEnd && !referenced.empty && front == referenced.front)\n {\n next();\n@@ -1446,7 +1446,7 @@ struct CtContext\n if (referenced.empty)\n $$\n else\n- $$`, mStr, nextInstr, bailOut);\n+ $$`, gStr, bailOut, gStr, gStr, nextInstr, bailOut);\n break;\n case IR.Nop:\n case IR.End:\ndiff --git a/libphobos/src/std/regex/internal/tests.d b/libphobos/src/std/regex/internal/tests.d\nindex 8a0fec16a1b..6b739050d85 100644\n--- a/libphobos/src/std/regex/internal/tests.d\n+++ b/libphobos/src/std/regex/internal/tests.d\n@@ -70,6 +70,10 @@ debug(std_regex_test) import std.stdio;\n TestVectors( \"a\\\\b\", \"a\", \"y\", \"$&\", \"a\" ),\n TestVectors( \"(a)b\\\\1\", \"abaab\",\"y\", \"$&\", \"aba\" ),\n TestVectors( \"()b\\\\1\", \"aaab\", \"y\", \"$&\", \"b\" ),\n+ TestVectors( \"(a)?\\\\1\", \"aa\", \"y\", \"$&\", \"aa\" ),\n+ TestVectors( \"(a)?\\\\1\", \"xaa\", \"y\", \"$&\", \"aa\" ),\n+ TestVectors( \"(a)?b\\\\1\", \"aba\", \"y\", \"$&\", \"aba\" ),\n+ TestVectors( \"(a)?b\\\\1\", \"b\", \"n\", \"-\", \"-\" ),\n TestVectors( \"abc\", \"abc\", \"y\", \"$&\", \"abc\" ),\n TestVectors( \"abc\", \"xbc\", \"n\", \"-\", \"-\" ),\n TestVectors( \"abc\", \"axc\", \"n\", \"-\", \"-\" ),\ndiff --git a/libphobos/src/std/regex/internal/thompson.d b/libphobos/src/std/regex/internal/thompson.d\nindex 195625f15ea..23bb3e91cd6 100644\n--- a/libphobos/src/std/regex/internal/thompson.d\n+++ b/libphobos/src/std/regex/internal/thompson.d\n@@ -476,7 +476,13 @@ template ThompsonOps(E, S, bool withInput:true)\n uint n = re.ir[t.pc].data;\n Group!DataIndex* source = re.ir[t.pc].localRef ? t.matches.ptr : backrefed.ptr;\n assert(source);\n- if (source[n].begin == source[n].end)//zero-width Backref!\n+ if (!source[n]) // unmatched group\n+ {\n+ recycle(t);\n+ t = worklist.fetch();\n+ return t != null;\n+ }\n+ if (source[n].begin == source[n].end) // zero-width match\n {\n t.pc += IRL!(IR.Backref);\n return true;\n@@ -681,7 +687,7 @@ template ThompsonOps(E,S, bool withInput:false)\n return state.popState(e);\n }\n \n- // special case of zero-width backref\n+ // special case of zero-width or unmatched backref\n static bool op(IR code:IR.Backref)(E e, S* state)\n {\n with(e) with(state)\n@@ -689,7 +695,9 @@ template ThompsonOps(E,S, bool withInput:false)\n uint n = re.ir[t.pc].data;\n Group!DataIndex* source = re.ir[t.pc].localRef ? t.matches.ptr : backrefed.ptr;\n assert(source);\n- if (source[n].begin == source[n].end)//zero-width Backref!\n+ if (!source[n]) // unmatched group\n+ return popState(e);\n+ if (source[n].begin == source[n].end) // zero-width match\n {\n t.pc += IRL!(IR.Backref);\n return true;\ndiff --git a/libphobos/src/std/socket.d b/libphobos/src/std/socket.d\nindex e48bf565971..8f29c78f59f 100644\n--- a/libphobos/src/std/socket.d\n+++ b/libphobos/src/std/socket.d\n@@ -2966,6 +2966,43 @@ public:\n return newSocket;\n }\n \n+ /**\n+ * Accept an incoming connection and retrieve the peer `Address`. If the\n+ * socket is blocking, `accept` waits for a connection request. Throws\n+ * `SocketAcceptException` if unable to _accept. See `accepting` for use\n+ * with derived classes.\n+ */\n+ Socket accept(out Address peerAddress) @trusted\n+ {\n+ Address addr = createAddress();\n+ socklen_t nameLen = addr.nameLen;\n+ auto newsock = cast(socket_t).accept(sock, addr.name, &nameLen);\n+ if (socket_t.init == newsock)\n+ throw new SocketAcceptException(\"Unable to accept socket connection\");\n+\n+ addr.setNameLen(nameLen);\n+ peerAddress = addr;\n+\n+ Socket newSocket;\n+ try\n+ {\n+ newSocket = accepting();\n+ assert(newSocket.sock == socket_t.init);\n+\n+ newSocket.setSock(newsock);\n+ version (Windows)\n+ newSocket._blocking = _blocking; //inherits blocking mode\n+ newSocket._family = _family; //same family\n+ }\n+ catch (Throwable o)\n+ {\n+ _close(newsock);\n+ throw o;\n+ }\n+\n+ return newSocket;\n+ }\n+\n /// Disables sends and/or receives.\n void shutdown(SocketShutdown how) @trusted nothrow @nogc\n {\n@@ -3687,6 +3724,10 @@ class UdpSocket: Socket\n {\n checkAttributes!q{@trusted}; assert(0);\n }\n+ @trusted Socket accept(out Address peerAddress)\n+ {\n+ checkAttributes!q{@trusted}; assert(0);\n+ }\n nothrow @nogc @trusted void shutdown(SocketShutdown how)\n {\n checkAttributes!q{nothrow @nogc @trusted};\n@@ -3859,3 +3900,26 @@ Socket[2] socketPair() @trusted\n pair[1].receive(buf);\n assert(buf == data);\n }\n+\n+// Test accept with peer address\n+@safe unittest\n+{\n+ auto listener = new TcpSocket();\n+ scope(exit) listener.close();\n+ listener.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, true);\n+ listener.bind(new InternetAddress(INADDR_LOOPBACK, InternetAddress.PORT_ANY));\n+ auto serverAddr = listener.localAddress;\n+ listener.listen(1);\n+\n+ auto client = new TcpSocket(serverAddr);\n+ scope(exit) client.close();\n+\n+ Address peerAddress;\n+ auto server = listener.accept(peerAddress);\n+ scope(exit) server.close();\n+\n+ assert(peerAddress !is null);\n+ assert(peerAddress.addressFamily == AddressFamily.INET);\n+ // The peer address should match the client's local address\n+ assert(peerAddress.toAddrString() == client.localAddress.toAddrString());\n+}\ndiff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d\nindex 5138efa5fa7..a2039006c8b 100644\n--- a/libphobos/src/std/typecons.d\n+++ b/libphobos/src/std/typecons.d\n@@ -3683,6 +3683,83 @@ struct Nullable(T)\n \n private bool _isNull = true;\n \n+ /**\n+ * Compares two Nullable values.\n+ *\n+ * - If one is null and the other is not, the null one is considered smaller.\n+ * - If both are null, they are equal.\n+ * - If both are non-null, compares the payloads.\n+ *\n+ * Returns:\n+ * Negative if `this < rhs`, zero if equal, positive if `this > rhs`.\n+ */\n+ int opCmp(this This, Rhs)(auto ref Rhs rhs)\n+ if (is(Rhs == Nullable!U, U) && is(typeof(this.get < rhs.get)))\n+ {\n+ if (_isNull)\n+ return rhs.isNull ? 0 : -1;\n+ else if (rhs.isNull)\n+ return 1;\n+ else if (_value.payload < rhs.get)\n+ return -1;\n+ else if (_value.payload > rhs.get)\n+ return 1;\n+ else\n+ return 0;\n+ }\n+\n+ /// Basic `Nullable` comparison test\n+ @safe unittest\n+ {\n+ Nullable!int a = 5;\n+ Nullable!int b = 0;\n+ assert(a > b);\n+ assert(b < a);\n+\n+ Nullable!int c;\n+ assert(c < a);\n+ assert(c < b);\n+ }\n+\n+ // Not suitable for documentation.\n+ @safe unittest\n+ {\n+ Nullable!int a = 5;\n+ Nullable!int b = 0;\n+ Nullable!int c;\n+ assert(a.opCmp(a) == 0); // Do not use `opEquals`, i.e. no `a == a`.\n+ assert(b.opCmp(b) == 0);\n+ assert(c.opCmp(c) == 0);\n+ assert(b.opCmp(c) != 0);\n+ }\n+\n+ // Advanced `Nullable` comparison test\n+ @safe unittest\n+ {\n+ Nullable!int a = 5;\n+ Nullable!byte b = 0;\n+\n+ assert(a > b);\n+ assert(b < a);\n+ assert(a.opCmp(a) == 0);\n+ assert(b.opCmp(b) == 0);\n+\n+ Nullable!float f = 2;\n+ assert(a > f);\n+ assert(b < f);\n+ assert(f.opCmp(f) == 0);\n+\n+ Nullable!short s = 5;\n+ assert(a == s);\n+\n+ a.nullify();\n+ assert(a.opCmp(s) != 0);\n+ assert(a < b);\n+\n+ b.nullify();\n+ assert(a.opCmp(b) == 0);\n+ }\n+\n /**\n * Constructor initializing `this` with `value`.\n *\n@@ -11239,6 +11316,32 @@ unittest\n assert(s.get().i == 2);\n }\n \n+/*\n+ `Nullable` comparison with a user-defined type whose `opCmp` is not `const`\n+\n+ This tests for the following pitfall:\n+ template `opCmp` is not callable using argument types `!()(Nullable!(NonConstOpCmp))`\n+ This test cannot embedded into `Nullable` because of the following issue:\n+ template instance `core.internal.traits._hasIndirections!(NonConstOpCmp)` recursive expansion\n+ */\n+@safe unittest\n+{\n+ static struct NonConstOpCmp\n+ {\n+ int value;\n+\n+ // non-const on purpose!\n+ int opCmp(NonConstOpCmp b) => (this.value > b.value) - (this.value < b.value);\n+ }\n+\n+ auto a = nullable(NonConstOpCmp(0));\n+ auto b = nullable(NonConstOpCmp(1));\n+ assert(a < b);\n+\n+ Nullable!NonConstOpCmp c;\n+ assert(c < a);\n+}\n+\n /// The old version of $(LREF SafeRefCounted), before $(LREF borrow) existed.\n /// Old code may be relying on `@safe`ty of some of the member functions which\n /// cannot be safe in the new scheme, and\ndiff --git a/libphobos/src/std/variant.d b/libphobos/src/std/variant.d\nindex a094aeb3409..1760f5fd694 100644\n--- a/libphobos/src/std/variant.d\n+++ b/libphobos/src/std/variant.d\n@@ -144,6 +144,13 @@ if (isTypeTuple!U)\n enum maxVariantAlignment = maxAlignment!(U);\n }\n \n+// Each internal operation is encoded with an identifier. See\n+// the \"handler\" function below.\n+private enum OpID { getTypeInfo, get, compare, equals, testConversion, toString,\n+ index, indexAssign, catAssign, copyOut, length,\n+ apply, postblit, destruct }\n+\n+\n /**\n * Back-end type seldom used directly by user\n * code. Two commonly-used types using `VariantN` are:\n@@ -179,6 +186,7 @@ struct VariantN(size_t maxDataSize, AllowedTypesParam...)\n alias AllowedTypes = This2Variant!(VariantN, AllowedTypesParam);\n \n private:\n+\n // Compute the largest practical size from maxDataSize\n struct SizeChecker\n {\n@@ -200,11 +208,11 @@ private:\n (AllowedTypes.length == 0 || staticIndexOf!(T, AllowedTypes) >= 0);\n }\n \n- // Each internal operation is encoded with an identifier. See\n- // the \"handler\" function below.\n- enum OpID { getTypeInfo, get, compare, equals, testConversion, toString,\n- index, indexAssign, catAssign, copyOut, length,\n- apply, postblit, destruct }\n+ enum biggerThanSize(alias T) = T.sizeof > size;\n+ enum needsPostblit = !AllowedTypes.length\n+ || anySatisfy!(hasElaborateCopyConstructor, AllowedTypes)\n+ // if bigger than size, its stored by ref and needs to be copied\n+ || anySatisfy!(biggerThanSize, AllowedTypes);\n \n // state\n union\n@@ -420,7 +428,8 @@ private:\n }\n else\n {\n- A* p = new A;\n+ // object will be intialized later. Using ubyte buffer in case `this()` is disabled\n+ A* p = cast(A*) (new ubyte[A.sizeof]).ptr;\n }\n *cast(A**)&target.store = p;\n }\n@@ -517,6 +526,24 @@ private:\n *result = (*zis)[index];\n break;\n }\n+ else static if (isInstanceOf!(Tuple, A))\n+ {\n+ size_t index = result.convertsTo!(int)\n+ ? result.get!(int) : result.get!(size_t);\n+switchStmtTupIndex:\n+ switch (index)\n+ {\n+ static foreach (i; 0 .. A.length)\n+ {\n+ case i:\n+ *result = (*zis)[i];\n+ break switchStmtTupIndex;\n+ }\n+ default:\n+ throw new VariantException(\"Tuple index out of range\");\n+ }\n+ break;\n+ }\n else static if (isAssociativeArray!(A))\n {\n *result = (*zis)[result.get!(typeof(A.init.keys[0]))];\n@@ -537,6 +564,24 @@ private:\n (*zis)[index] = args[0].get!(typeof((*zis)[0]));\n break;\n }\n+ else static if (isInstanceOf!(Tuple, A))\n+ {\n+ size_t index = args[1].convertsTo!(int)\n+ ? args[1].get!(int) : args[1].get!(size_t);\n+switchStmtTupAssign:\n+ switch (index)\n+ {\n+ static foreach (i; 0 .. A.length)\n+ {\n+ case i:\n+ (*zis)[i] = args[0].get!(typeof((*zis)[i]));\n+ break switchStmtTupAssign;\n+ }\n+ default:\n+ throw new VariantException(\"Tuple index out of range\");\n+ }\n+ break;\n+ }\n else static if (isAssociativeArray!(A) && is(typeof((*zis)[A.init.keys[0]] = A.init.values[0])))\n {\n (*zis)[args[1].get!(typeof(A.init.keys[0]))]\n@@ -625,12 +670,30 @@ private:\n }\n break;\n \n- case OpID.postblit:\n- static if (hasElaborateCopyConstructor!A)\n+ static if (needsPostblit)\n {\n- zis.__xpostblit();\n+ case OpID.postblit:\n+ if (A.sizeof > size)\n+ {\n+ import core.lifetime : copyEmplace;\n+ static if (is(A == U[n], U, size_t n))\n+ auto p = cast(A*) (new U[n]).ptr;\n+ else\n+ // object will be intialized later. Using ubyte buffer in case `this()` is disabled\n+ A* p = cast(A*) (new ubyte[A.sizeof]).ptr;\n+ // Emplace will run the postblit of `A` us, no need to do it manually, then\n+ copyEmplace(*zis, *p);\n+ *(cast(A**) pStore) = p;\n+ }\n+ else\n+ {\n+ static if (hasElaborateCopyConstructor!A)\n+ {\n+ zis.__xpostblit();\n+ }\n+ }\n+ break;\n }\n- break;\n \n case OpID.destruct:\n static if (hasElaborateDestructor!A)\n@@ -663,7 +726,10 @@ public:\n opAssign(value);\n }\n \n- static if (!AllowedTypes.length || anySatisfy!(hasElaborateCopyConstructor, AllowedTypes))\n+ /** If a type is bigger than size, it is saved via pointer on the heap.\n+ * This means we must copy it in the postblit to preserve value semantics\n+ */\n+ static if (needsPostblit)\n {\n this(this)\n {\n@@ -721,9 +787,10 @@ public:\n else\n {\n static if (is(T == U[n], U, size_t n))\n- auto p = cast(T*) (new U[n]).ptr;\n+ T* p = cast(T*) (new U[n]).ptr;\n else\n- auto p = new T;\n+ // object will be intialized later. Using ubyte buffer in case `this()` is disabled\n+ T* p = cast(T*) (new ubyte[T.sizeof]).ptr;\n copyEmplace(rhs, *p);\n *(cast(T**) &store) = p;\n }\n@@ -3303,3 +3370,105 @@ if (isAlgebraic!VariantType && Handler.length > 0)\n assert(variant[\"huge\"] == Variant(h));\n +/\n }\n+\n+// https://github.com/dlang/phobos/issues/10429\n+@system unittest\n+{\n+ Variant test = tuple(1,2);\n+ assert(test[0] == 1);\n+ test[1] = 10;\n+ assert(test[1] == 10);\n+}\n+\n+// https://github.com/dlang/phobos/issues/10062\n+// https://github.com/dlang/phobos/issues/9783\n+@system\n+unittest\n+{\n+ static struct S(size_t padding, bool withPostblit)\n+ {\n+ int* p;\n+ ubyte[padding] _;\n+\n+ this(int* a)\n+ {\n+ p = a;\n+ }\n+\n+ static if (withPostblit)\n+ {\n+ this(this)\n+ {\n+ p = new int(*p);\n+ }\n+\n+ // Running destructor without postblit makes no sense, as all copies of the struct have a pointer to the same memory location\n+ ~this()\n+ {\n+ // We can't assume that destructor runs exactly once, sometimes the GC will also run it\n+ // assert(*p != 42);\n+ *p = 42;\n+ }\n+ }\n+ }\n+\n+ static void testPostblit(T)()\n+ {\n+ alias V = VariantN!(32, T);\n+ int buf = 1;\n+ auto v = V(T(&buf));\n+ {\n+ // Copy v: Must run postblit of Variant AND T\n+ V v2 = v;\n+ *(v2.peek!T.p) = 2;\n+ assert(v.peek!T.p !is null);\n+ assert(*(v.peek!T.p) == 1);\n+ }\n+ // Verify that destructor ran\n+ assert(buf == 42);\n+ }\n+\n+ static void testValueSemantics(alias S, ulong size, bool withPostblit)()\n+ {\n+ alias T = S!(size, withPostblit);\n+ alias V = VariantN!(32, T);\n+ assert(__traits(hasPostblit, V) == (withPostblit || (size > 32)));\n+ int buf = 1;\n+ auto v = V(T(&buf));\n+ {\n+ int buf2 = 2;\n+ // copy: We care that at least postblit of Variant run. Thus we change the *pointer*, not the int pointed to it here\n+ V v2 = v;\n+ v2.peek!T.p = &buf;\n+ assert(v.peek!T.p !is null);\n+ assert(v.peek!T.p != &buf2);\n+ assert(*(v.peek!T.p) == 1);\n+ }\n+ }\n+\n+ testPostblit!(S!(1, true)); // S!1 fits in the `store`. This already used to work before this bugfix\n+ testPostblit!(S!(100, true)); // S!100 object will be put on the heap and is special case\n+\n+ // OpID.postblit has different handling for big (heap) and small payloads as well as whether these have a postblit or not, so just cover all cases to be sure\n+ static foreach (size; AliasSeq!(1,100))\n+ static foreach (withPostblit; AliasSeq!(false, true))\n+ testValueSemantics!(S, size, withPostblit);\n+}\n+\n+@system\n+unittest\n+{\n+ static struct S\n+ {\n+ int i;\n+ ubyte[100] padding; // Variant must heap allocate this\n+ @disable this();\n+ this(int i)\n+ {\n+ this.i = i;\n+ }\n+ }\n+\n+ VariantN!32 v = VariantN!32(S(10));\n+ v = VariantN!32(S(9));\n+}\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_algorithm_comparison.d b/libphobos/testsuite/libphobos.phobos/std_algorithm_comparison.d\nindex 800694039a0..147a459e8a7 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_algorithm_comparison.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_algorithm_comparison.d\n@@ -31,8 +31,7 @@\n class A\n {\n int a;\n- this(int a) {this.a = a;}\n- @property int i() { return a; }\n+ this(int a) { this.a = a; }\n }\n interface I { }\n class B : I { }\n@@ -57,19 +56,30 @@\n {\n import std.algorithm.comparison;\n \n+ import core.exception : SwitchError;\n import std.exception : assertThrown;\n \n class A { }\n class B { }\n- // Void handlers are allowed if they throw:\n+\n+ // B's handler never returns, so `i` does not need a value\n+ int i;\n assertThrown!Exception(\n- new B().castSwitch!(\n+ i = new B().castSwitch!(\n+ (A a) => 1,\n+ (B b) { throw new Exception(\"B is not allowed!\"); }\n+ )()\n+ );\n+\n+ // Void handler call will throw if another handler returns a value\n+ assertThrown!SwitchError(\n+ i = new B().castSwitch!(\n (A a) => 1,\n- (B d) { throw new Exception(\"B is not allowed!\"); }\n+ (B b) {}\n )()\n );\n \n- // Void handlers are also allowed if all the handlers are void:\n+ // Void handlers are allowed if all the handlers convert to void:\n new A().castSwitch!(\n (A a) { },\n (B b) { assert(false); },\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_algorithm_iteration.d b/libphobos/testsuite/libphobos.phobos/std_algorithm_iteration.d\nindex a4f74fb9394..da926c0cddf 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_algorithm_iteration.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_algorithm_iteration.d\n@@ -60,6 +60,40 @@\n assert(i == 3); //cache has accessed 3. It is still stored internally by cache.\n }\n \n+@safe unittest\n+{\n+ import std.algorithm.iteration;\n+\n+ import std.algorithm.comparison : equal;\n+ import std.range, std.stdio;\n+ import std.typecons : tuple;\n+\n+ ulong counter = 0;\n+ double fun(int x)\n+ {\n+ ++counter;\n+ // http://en.wikipedia.org/wiki/Quartic_function\n+ return ( (x + 4.0) * (x + 1.0) * (x - 1.0) * (x - 3.0) ) / 14.0 + 0.5;\n+ }\n+ // With lazyCache, front won't be evaluated until requested\n+ counter = 0;\n+ auto result = iota(-4, 5).map!(a => tuple(a, fun(a)))()\n+ .lazyCache();\n+ // At this point, no elements have been evaluated yet\n+ assert(counter == 0);\n+ // Now access the first element\n+ auto firstElement = result.front;\n+ // Only now the first element is evaluated\n+ assert(counter == 1);\n+ // Process the result lazily\n+ auto filtered = result.filter!(a => a[1] < 0)()\n+ .map!(a => a[0])();\n+ // Values are calculated as we iterate\n+ assert(equal(filtered, [-3, -2, 2]));\n+ // Only elements we actually accessed were evaluated\n+ assert(counter == iota(-4, 5).length);\n+}\n+\n @safe @nogc unittest\n {\n import std.algorithm.iteration;\n@@ -764,30 +798,6 @@ nothrow pure @safe unittest\n .equal([ [[0]], [[1]], [[2]] ]));\n }\n \n-@safe unittest\n-{\n- import std.algorithm.iteration;\n-\n- import std.algorithm.comparison : equal;\n- import std.range.primitives : front;\n-\n- assert(equal(splitter!(a => a == '|')(\"a|bc|def\"), [ \"a\", \"bc\", \"def\" ]));\n- assert(equal(splitter!(a => a == ' ')(\"hello world\"), [ \"hello\", \"\", \"world\" ]));\n-\n- int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];\n- int[][] w = [ [1, 2], [], [3], [4, 5], [] ];\n- assert(equal(splitter!(a => a == 0)(a), w));\n-\n- a = [ 0 ];\n- assert(equal(splitter!(a => a == 0)(a), [ (int[]).init, (int[]).init ]));\n-\n- a = [ 0, 1 ];\n- assert(equal(splitter!(a => a == 0)(a), [ [], [1] ]));\n-\n- w = [ [0], [1], [2] ];\n- assert(equal(splitter!(a => a.front == 1)(w), [ [[0]], [[2]] ]));\n-}\n-\n @safe unittest\n {\n import std.algorithm.iteration;\n@@ -839,8 +849,32 @@ nothrow pure @safe unittest\n import std.algorithm.comparison : equal;\n import std.algorithm.iteration : splitter;\n \n- string str = \"Hello World!\";\n- assert(str.splitter!(isWhite).equal([\"Hello\", \"World!\"]));\n+ string str = \"Hello World\\t!\";\n+ assert(str.splitter!(isWhite).equal([\"Hello\", \"World\", \"!\"]));\n+}\n+\n+@safe unittest\n+{\n+ import std.algorithm.iteration;\n+\n+ import std.algorithm.comparison : equal;\n+ import std.range.primitives : front;\n+\n+ assert(equal(splitter!(a => a == '|')(\"a|bc|def\"), [ \"a\", \"bc\", \"def\" ]));\n+ assert(equal(splitter!(a => a == ' ')(\"hello world\"), [ \"hello\", \"\", \"world\" ]));\n+\n+ int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];\n+ int[][] w = [ [1, 2], [], [3], [4, 5], [] ];\n+ assert(equal(splitter!(a => a == 0)(a), w));\n+\n+ a = [ 0 ];\n+ assert(equal(splitter!(a => a == 0)(a), [ (int[]).init, (int[]).init ]));\n+\n+ a = [ 0, 1 ];\n+ assert(equal(splitter!(a => a == 0)(a), [ [], [1] ]));\n+\n+ w = [ [0], [1], [2] ];\n+ assert(equal(splitter!(a => a.front == 1)(w), [ [[0]], [[2]] ]));\n }\n \n @safe pure unittest\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_algorithm_searching.d b/libphobos/testsuite/libphobos.phobos/std_algorithm_searching.d\nindex fd09d0abcd4..468e8c04a98 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_algorithm_searching.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_algorithm_searching.d\n@@ -123,19 +123,30 @@\n assert(countUntil(\"日本語\", '語') == 2);\n assert(countUntil(\"日本語\", \"五\") == -1);\n assert(countUntil(\"日本語\", '五') == -1);\n- assert(countUntil([0, 7, 12, 22, 9], [12, 22]) == 2);\n- assert(countUntil([0, 7, 12, 22, 9], 9) == 4);\n- assert(countUntil!\"a > b\"([0, 7, 12, 22, 9], 20) == 3);\n \n- // supports multiple needles\n+ const arr = [0, 7, 12, 22, 9];\n+ assert(countUntil(arr, [12, 22]) == 2);\n+ assert(countUntil(arr, 9) == 4);\n+ assert(countUntil!\"a > b\"(arr, 20) == 3);\n+}\n+\n+@safe unittest\n+{\n+ import std.algorithm.searching;\n+\n auto res = \"...hello\".countUntil(\"ha\", \"he\");\n assert(res.steps == 3);\n- assert(res.needle == 1);\n+ assert(res.needle == 1); // the 2nd needle matched\n \n // returns -1 if no needle was found\n res = \"hello\".countUntil(\"ha\", \"hu\");\n assert(res.steps == -1);\n assert(res.needle == -1);\n+\n+ // `steps` can also be implicitly compared\n+ const arr = [0, 7, 12, 22, 9];\n+ assert(countUntil(arr, 22, 12) == 2); // `12` found after 2 elements\n+ assert(countUntil(arr, 5, 6) == -1);\n }\n \n @safe unittest\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_array.d b/libphobos/testsuite/libphobos.phobos/std_array.d\nindex 87ea0f0c447..b74b19a3e92 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_array.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_array.d\n@@ -27,25 +27,29 @@\n static assert(isRandomAccessRange!dstring == true);\n }\n \n-@safe pure unittest\n+@safe pure nothrow unittest\n {\n import std.array;\n \n- import std.range : repeat, zip;\n import std.typecons : tuple;\n- import std.range.primitives : autodecodeStrings;\n- auto a = assocArray(zip([0, 1, 2], [\"a\", \"b\", \"c\"])); // aka zipMap\n- static assert(is(typeof(a) == string[int]));\n- assert(a == [0:\"a\", 1:\"b\", 2:\"c\"]);\n \n auto b = assocArray([ tuple(\"foo\", \"bar\"), tuple(\"baz\", \"quux\") ]);\n static assert(is(typeof(b) == string[string]));\n assert(b == [\"foo\":\"bar\", \"baz\":\"quux\"]);\n+}\n+\n+@safe pure nothrow unittest\n+{\n+ import std.array;\n+\n+ import std.range.primitives : autodecodeStrings;\n+ import std.range : repeat;\n \n static if (autodecodeStrings)\n alias achar = dchar;\n else\n alias achar = immutable(char);\n+\n auto c = assocArray(\"ABCD\", true.repeat);\n static assert(is(typeof(c) == bool[achar]));\n bool[achar] expected = ['D':true, 'A':true, 'B':true, 'C':true];\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_concurrency.d b/libphobos/testsuite/libphobos.phobos/std_concurrency.d\nindex 46da87d47af..dca171d34e9 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_concurrency.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_concurrency.d\n@@ -138,6 +138,23 @@\n send(tid, 0.5, Record(\"Alice\", 31));\n }\n \n+@system unittest\n+{\n+ import std.concurrency;\n+\n+ import core.time : msecs;\n+ import core.thread : Thread;\n+\n+ auto tid = spawn((int x) {\n+ Thread.sleep(10.msecs);\n+ ownerTid.send(x * 2);\n+ }, 21);\n+\n+ join(tid); // Wait for thread to finish\n+ auto result = receiveOnly!int();\n+ assert(result == 42);\n+}\n+\n @system unittest\n {\n import std.concurrency;\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_conv.d b/libphobos/testsuite/libphobos.phobos/std_conv.d\nindex 5e9636be9eb..6b30efbe03c 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_conv.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_conv.d\n@@ -394,6 +394,31 @@\n assert(dtext(42, ' ', 1.5, \": xyz\") == \"42 1.5: xyz\"d);\n }\n \n+@safe unittest\n+{\n+ import std.conv;\n+\n+ import std.array : appender;\n+\n+ auto output = appender!string();\n+ output.writeText(\"The answer is \", 42);\n+\n+ assert(output.data == \"The answer is 42\");\n+}\n+\n+@safe unittest\n+{\n+ import std.conv;\n+\n+ import std.array : appender;\n+\n+ const color = \"red\";\n+ auto output = appender!string();\n+ output.writeText(i\"My favorite color is $(color)\");\n+\n+ assert(output.data == \"My favorite color is red\");\n+}\n+\n @safe unittest\n {\n import std.conv;\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_datetime_date.d b/libphobos/testsuite/libphobos.phobos/std_datetime_date.d\nindex 0ecf625562a..ca4e819064c 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_datetime_date.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_datetime_date.d\n@@ -158,6 +158,9 @@\n \n assert(DateTime(2016, 1, 1, 0, 59, 59) - hours(1) ==\n DateTime(2015, 12, 31, 23, 59, 59));\n+\n+ assert(DateTime(2015, 12, 31, 23, 59, 59) + hours(1) ==\n+ hours(1) + DateTime(2015, 12, 31, 23, 59, 59));\n \n }\n \n@@ -555,6 +558,8 @@\n \n assert(Date(2016, 1, 1) - days(1) == Date(2015, 12, 31));\n assert(Date(2004, 3, 1) - days(4) == Date(2004, 2, 26));\n+\n+ assert(Date(2004, 2, 26) + days(4) == days(4) + Date(2004, 2, 26));\n \n }\n \n@@ -797,6 +802,8 @@\n assert(TimeOfDay(12, 12, 12) - minutes(1) == TimeOfDay(12, 11, 12));\n assert(TimeOfDay(12, 12, 12) - hours(1) == TimeOfDay(11, 12, 12));\n assert(TimeOfDay(0, 0, 0) - seconds(1) == TimeOfDay(23, 59, 59));\n+\n+ assert(TimeOfDay(12, 12, 12) + seconds(1) == seconds(1) + TimeOfDay(12, 12, 12));\n \n }\n \ndiff --git a/libphobos/testsuite/libphobos.phobos/std_datetime_systime.d b/libphobos/testsuite/libphobos.phobos/std_datetime_systime.d\nindex a0f410374d6..b98b6866b23 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_datetime_systime.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_datetime_systime.d\n@@ -295,6 +295,9 @@\n \n assert(SysTime(DateTime(2016, 1, 1, 0, 59, 59)) - hours(1) ==\n SysTime(DateTime(2015, 12, 31, 23, 59, 59)));\n+\n+ assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + seconds(1) ==\n+ seconds(1) + SysTime(DateTime(2015, 12, 31, 23, 59, 59)));\n \n }\n \ndiff --git a/libphobos/testsuite/libphobos.phobos/std_internal_entropy.d b/libphobos/testsuite/libphobos.phobos/std_internal_entropy.d\nnew file mode 100644\nindex 00000000000..505785b7cd3\n--- /dev/null\n+++ b/libphobos/testsuite/libphobos.phobos/std_internal_entropy.d\n@@ -0,0 +1,82 @@\n+@safe unittest\n+{\n+ import std.internal.entropy;\n+\n+ int[4] bytes;\n+ if (getEntropy(cast(void[]) bytes).isOK)\n+ {\n+ // Success; data in `bytes` may be used.\n+ }\n+\n+ assert((cast(void[]) bytes).length == bytes.sizeof);\n+}\n+\n+@safe unittest\n+{\n+ import std.internal.entropy;\n+\n+ ubyte[16] bytes;\n+ if (getEntropy(bytes).isOK)\n+ {\n+ // Success; data in `bytes` may be used.\n+ }\n+}\n+\n+@system unittest\n+{\n+ import std.internal.entropy;\n+\n+ ubyte[16] bytes;\n+ if (getEntropy(cast(void*) bytes.ptr, bytes.length).isOK)\n+ {\n+ // Success; data in `bytes` may be used.\n+ }\n+}\n+\n+@system unittest\n+{\n+ import std.internal.entropy;\n+\n+ int number = void;\n+ if (getEntropy(&number, number.sizeof).isOK)\n+ {\n+ // Success; value of `number` may be used.\n+ }\n+}\n+\n+@system unittest\n+{\n+ import std.internal.entropy;\n+\n+ ubyte[4] bytes;\n+\n+ // `EntropySource.none` always fails.\n+ assert(!getEntropy(bytes.ptr, bytes.length, EntropySource.none).isOK);\n+}\n+\n+@safe unittest\n+{\n+ import std.internal.entropy;\n+\n+ ubyte[4] data;\n+ EntropyResult result = getEntropy(data[]);\n+\n+ if (result.isOK)\n+ {\n+ // Success; data in `bytes` may be used.\n+ }\n+ else\n+ {\n+ // Failure\n+\n+ if (result.isUnavailable)\n+ {\n+ // System’s entropy source was unavailable.\n+ }\n+\n+ // Call `toString` to obtain a user-readable error message.\n+ assert(result.toString() !is null);\n+ assert(result.toString().length > 0);\n+ }\n+}\n+\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_math_algebraic.d b/libphobos/testsuite/libphobos.phobos/std_math_algebraic.d\nindex 7b20a13ca26..bee4fc93ec4 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_math_algebraic.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_math_algebraic.d\n@@ -46,7 +46,7 @@\n assert(isNaN(sqrt(-1.0L)));\n }\n \n-@safe unittest\n+@safe pure unittest\n {\n import std.math.algebraic;\n \n@@ -62,11 +62,16 @@\n import std.math.algebraic;\n \n import std.math.operations : feqrel;\n+ import std.math.traits : isNaN;\n \n assert(hypot(1.0, 1.0).feqrel(1.4142) > 16);\n assert(hypot(3.0, 4.0).feqrel(5.0) > 16);\n assert(hypot(real.infinity, 1.0L) == real.infinity);\n+ assert(hypot(1.0L, real.infinity) == real.infinity);\n assert(hypot(real.infinity, real.nan) == real.infinity);\n+ assert(hypot(real.nan, real.infinity) == real.infinity);\n+ assert(hypot(real.nan, 1.0L).isNaN);\n+ assert(hypot(1.0L, real.nan).isNaN);\n }\n \n @safe unittest\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_mathspecial.d b/libphobos/testsuite/libphobos.phobos/std_mathspecial.d\nnew file mode 100644\nindex 00000000000..84a90c81345\n--- /dev/null\n+++ b/libphobos/testsuite/libphobos.phobos/std_mathspecial.d\n@@ -0,0 +1,86 @@\n+@safe unittest\n+{\n+ import std.mathspecial;\n+\n+ assert(sgnGamma(10_000) == 1);\n+}\n+\n+@safe unittest\n+{\n+ import std.mathspecial;\n+\n+ assert(beta(1, 2) == 0.5);\n+ assert(isIdentical(beta(NaN(0xABC), 4), NaN(0xABC)));\n+ assert(beta(3, 4) == beta(4, 3));\n+ assert(isNaN(beta(-real.infinity, +0.)));\n+ assert(isNaN(beta(-1, 2)));\n+ assert(beta(-0.5, 0.5) is -0.0L);\n+ assert(beta(-1.5, 0.5) is +0.0L);\n+ assert(beta(+0., +0.) == +real.infinity);\n+ assert(isNaN(beta(+0., +real.infinity)));\n+ assert(beta(1, +real.infinity) is +0.0L);\n+ assert(isNaN(beta(-0., +0.)));\n+ assert(beta(-0., nextUp(+0.0L)) == -real.infinity);\n+ assert(beta(-0.5, +real.infinity) == -real.infinity);\n+ assert(beta(nextDown(-1.0L), real.infinity) == real.infinity);\n+ assert(beta(nextDown(-0.0L), +0.) == +real.infinity);\n+ assert(beta(-0.5, -0.) == -real.infinity);\n+}\n+\n+@safe unittest\n+{\n+ import std.mathspecial;\n+\n+ const euler = 0.57721_56649_01532_86060_65121L;\n+\n+ assert(isClose(digamma(1), -euler));\n+ assert(digamma(+0.) == -real.infinity);\n+ assert(digamma(-0.) == +real.infinity);\n+ assert(digamma(+real.infinity) == +real.infinity);\n+ assert(isNaN(digamma(-1)));\n+ assert(isNaN(digamma(-real.infinity)));\n+}\n+\n+@safe unittest\n+{\n+ import std.mathspecial;\n+\n+ assert(betaIncomplete(1, 1, .5) == .5);\n+ assert(betaIncomplete(+0., +0., 0) == 0);\n+ assert(isNaN(betaIncomplete(+0., +0., .5)));\n+ assert(isNaN(betaIncomplete(real.infinity, real.infinity, .5)));\n+ assert(betaIncomplete(real.infinity, real.infinity, 1) == 1);\n+ assert(betaIncomplete(NaN(0x1), 1, NaN(0x2)) is NaN(0x2));\n+ assert(betaIncomplete(1, NaN(0x3), -NaN(0x3)) is -NaN(0x3));\n+}\n+\n+@safe unittest\n+{\n+ import std.mathspecial;\n+\n+ assert(betaIncompleteCompl(.1, .2, 0) == betaIncomplete(.2, .1, 1));\n+}\n+\n+@safe unittest\n+{\n+ import std.mathspecial;\n+\n+ assert(isClose(gammaIncomplete(1, 1), 1 - 1/E));\n+ assert(gammaIncomplete(1, 0) == 0);\n+ assert(gammaIncomplete(1, real.infinity) == 1);\n+ assert(gammaIncomplete(+0., 1) == 1);\n+ assert(gammaIncomplete(real.infinity, 1) == 0);\n+}\n+\n+@safe unittest\n+{\n+ import std.mathspecial;\n+\n+ assert(isClose(gammaIncompleteCompl(2, 1), 2/E));\n+ assert(gammaIncompleteCompl(1, 0) == 1);\n+ assert(gammaIncompleteCompl(1, real.infinity) == 0);\n+ assert(gammaIncompleteCompl(+0., 1) == 0);\n+ assert(gammaIncompleteCompl(real.infinity, 1) == 1);\n+ assert(isClose(gammaIncompleteCompl(1, 2), 1-gammaIncomplete(1, 2)));\n+}\n+\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_meta.d b/libphobos/testsuite/libphobos.phobos/std_meta.d\nindex d5928462f1e..8e45cf996b5 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_meta.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_meta.d\n@@ -120,14 +120,9 @@\n {\n import std.meta;\n \n- import std.stdio;\n-\n- void foo()\n- {\n- writefln(\"The index of long is %s\",\n- staticIndexOf!(long, AliasSeq!(int, long, double)));\n- // prints: The index of long is 1\n- }\n+ alias Types = AliasSeq!(int, long, double);\n+ static assert(staticIndexOf!(long, Types) == 1);\n+ static assert(staticIndexOf!(void, 0, \"void\", void) == 2);\n }\n \n @safe unittest\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_range_package.d b/libphobos/testsuite/libphobos.phobos/std_range_package.d\nindex 03378ce3d66..826b287745f 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_range_package.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_range_package.d\n@@ -122,12 +122,9 @@ pure @safe nothrow unittest\n {\n import std.algorithm.comparison : equal;\n \n- int[4] sarr1 = [1, 2, 3, 4];\n- int[2] sarr2 = [5, 6];\n- int[1] sarr3 = [7];\n- auto arr1 = sarr1[];\n- auto arr2 = sarr2[];\n- auto arr3 = sarr3[];\n+ scope arr1 = [1, 2, 3, 4];\n+ scope arr2 = [5, 6];\n+ scope arr3 = [7];\n \n {\n auto s = chooseAmong(0, arr1, arr2, arr3);\n@@ -137,23 +134,44 @@ pure @safe nothrow unittest\n s.popFront();\n assert(equal(t, only(1, 2, 3, 4)));\n }\n+ // result elements can be modified\n {\n auto s = chooseAmong(1, arr1, arr2, arr3);\n assert(s.length == 2);\n s.front = 8;\n assert(equal(s, only(8, 6)));\n- }\n- {\n- auto s = chooseAmong(1, arr1, arr2, arr3);\n- assert(s.length == 2);\n s[1] = 9;\n assert(equal(s, only(8, 9)));\n+ // original range was mutated\n+ assert(equal(s, arr2));\n }\n+ return 0;\n+ }\n+ // works at runtime\n+ auto a = test();\n+ // and at compile time\n+ static b = test();\n+}\n+\n+@safe nothrow pure @nogc unittest\n+{\n+ import std.range;\n+\n+ auto test()\n+ {\n+ import std.algorithm.comparison : equal;\n+\n+ scope arr1 = [1, 2, 3, 4];\n+ scope arr2 = [8, 9];\n+ scope arr3 = [10];\n+\n+ // slicing\n {\n auto s = chooseAmong(1, arr2, arr1, arr3)[1 .. 3];\n assert(s.length == 2);\n assert(equal(s, only(2, 3)));\n }\n+ // bidirectional\n {\n auto s = chooseAmong(0, arr1, arr2, arr3);\n assert(s.length == 4);\n@@ -164,6 +182,7 @@ pure @safe nothrow unittest\n s.back = 3;\n assert(equal(s, only(1, 2, 3)));\n }\n+ // range primitives\n {\n uint[5] foo = [1, 2, 3, 4, 5];\n uint[5] bar = [6, 7, 8, 9, 10];\n@@ -175,6 +194,7 @@ pure @safe nothrow unittest\n assert(c.moveBack() == 10);\n assert(c.moveAt(4) == 10);\n }\n+ // composability\n {\n import std.range : cycle;\n auto s = chooseAmong(0, cycle(arr2), cycle(arr3));\n@@ -355,7 +375,10 @@ pure @safe nothrow unittest\n \n import std.algorithm.comparison : equal;\n \n- assert([0, 2, 1, 5, 0, 3].drop(3) == [5, 0, 3]);\n+ auto a = [0, 2, 1, 5, 0, 3];\n+ assert(a.drop(3) == [5, 0, 3]);\n+ assert(a.length == 6); // original unchanged\n+\n assert(\"hello world\".drop(6) == \"world\");\n assert(\"hello world\".drop(50).empty);\n assert(\"hello world\".take(6).drop(3).equal(\"lo \"));\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_sumtype.d b/libphobos/testsuite/libphobos.phobos/std_sumtype.d\nindex 7084e98e88f..2e27e0a248a 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_sumtype.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_sumtype.d\n@@ -4,9 +4,9 @@\n \n import std.math.operations : isClose;\n \n- struct Fahrenheit { double degrees; }\n- struct Celsius { double degrees; }\n- struct Kelvin { double degrees; }\n+ struct Fahrenheit { double value; }\n+ struct Celsius { double value; }\n+ struct Kelvin { double value; }\n \n alias Temperature = SumType!(Fahrenheit, Celsius, Kelvin);\n \n@@ -20,29 +20,29 @@\n {\n return Fahrenheit(\n t.match!(\n- (Fahrenheit f) => f.degrees,\n- (Celsius c) => c.degrees * 9.0/5 + 32,\n- (Kelvin k) => k.degrees * 9.0/5 - 459.4\n+ (Fahrenheit f) => f.value,\n+ (Celsius c) => c.value * 9.0/5 + 32,\n+ (Kelvin k) => k.value * 9.0/5 - 459.4\n )\n );\n }\n \n- assert(toFahrenheit(t1).degrees.isClose(98.6));\n- assert(toFahrenheit(t2).degrees.isClose(212));\n- assert(toFahrenheit(t3).degrees.isClose(32));\n+ assert(toFahrenheit(t1).value.isClose(98.6));\n+ assert(toFahrenheit(t2).value.isClose(212));\n+ assert(toFahrenheit(t3).value.isClose(32));\n \n // Use ref to modify the value in place.\n void freeze(ref Temperature t)\n {\n t.match!(\n- (ref Fahrenheit f) => f.degrees = 32,\n- (ref Celsius c) => c.degrees = 0,\n- (ref Kelvin k) => k.degrees = 273\n+ (ref Fahrenheit f) => f.value = 32,\n+ (ref Celsius c) => c.value = 0,\n+ (ref Kelvin k) => k.value = 273\n );\n }\n \n freeze(t1);\n- assert(toFahrenheit(t1).degrees.isClose(32));\n+ assert(toFahrenheit(t1).value.isClose(32));\n \n // Use a catch-all handler to give a default result.\n bool isFahrenheit(Temperature t)\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_traits.d b/libphobos/testsuite/libphobos.phobos/std_traits.d\nindex a86892c26ab..e6aedb366e8 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_traits.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_traits.d\n@@ -154,14 +154,7 @@\n static assert(pstc.length == 4); // number of parameters\n static assert(pstc[0] == STC.ref_);\n static assert(pstc[1] == STC.out_);\n- version (none)\n- {\n- // TODO: When the DMD PR (dlang/dmd#11474) gets merged,\n- // remove the versioning and the second test\n- static assert(pstc[2] == STC.in_);\n- // This is the current behavior, before `in` is fixed to not be an alias\n- static assert(pstc[2] == STC.scope_);\n- }\n+ static assert(pstc[2] == STC.in_);\n static assert(pstc[3] == STC.none);\n }\n \n@@ -1638,6 +1631,20 @@\n static assert( isCallable!f);\n static assert( isCallable!g);\n \n+ auto fp = &f;\n+ static assert( isCallable!fp);\n+ static assert( isCallable!((int x) {}));\n+\n+ int x;\n+ static assert(!isCallable!x);\n+ auto d = () => x;\n+ static assert( isCallable!d);\n+}\n+\n+@safe unittest\n+{\n+ import std.traits;\n+\n class C { int opCall(int) { return 0; } }\n auto c = new C;\n struct S { static int opCall(int) { return 0; } }\n@@ -1647,7 +1654,6 @@\n static assert( isCallable!(c.opCall));\n static assert( isCallable!S);\n static assert( isCallable!(I.value));\n- static assert( isCallable!((int a) { return a; }));\n \n static assert(!isCallable!I);\n }\n@@ -1658,13 +1664,17 @@\n \n void f()() { }\n T g(T = int)(T x) { return x; }\n+ int h(T)();\n struct S1 { static void opCall()() { } }\n struct S2 { static T opCall(T = int)(T x) {return x; } }\n \n static assert( isCallable!f);\n static assert( isCallable!g);\n+ static assert(!isCallable!h);\n static assert( isCallable!S1);\n static assert( isCallable!S2);\n+\n+ static assert(!isCallable!((x) {}));\n }\n \n @safe unittest\n@@ -2368,6 +2378,14 @@\n \n static void func(){}\n static assert(isFunction!func);\n+ static assert(isFunction!(typeof(func)));\n+\n+ auto fp = &func; // function pointer\n+ static assert(!isFunction!fp);\n+\n+ int i;\n+ int f2() => i; // nested function\n+ static assert(isFunction!f2);\n \n struct S\n {\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_typecons.d b/libphobos/testsuite/libphobos.phobos/std_typecons.d\nindex c8e43ac499a..622d0fa9b3e 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_typecons.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_typecons.d\n@@ -599,6 +599,21 @@\n }\n }\n \n+@safe unittest\n+{\n+ import std.typecons;\n+\n+ Nullable!int a = 5;\n+ Nullable!int b = 0;\n+ assert(a > b);\n+ assert(b < a);\n+\n+ Nullable!int c;\n+ assert(c < a);\n+ assert(c < b);\n+ \n+}\n+\n @safe unittest\n {\n import std.typecons;\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_uuid.d b/libphobos/testsuite/libphobos.phobos/std_uuid.d\nindex 2486083cd26..ba41272037a 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_uuid.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_uuid.d\n@@ -43,6 +43,18 @@\n \n }\n \n+@system unittest\n+{\n+ import std.uuid;\n+\n+ import std.datetime : DateTime, SysTime;\n+ SysTime st = DateTime(2025, 8, 19, 10, 38, 45);\n+ UUID u = UUID(st);\n+ SysTime o = u.v7Timestamp();\n+ assert(o == st, st.toString() ~ \" | \" ~ o.toString());\n+ \n+}\n+\n @safe pure unittest\n {\n import std.uuid;\n@@ -189,6 +201,26 @@\n auto uuid3 = randomUUID(gen);\n }\n \n+@system unittest\n+{\n+ import std.uuid;\n+\n+ auto f = new shared MonotonicUUIDsFactory;\n+\n+ UUID[10] monotonic;\n+\n+ foreach (ref u; monotonic)\n+ u = f.createUUIDv7_method3;\n+}\n+\n+@system unittest\n+{\n+ import std.uuid;\n+\n+ UUID u = timestampRandomUUID();\n+ assert(u.uuidVersion == UUID.Version.timestampRandom);\n+}\n+\n @safe unittest\n {\n import std.uuid;\n@@ -250,3 +282,30 @@\n assert(ex.reason == UUIDParsingException.Reason.tooLittle);\n }\n \n+@system unittest\n+{\n+ import std.uuid;\n+\n+ import std.datetime : DateTime, SysTime;\n+\n+ SysTime st = DateTime(2025, 8, 19, 10, 38, 45);\n+ UUID u = UUID(st);\n+ assert(u.uuidVersion == UUID.Version.timestampRandom);\n+ SysTime o = u.v7Timestamp();\n+ assert(o == st, st.toString() ~ \" | \" ~ o.toString());\n+ string s = u.toString();\n+ UUID u2 = UUID(s);\n+ SysTime o2 = u2.v7Timestamp();\n+ assert(o2 == st, st.toString() ~ \" | \" ~ o2.toString());\n+}\n+\n+@system unittest\n+{\n+ import std.uuid;\n+\n+ import std.datetime : DateTime, SysTime;\n+ UUID u = UUID(\"0198c2b2-c5a8-7a0f-a1db-86aac7906c7b\");\n+ auto d = DateTime(2025,8,19);\n+ assert((cast(DateTime) u.v7Timestamp()).year == d.year);\n+}\n+\n", "prefixes": [ "committed" ] }