get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2218714/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2218714,
    "url": "http://patchwork.ozlabs.org/api/patches/2218714/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20260401183432.3740846-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": "<20260401183432.3740846-1-ibuclaw@gdcproject.org>",
    "list_archive_url": null,
    "date": "2026-04-01T18:34:31",
    "name": "[committed] d: Merge upstream dmd, druntime 55e64690bc, phobos 0c519ae39.",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "6b1a76cf1b8ae66efc9d7336b553ddcdf8f9d77c",
    "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/20260401183432.3740846-1-ibuclaw@gdcproject.org/mbox/",
    "series": [
        {
            "id": 498377,
            "url": "http://patchwork.ozlabs.org/api/series/498377/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=498377",
            "date": "2026-04-01T18:34:31",
            "name": "[committed] d: Merge upstream dmd, druntime 55e64690bc, phobos 0c519ae39.",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/498377/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2218714/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2218714/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=oaH4/+Q3;\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=oaH4/+Q3",
            "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.172",
            "outgoing_mbo_mout; dkim=none;\n spf=pass (outgoing_mbo_mout: domain of ibuclaw@gdcproject.org designates\n 2001:67c:2050:b231:465::2 as permitted sender)\n smtp.mailfrom=ibuclaw@gdcproject.org"
        ],
        "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 4fmDFn2cBYz1yFv\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 02 Apr 2026 05:35:57 +1100 (AEDT)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 0D1E24BA2E3C\n\tfor <incoming@patchwork.ozlabs.org>; Wed,  1 Apr 2026 18:35:55 +0000 (GMT)",
            "from mout-p-202.mailbox.org (mout-p-202.mailbox.org [80.241.56.172])\n by sourceware.org (Postfix) with ESMTPS id 64F444BA2E3C\n for <gcc-patches@gcc.gnu.org>; Wed,  1 Apr 2026 18:34:48 +0000 (GMT)",
            "from smtp2.mailbox.org (smtp2.mailbox.org\n [IPv6:2001:67c:2050:b231:465::2])\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-202.mailbox.org (Postfix) with ESMTPS id 4fmDDN6WnTz9v5t;\n Wed,  1 Apr 2026 20:34:44 +0200 (CEST)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org 0D1E24BA2E3C",
            "OpenDKIM Filter v2.11.0 sourceware.org 64F444BA2E3C"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 64F444BA2E3C",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 64F444BA2E3C",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1775068489; cv=none;\n b=HVvW/3PjLWHvDojCVtoX0JRcYD+Pcdh9XaRnv2DJa3KtXgjaD+jcfK7tKhXYXcmVB5smDfmFlwMlX1Dzk0Wczm+cppaRxYGT1Mr26hqyoUkZLnSiH9OBVETObXhysfuAxoa8Hll6yYpheuOva/E9xSwMOVlPhG+v46AbtUV0kyk=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1775068489; c=relaxed/simple;\n bh=mhNHvxM/oD/n3nFJQZTH7Ktr+1bIKiwyXajmUB8hqTk=;\n h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version;\n b=SUBh3AN6q6TUpZ/f6FO/bMycPSmBMLWtX4BUd6Zj2E2b9Q8EML8CNqUB3TIvJi34LWPrlZ0goKYT1MshsVE9bLbDoPiO2vBFHjrxrag4lsyKiKTW5supX2Zot5AtghOtp/X3k6BG5cdcQAua93vgXb5xei90BI9ukTGgE6F8+qY=",
        "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=1775068485;\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=YhK/udaHQakofYL+e6MseF/pg3i+fX02Qw30IhNbaMw=;\n b=oaH4/+Q3zsLBqL5Z8UZxaesYip/5KQf59596aE5Cuv4dqAgKmbBIFJ8u/Y4bFnJtvmOLz6\n EiqdrGoSujqVaK8R61LWAbupl/BQNqQaPZXZyNz7o9zV+BFBX9tyg9vw6HaLwoLke9CYMi\n VUsz4i3GWWJP6pYOteZUJ1jm4j3JkBgw7gHCcL/A6LfjRrdnvjPUc00S4UGZ23to596Q+0\n X7N7Tjk4bRaelRY472kWMYVwXj+Jnaahd01j0yFSpa1zGBBJA+d6ZjjdD6BUn/xoJoij6O\n QWGeo47bOh67bceZ83jZEvC3+9t5KtDNRSlfkO7q0g8SVRE5HI2pTRPiJJKnng==",
        "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 55e64690bc,\n phobos 0c519ae39.",
        "Date": "Wed,  1 Apr 2026 20:34:31 +0200",
        "Message-ID": "<20260401183432.3740846-1-ibuclaw@gdcproject.org>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "X-Rspamd-Queue-Id": "4fmDDN6WnTz9v5t",
        "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\n55e64690bc, and the standard library with phobos 0c519ae39.\n\nThis, now in sync with v2.113 release branch.\n\nD front-end changes:\n\n\t- Import dmd v2.113.0-beta.1.\n\t- Add support for static array length inference.\n\t- Added trait `__traits(needsDestruction, T)'.\n\t- Added trait `__traits(isOverlapped, field)'.\n\nD runtime changes:\n\n\t- Import druntime v2.113.0-beta.1.\n\nPhobos changes:\n\n\t- Import phobos v2.113.0-beta.1.\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 55e64690bc.\n\t* dmd/VERSION: Bump version to v2.113.0-beta.1.\n\t* d-codegen.cc (d_build_call): Check if argument is already a\n\tTARGET_EXPR.\n\t* decl.cc (DeclVisitor::visit (FuncDeclaration *)): Don't use\n\t`__result' decl as named return value if it's a ref type.\n\t* expr.cc (ExprVisitor::visit (StructLiteralExp *)): Force TARGET_EXPR\n\tif init symbol needs to be mutable.\n\t* runtime.def (ARRAYSETLENGTHT): Remove.\n\t(ARRAYSETLENGTHIT): Remove.\n\t(ARRAYCOPY): Remove.\n\t(ARRAYAPPENDCTX): Remove.\n\t* typeinfo.cc (TypeInfoVisitor::visit (TypeInfoClassDeclaration *)):\n\tOnly scan class fields for pointer members.\n\nlibphobos/ChangeLog:\n\n\t* libdruntime/MERGE: Merge upstream druntime 55e64690bc.\n\t* src/MERGE: Merge upstream phobos 0c519ae39.\n\t* testsuite/libphobos.aa/test_aa.d: Update.\n\t* testsuite/libphobos.phobos/std_array.d: Regenerate.\n\t* testsuite/libphobos.phobos/std_mathspecial.d: Regenerate.\n\t* src/std/internal/windows/bcrypt.d: New file.\n---\n gcc/d/d-codegen.cc                            |   3 +-\n gcc/d/decl.cc                                 |   2 +-\n gcc/d/dmd/MERGE                               |   2 +-\n gcc/d/dmd/VERSION                             |   2 +-\n gcc/d/dmd/aliasthis.d                         |   2 +-\n gcc/d/dmd/common/charactertables.d            |   7 +\n gcc/d/dmd/common/file.d                       |   6 +-\n gcc/d/dmd/cparse.d                            | 177 ++++----\n gcc/d/dmd/cxxfrontend.d                       |   6 +\n gcc/d/dmd/dcast.d                             |   2 -\n gcc/d/dmd/dclass.d                            |   1 -\n gcc/d/dmd/declaration.d                       |   6 +-\n gcc/d/dmd/dimport.d                           |   2 +-\n gcc/d/dmd/dmodule.d                           |   4 +-\n gcc/d/dmd/dsymbol.d                           |  78 +++-\n gcc/d/dmd/dsymbol.h                           |   1 -\n gcc/d/dmd/dsymbolsem.d                        | 211 ++++++---\n gcc/d/dmd/dtemplate.d                         |  38 --\n gcc/d/dmd/dversion.d                          |   4 +-\n gcc/d/dmd/expression.h                        |   1 +\n gcc/d/dmd/expressionsem.d                     | 151 +++++--\n gcc/d/dmd/func.d                              |   9 -\n gcc/d/dmd/funcsem.d                           |   3 +-\n gcc/d/dmd/hdrgen.d                            |   7 +-\n gcc/d/dmd/id.d                                |   6 +\n gcc/d/dmd/initsem.d                           |  18 +-\n gcc/d/dmd/lexer.d                             |  24 +-\n gcc/d/dmd/mtype.d                             |   4 +\n gcc/d/dmd/nogc.d                              |  14 +-\n gcc/d/dmd/parse.d                             |  15 +\n gcc/d/dmd/root/ctfloat.d                      |   6 +-\n gcc/d/dmd/semantic3.d                         |  58 ++-\n gcc/d/dmd/statement.d                         |   1 +\n gcc/d/dmd/statement.h                         |   1 +\n gcc/d/dmd/statementsem.d                      |   7 +-\n gcc/d/dmd/templatesem.d                       |  44 +-\n gcc/d/dmd/traits.d                            |  78 +++-\n gcc/d/dmd/typesem.d                           |  52 ++-\n gcc/d/expr.cc                                 |   2 +\n gcc/d/runtime.def                             |  16 -\n gcc/d/typeinfo.cc                             |   9 +-\n gcc/testsuite/gdc.test/compilable/diag20916.d |  64 +++\n .../gdc.test/compilable/imports/test22480b.d  |  13 +\n .../gdc.test/compilable/issue22769.d          |  19 +\n gcc/testsuite/gdc.test/compilable/new_xdtor.d |  10 +\n .../gdc.test/compilable/struct_allMembers.d   |  14 +\n gcc/testsuite/gdc.test/compilable/test22480.d |  10 +\n gcc/testsuite/gdc.test/compilable/test22501.d |  12 +\n gcc/testsuite/gdc.test/compilable/test22543.d |  11 +\n gcc/testsuite/gdc.test/compilable/test22544.d |  11 +\n gcc/testsuite/gdc.test/compilable/test22752.d |  23 +\n gcc/testsuite/gdc.test/compilable/test24295.d |  11 +\n .../gdc.test/compilable/test_isOverlapped.d   | 181 ++++++++\n .../test_nosharedaccess_ctor_nested_new.d     |  13 +\n ...est_nosharedaccess_shared_struct_literal.d |  15 +\n gcc/testsuite/gdc.test/compilable/traits.d    |   1 +\n gcc/testsuite/gdc.test/compilable/vgc3.d      |   8 +-\n .../gdc.test/fail_compilation/fail19898a.d    |   2 +-\n .../gdc.test/fail_compilation/fail19898b.d    |   4 +-\n .../fail_compilation/getMember_private.d      |  26 ++\n .../gdc.test/fail_compilation/issue22147.d    |  16 +\n .../gdc.test/fail_compilation/safeprintf.d    |  37 +-\n .../gdc.test/fail_compilation/staticarray.d   |  12 +\n .../gdc.test/fail_compilation/test17977.d     |   2 +-\n .../gdc.test/fail_compilation/test24295.d     |  13 -\n .../gdc.test/fail_compilation/test9150.d      |   2 +-\n .../test_isOverlapped_errors.d                |  17 +\n gcc/testsuite/gdc.test/runnable/b10562.d      |   8 +\n .../runnable/extra-files/sectiondefs.d        |  13 +\n gcc/testsuite/gdc.test/runnable/foreach5.d    |  31 ++\n gcc/testsuite/gdc.test/runnable/issue22621.d  |  40 ++\n gcc/testsuite/gdc.test/runnable/issue22639.d  |  35 ++\n gcc/testsuite/gdc.test/runnable/lexer.d       |  12 +\n gcc/testsuite/gdc.test/runnable/rvalue1.d     |  24 +\n gcc/testsuite/gdc.test/runnable/sctor.d       |  37 ++\n gcc/testsuite/gdc.test/runnable/staticarray.d |  83 ++++\n .../gdc.test/runnable/structlit_rvalue.d      |  64 ++-\n gcc/testsuite/gdc.test/runnable/test20275.d   |   1 +\n gcc/testsuite/gdc.test/runnable/test22422.d   |  21 +\n gcc/testsuite/gdc.test/runnable/test22594.d   |  23 +\n gcc/testsuite/gdc.test/runnable/testaa2.d     |   8 +\n gcc/testsuite/gdc.test/runnable/testaa3.d     |  70 +++\n libphobos/libdruntime/MERGE                   |   2 +-\n libphobos/libdruntime/core/atomic.d           | 130 +++---\n libphobos/libdruntime/core/attribute.d        |  26 ++\n libphobos/libdruntime/core/gc/config.d        |   6 +\n .../core/internal/array/capacity.d            |  20 +-\n .../core/internal/array/construction.d        |   5 +-\n .../core/internal/array/duplication.d         |  27 +-\n .../core/internal/array/equality.d            |  44 +-\n .../libdruntime/core/internal/array/utils.d   |  12 +-\n libphobos/libdruntime/core/internal/atomic.d  |  78 ++++\n .../core/internal/gc/impl/conservative/gc.d   |  29 +-\n .../libdruntime/core/internal/lifetime.d      |  13 +-\n libphobos/libdruntime/core/internal/newaa.d   |  24 +\n libphobos/libdruntime/core/internal/traits.d  |  69 ++-\n libphobos/libdruntime/core/lifetime.d         |  35 +-\n libphobos/libdruntime/core/memory.d           |   2 +-\n libphobos/libdruntime/core/stdc/stdatomic.d   |   5 +-\n libphobos/libdruntime/core/stdc/stdint.d      |  15 +-\n libphobos/libdruntime/core/stdc/stdio.d       |  20 +-\n libphobos/libdruntime/core/stdc/time.d        |  73 ++-\n libphobos/libdruntime/core/sync/condition.d   |   4 +-\n libphobos/libdruntime/core/sync/mutex.d       |  18 +-\n libphobos/libdruntime/core/sync/rwmutex.d     | 122 +----\n .../libdruntime/core/sys/darwin/crt_externs.d |   2 +-\n .../libdruntime/core/sys/freebsd/config.d     |   3 +-\n libphobos/libdruntime/core/sys/posix/aio.d    |  12 +\n libphobos/libdruntime/core/sys/posix/dirent.d |  20 +\n libphobos/libdruntime/core/sys/posix/locale.d |  13 +-\n .../libdruntime/core/sys/posix/netinet/in_.d  |  48 +-\n libphobos/libdruntime/core/sys/posix/pwd.d    |  14 +-\n libphobos/libdruntime/core/sys/posix/sched.d  |   1 +\n libphobos/libdruntime/core/sys/posix/setjmp.d |   8 +-\n libphobos/libdruntime/core/sys/posix/signal.d |   1 +\n .../libdruntime/core/sys/posix/stdc/time.d    |   1 +\n libphobos/libdruntime/core/sys/posix/stdlib.d |   4 +-\n .../libdruntime/core/sys/posix/sys/msg.d      |   5 +-\n .../libdruntime/core/sys/posix/sys/resource.d |   2 +-\n .../libdruntime/core/sys/posix/sys/select.d   |   2 +\n .../libdruntime/core/sys/posix/sys/shm.d      |   2 +-\n .../libdruntime/core/sys/posix/sys/socket.d   |   2 +-\n .../libdruntime/core/sys/posix/sys/stat.d     |   6 +-\n .../libdruntime/core/sys/posix/sys/statvfs.d  |   2 +\n .../libdruntime/core/sys/posix/sys/time.d     |   4 +\n .../libdruntime/core/sys/posix/sys/types.d    |   6 +-\n libphobos/libdruntime/core/sys/posix/time.d   |  10 +\n libphobos/libdruntime/core/sys/posix/unistd.d |  20 +-\n libphobos/libdruntime/core/sys/posix/utime.d  |   2 +-\n .../libdruntime/core/sys/windows/winuser.d    |   8 +-\n libphobos/libdruntime/core/thread/context.d   |   1 +\n libphobos/libdruntime/core/thread/osthread.d  |  30 +-\n libphobos/libdruntime/core/thread/package.d   |  26 +-\n libphobos/libdruntime/core/thread/types.d     |  17 +-\n libphobos/libdruntime/etc/valgrind/valgrind.d |   2 +-\n libphobos/libdruntime/object.d                |  42 +-\n libphobos/libdruntime/rt/critical_.d          |   8 +-\n libphobos/libdruntime/rt/dmain2.d             |  61 ++-\n libphobos/libdruntime/rt/minfo.d              |   6 +-\n libphobos/libdruntime/rt/monitor_.d           |  12 +-\n libphobos/libdruntime/rt/profilegc.d          |   4 +-\n libphobos/libdruntime/rt/sections.d           |   4 +-\n libphobos/src/MERGE                           |   2 +-\n libphobos/src/Makefile.am                     |  17 +-\n libphobos/src/Makefile.in                     |  19 +-\n libphobos/src/index.dd                        |  48 +-\n libphobos/src/std/algorithm/setops.d          |  26 ++\n libphobos/src/std/array.d                     | 425 +++++-------------\n libphobos/src/std/container/rbtree.d          |  36 +-\n .../src/std/experimental/allocator/common.d   |   3 +-\n libphobos/src/std/file.d                      |  17 +-\n libphobos/src/std/format/write.d              |  11 +-\n .../src/std/internal/math/errorfunction.d     |   5 +\n .../src/std/internal/math/gammafunction.d     | 175 +++++---\n libphobos/src/std/internal/windows/bcrypt.d   |  65 +++\n libphobos/src/std/logger/core.d               |  11 +\n libphobos/src/std/logger/package.d            |  86 +++-\n libphobos/src/std/math/hardware.d             |  67 ++-\n libphobos/src/std/mathspecial.d               |  61 ++-\n libphobos/src/std/signals.d                   |   5 -\n libphobos/src/std/socket.d                    |   2 +-\n libphobos/src/std/traits.d                    |   4 +-\n libphobos/src/std/typecons.d                  |  50 +--\n libphobos/src/std/uni/package.d               |  19 +\n libphobos/src/std/variant.d                   |  17 +-\n libphobos/testsuite/libphobos.aa/test_aa.d    |  35 ++\n .../testsuite/libphobos.phobos/std_array.d    |  17 -\n .../libphobos.phobos/std_mathspecial.d        |  29 +-\n 168 files changed, 3280 insertions(+), 1259 deletions(-)\n create mode 100644 gcc/testsuite/gdc.test/compilable/diag20916.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/imports/test22480b.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/issue22769.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/new_xdtor.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/struct_allMembers.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/test22480.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/test22501.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/test22543.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/test22544.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/test22752.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/test24295.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/test_isOverlapped.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/test_nosharedaccess_ctor_nested_new.d\n create mode 100644 gcc/testsuite/gdc.test/compilable/test_nosharedaccess_shared_struct_literal.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/getMember_private.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/issue22147.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/staticarray.d\n delete mode 100644 gcc/testsuite/gdc.test/fail_compilation/test24295.d\n create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test_isOverlapped_errors.d\n create mode 100644 gcc/testsuite/gdc.test/runnable/extra-files/sectiondefs.d\n create mode 100644 gcc/testsuite/gdc.test/runnable/issue22621.d\n create mode 100644 gcc/testsuite/gdc.test/runnable/issue22639.d\n create mode 100644 gcc/testsuite/gdc.test/runnable/staticarray.d\n create mode 100644 gcc/testsuite/gdc.test/runnable/test22422.d\n create mode 100644 gcc/testsuite/gdc.test/runnable/test22594.d\n create mode 100644 libphobos/src/std/internal/windows/bcrypt.d",
    "diff": "diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc\nindex 562a8c7ae26..6e397decea0 100644\n--- a/gcc/d/d-codegen.cc\n+++ b/gcc/d/d-codegen.cc\n@@ -2349,7 +2349,8 @@ d_build_call (TypeFunction *tf, tree callable, tree object,\n \t\t - The ABI of the function expects the callee to destroy its\n \t\t arguments; when the caller is handles destruction, then `targ'\n \t\t has already been made into a temporary. */\n-\t      if (!can_elide_copy_p (arg)\n+\t      if (TREE_CODE (targ) != TARGET_EXPR\n+\t\t  && !can_elide_copy_p (arg)\n \t\t  && (arg->op == EXP::structLiteral\n \t\t      || (!sd->postblit && !sd->dtor)\n \t\t      || target.isCalleeDestroyingArgs (tf)))\ndiff --git a/gcc/d/decl.cc b/gcc/d/decl.cc\nindex fd2b1013a46..3b6f8544f2a 100644\n--- a/gcc/d/decl.cc\n+++ b/gcc/d/decl.cc\n@@ -1053,7 +1053,7 @@ public:\n \n \tif (d->isNRVO () && d->nrvo_var)\n \t  var = get_symbol_decl (d->nrvo_var);\n-\telse if (d->vresult)\n+\telse if (d->vresult && !d->vresult->isRef ())\n \t  var = get_symbol_decl (d->vresult);\n \n \tif (var != NULL_TREE)\ndiff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE\nindex 434ad554b84..a5b457e873c 100644\n--- a/gcc/d/dmd/MERGE\n+++ b/gcc/d/dmd/MERGE\n@@ -1,4 +1,4 @@\n-e7c34c13de2930f2becc484e12b2c2cf1a16f6e8\n+662104f52607c175ecb80633bd261932aa004561\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/VERSION b/gcc/d/dmd/VERSION\nindex bb14ba5b599..7efbee7bbe6 100644\n--- a/gcc/d/dmd/VERSION\n+++ b/gcc/d/dmd/VERSION\n@@ -1 +1 @@\n-v2.112.0\n+v2.113.0-beta.1\ndiff --git a/gcc/d/dmd/aliasthis.d b/gcc/d/dmd/aliasthis.d\nindex bb1fcd02038..98380cb90f3 100644\n--- a/gcc/d/dmd/aliasthis.d\n+++ b/gcc/d/dmd/aliasthis.d\n@@ -41,7 +41,7 @@ extern (C++) final class AliasThis : Dsymbol\n     {\n         assert(!s);\n         auto at = new AliasThis(loc, ident);\n-        at.comment = comment;\n+        at.addComment(comment);\n         return at;\n     }\n \ndiff --git a/gcc/d/dmd/common/charactertables.d b/gcc/d/dmd/common/charactertables.d\nindex baa12620328..620c04cfffc 100644\n--- a/gcc/d/dmd/common/charactertables.d\n+++ b/gcc/d/dmd/common/charactertables.d\n@@ -185,6 +185,13 @@ bool c_isalnum(const int c)\n         ( c >= 'A' && c <= 'Z'));\n }\n \n+///\n+bool isAlphaASCII(const dchar c)\n+{\n+    return (( c >= 'a' && c <= 'z') ||\n+        ( c >= 'A' && c <= 'Z'));\n+}\n+\n extern(D) private:\n \n // originally from dmd.root.utf\ndiff --git a/gcc/d/dmd/common/file.d b/gcc/d/dmd/common/file.d\nindex dad41de13ef..7b7c2bf6a7d 100644\n--- a/gcc/d/dmd/common/file.d\n+++ b/gcc/d/dmd/common/file.d\n@@ -121,7 +121,7 @@ struct FileMapping(Datum)\n \n             if (size > 0 && size != ulong.max && size <= size_t.max)\n             {\n-                auto p = mmap(null, cast(size_t) size, is(Datum == const) ? PROT_READ : PROT_WRITE, MAP_SHARED, handle, 0);\n+                auto p = mmap(null, cast(size_t) size, is(Datum == const) ? PROT_READ : (PROT_READ | PROT_WRITE), MAP_SHARED, handle, 0);\n                 if (p == MAP_FAILED)\n                 {\n                     fprintf(stderr, \"mmap(null, %zu) for \\\"%s\\\" failed: %s\\n\", cast(size_t) size, filename, strerror(errno));\n@@ -382,8 +382,8 @@ struct FileMapping(Datum)\n                 }\n                 if (size > 0)\n                 {\n-                    auto p = mmap(null, size, PROT_WRITE, MAP_SHARED, handle, 0);\n-                    if (cast(ssize_t) p == -1)\n+                    auto p = mmap(null, size, PROT_READ | PROT_WRITE, MAP_SHARED, handle, 0);\n+                    if (p == MAP_FAILED)\n                     {\n                         fprintf(stderr, \"mmap() failed for \\\"%s\\\": %s\\n\", filename, strerror(errno));\n                         exit(1);\ndiff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d\nindex 32b4e0146a3..e1793ae5426 100644\n--- a/gcc/d/dmd/cparse.d\n+++ b/gcc/d/dmd/cparse.d\n@@ -2395,7 +2395,6 @@ final class CParser(AST) : Parser!AST\n             xllong     = 0x40,\n             xfloat     = 0x80,\n             xdouble    = 0x100,\n-            xldouble   = 0x200,\n             xtag       = 0x400,\n             xident     = 0x800,\n             xvoid      = 0x1000,\n@@ -3657,109 +3656,108 @@ final class CParser(AST) : Parser!AST\n         if (!isGnuAttributeName())\n             return;\n \n-        if (token.value == TOK.identifier)\n+        if (token.value != TOK.identifier)\n         {\n-            if (token.ident == Id.aligned)\n-            {\n-                nextToken();\n-                if (token.value == TOK.leftParenthesis)\n-                {\n-                    nextToken();\n-                    AST.Expression exp = cparseConstantExp();\n-                    if (!specifier.alignAttrs)\n-                        specifier.alignAttrs = new AST.Expressions();\n-                    specifier.alignAttrs.push(exp);\n-                    check(TOK.rightParenthesis);\n-                }\n-                else\n-                {\n-                    /* ignore __attribute__((aligned)), which sets the alignment to the largest value for any data\n-                     * type on the target machine. It's the opposite of __attribute__((packed))\n-                     */\n-                }\n-            }\n-            else if (token.ident == Id.packed)\n-            {\n-                specifier.packalign.set(1);\n-                specifier.packalign.setPack();\n-                nextToken();\n-            }\n-            else if (token.ident == Id.always_inline) // https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html\n-            {\n-                specifier.scw |= SCW.xinline;\n-                nextToken();\n-            }\n-            else if (token.ident == Id._deprecated)\n-            {\n-                specifier._deprecated = true;\n-                nextToken();\n-                if (token.value == TOK.leftParenthesis)  // optional deprecation message\n-                {\n-                    nextToken();\n-                    specifier.depMsg = cparseExpression();\n-                    check(TOK.rightParenthesis);\n-                }\n-            }\n-            else if (token.ident == Id.dllimport)\n-            {\n-                specifier.dllimport = true;\n-                nextToken();\n-            }\n-            else if (token.ident == Id.dllexport)\n-            {\n-                specifier.dllexport = true;\n-                nextToken();\n-            }\n-            else if (token.ident == Id.naked)\n-            {\n-                specifier.naked = true;\n-                nextToken();\n-            }\n-            else if (token.ident == Id.noinline)\n-            {\n-                specifier.scw |= SCW.xnoinline;\n-                nextToken();\n-            }\n-            else if (token.ident == Id.noreturn)\n+            nextToken();\n+            if (token.value == TOK.leftParenthesis)\n+                cparseParens();\n+            return;\n+        }\n+\n+        if (token.ident == Id.aligned)\n+        {\n+            nextToken();\n+            if (token.value == TOK.leftParenthesis)\n             {\n-                specifier.noreturn = true;\n                 nextToken();\n+                AST.Expression exp = cparseConstantExp();\n+                if (!specifier.alignAttrs)\n+                    specifier.alignAttrs = new AST.Expressions();\n+                specifier.alignAttrs.push(exp);\n+                check(TOK.rightParenthesis);\n             }\n-            else if (token.ident == Id._nothrow)\n+            else\n             {\n-                specifier._nothrow = true;\n-                nextToken();\n+                /* ignore __attribute__((aligned)), which sets the alignment to the largest value for any data\n+                 * type on the target machine. It's the opposite of __attribute__((packed))\n+                 */\n             }\n-            else if (token.ident == Id._pure)\n+        }\n+        else if (token.ident == Id.packed)\n+        {\n+            specifier.packalign.set(1);\n+            specifier.packalign.setPack();\n+            nextToken();\n+        }\n+        else if (token.ident == Id.always_inline) // https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html\n+        {\n+            specifier.scw |= SCW.xinline;\n+            nextToken();\n+        }\n+        else if (token.ident == Id._deprecated)\n+        {\n+            specifier._deprecated = true;\n+            nextToken();\n+            if (token.value == TOK.leftParenthesis)  // optional deprecation message\n             {\n-                specifier._pure = true;\n                 nextToken();\n+                specifier.depMsg = cparseExpression();\n+                check(TOK.rightParenthesis);\n             }\n-            else if (token.ident == Id.vector_size)\n+        }\n+        else if (token.ident == Id.dllimport)\n+        {\n+            specifier.dllimport = true;\n+            nextToken();\n+        }\n+        else if (token.ident == Id.dllexport)\n+        {\n+            specifier.dllexport = true;\n+            nextToken();\n+        }\n+        else if (token.ident == Id.naked)\n+        {\n+            specifier.naked = true;\n+            nextToken();\n+        }\n+        else if (token.ident == Id.noinline)\n+        {\n+            specifier.scw |= SCW.xnoinline;\n+            nextToken();\n+        }\n+        else if (token.ident == Id.noreturn)\n+        {\n+            specifier.noreturn = true;\n+            nextToken();\n+        }\n+        else if (token.ident == Id._nothrow)\n+        {\n+            specifier._nothrow = true;\n+            nextToken();\n+        }\n+        else if (token.ident == Id._pure)\n+        {\n+            specifier._pure = true;\n+            nextToken();\n+        }\n+        else if (token.ident == Id.vector_size)\n+        {\n+            nextToken();\n+            check(TOK.leftParenthesis);\n+            if (token.value == TOK.int32Literal)\n             {\n+                const n = token.unsvalue;\n+                if (n < 1 || n & (n - 1) || ushort.max < n)\n+                    error(\"__attribute__((vector_size(%lld))) must be an integer positive power of 2 and be <= 32,768\", cast(ulong)n);\n+                specifier.vector_size = cast(uint) n;\n                 nextToken();\n-                check(TOK.leftParenthesis);\n-                if (token.value == TOK.int32Literal)\n-                {\n-                    const n = token.unsvalue;\n-                    if (n < 1 || n & (n - 1) || ushort.max < n)\n-                        error(\"__attribute__((vector_size(%lld))) must be an integer positive power of 2 and be <= 32,768\", cast(ulong)n);\n-                    specifier.vector_size = cast(uint) n;\n-                    nextToken();\n-                }\n-                else\n-                {\n-                    error(\"value for vector_size expected, not `%s`\", token.toChars());\n-                    nextToken();\n-                }\n-                check(TOK.rightParenthesis);\n             }\n             else\n             {\n+                error(\"value for vector_size expected, not `%s`\", token.toChars());\n                 nextToken();\n-                if (token.value == TOK.leftParenthesis)\n-                    cparseParens();\n             }\n+            check(TOK.rightParenthesis);\n         }\n         else\n         {\n@@ -5076,8 +5074,7 @@ final class CParser(AST) : Parser!AST\n             if (pt && *pt)\n                 t = *pt;\n         }\n-        if (t.mcache && t.mcache.typedefIdent)\n-        {\n+        if ((t.mcache && t.mcache.typedefIdent) || t.isTypeBasic()) {\n             t = t.copy();\n             t.mcache = null;\n         }\ndiff --git a/gcc/d/dmd/cxxfrontend.d b/gcc/d/dmd/cxxfrontend.d\nindex b4524a465bc..709aff03caa 100644\n--- a/gcc/d/dmd/cxxfrontend.d\n+++ b/gcc/d/dmd/cxxfrontend.d\n@@ -430,6 +430,12 @@ bool isLvalue(Expression exp)\n     return dmd.expressionsem.isLvalue(exp);\n }\n \n+bool canElideCopy(Expression exp, Type to, bool checkMod)\n+{\n+    import dmd.expressionsem;\n+    return dmd.expressionsem.canElideCopy(exp, to, checkMod);\n+}\n+\n int getFieldIndex(ClassReferenceExp cre, Type fieldtype, uint fieldoffset)\n {\n     import dmd.expressionsem;\ndiff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d\nindex 66c0b8a8c20..fdc29094aa0 100644\n--- a/gcc/d/dmd/dcast.d\n+++ b/gcc/d/dmd/dcast.d\n@@ -4374,8 +4374,6 @@ void fix16997(Scope* sc, UnaExp ue)\n extern (D) bool keyCompatibleWithoutCasting(Expression ekey, Type t2)\n {\n     Type t1 = ekey.type;\n-    t1 = t1.toBasetype();\n-    t2 = t2.toBasetype();\n \n     if ((t1.isStaticOrDynamicArray() || t1.ty == Tpointer) && t2.ty == t1.ty)\n     {\ndiff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d\nindex 6385265f9f1..950f7db1137 100644\n--- a/gcc/d/dmd/dclass.d\n+++ b/gcc/d/dmd/dclass.d\n@@ -20,7 +20,6 @@ import dmd.aggregate;\n import dmd.arraytypes;\n import dmd.astenums;\n import dmd.declaration;\n-import dmd.dscope;\n import dmd.dsymbol;\n import dmd.errors;\n import dmd.func;\ndiff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d\nindex d9eab5b7642..e1a4f9bf656 100644\n--- a/gcc/d/dmd/declaration.d\n+++ b/gcc/d/dmd/declaration.d\n@@ -361,7 +361,7 @@ extern (C++) final class AliasDeclaration : Declaration\n         //printf(\"AliasDeclaration::syntaxCopy()\\n\");\n         assert(!s);\n         AliasDeclaration sa = type ? new AliasDeclaration(loc, ident, type.syntaxCopy()) : new AliasDeclaration(loc, ident, aliassym.syntaxCopy(null));\n-        sa.comment = comment;\n+        sa.addComment(comment);\n         sa.storage_class = storage_class;\n         return sa;\n     }\n@@ -512,7 +512,7 @@ extern (C++) class VarDeclaration : Declaration\n         //printf(\"VarDeclaration::syntaxCopy(%s)\\n\", toChars());\n         assert(!s);\n         auto v = new VarDeclaration(loc, type ? type.syntaxCopy() : null, ident, _init ? _init.syntaxCopy() : null, storage_class);\n-        v.comment = comment;\n+        v.addComment(comment);\n         return v;\n     }\n \n@@ -678,7 +678,7 @@ extern (C++) class BitFieldDeclaration : VarDeclaration\n         //printf(\"BitFieldDeclaration::syntaxCopy(%s)\\n\", toChars());\n         assert(!s);\n         auto bf = new BitFieldDeclaration(loc, type ? type.syntaxCopy() : null, ident, width.syntaxCopy(), _init ? _init.syntaxCopy() : null);\n-        bf.comment = comment;\n+        bf.addComment(comment);\n         return bf;\n     }\n \ndiff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d\nindex 201ab010ced..349f439ac2c 100644\n--- a/gcc/d/dmd/dimport.d\n+++ b/gcc/d/dmd/dimport.d\n@@ -95,7 +95,7 @@ extern (C++) final class Import : Dsymbol\n     {\n         assert(!s);\n         auto si = new Import(loc, packages, id, aliasId, isstatic);\n-        si.comment = comment;\n+        si.addComment(comment);\n         assert(!(isstatic && names.length));\n         if (names.length && !si.aliasId)\n             si.ident = null;\ndiff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d\nindex 1baf39b0751..de1c8f0a575 100644\n--- a/gcc/d/dmd/dmodule.d\n+++ b/gcc/d/dmd/dmodule.d\n@@ -707,7 +707,7 @@ extern (C++) final class Module : Package\n          */\n         if (buf.length>= 4 && buf[0..4] == \"Ddoc\")\n         {\n-            comment = buf.ptr + 4;\n+            this.addComment(buf.ptr + 4);\n             filetype = FileType.ddoc;\n             if (!docfile)\n                 setDocfile();\n@@ -720,7 +720,7 @@ extern (C++) final class Module : Package\n          */\n         if (FileName.equalsExt(arg, dd_ext))\n         {\n-            comment = buf.ptr; // the optional Ddoc, if present, is handled above.\n+            this.addComment(buf.ptr); // the optional Ddoc, if present, is handled above.\n             filetype = FileType.ddoc;\n             if (!docfile)\n                 setDocfile();\ndiff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d\nindex ed02ead4cf8..f61c2998195 100644\n--- a/gcc/d/dmd/dsymbol.d\n+++ b/gcc/d/dmd/dsymbol.d\n@@ -45,9 +45,7 @@ import dmd.statement;\n import dmd.staticassert;\n import dmd.tokens;\n import dmd.visitor;\n-\n import dmd.common.outbuffer;\n-\n /***************************************\n  * Calls dg(Dsymbol* sym) for each Dsymbol.\n  * If dg returns !=0, stops and returns that value else returns 0.\n@@ -100,6 +98,62 @@ void foreachDsymbol(Dsymbols* symbols, scope void delegate(Dsymbol) dg)\n     }\n }\n \n+private void addComment(Dsymbol d, const(char)* comment)\n+{\n+    scope v = new AddCommentVisitor(comment);\n+    d.accept(v);\n+}\n+\n+extern (C++) private class AddCommentVisitor: Visitor\n+{\n+    alias visit = Visitor.visit;\n+\n+    const(char)* comment;\n+\n+    this(const(char)* comment)\n+    {\n+        this.comment = comment;\n+    }\n+\n+    override void visit(Dsymbol d)\n+    {\n+        if (!comment || !*comment)\n+            return;\n+\n+        //printf(\"addComment '%s' to Dsymbol %p '%s'\\n\", comment, this, toChars());\n+        void* h = cast(void*)d;      // just the pointer is the key\n+        auto p = h in d.commentHashTable;\n+        if (!p)\n+        {\n+            d.commentHashTable[h] = comment;\n+            return;\n+        }\n+        if (strcmp(*p, comment) != 0)\n+        {\n+            // Concatenate the two\n+            import dmd.lexer;\n+            *p = Lexer.combineComments((*p).toDString(), comment.toDString(), true);\n+        }\n+    }\n+    override void visit(AttribDeclaration atd)\n+    {\n+        if (comment && atd.decl)\n+        {\n+            atd.decl.foreachDsymbol( s => s.addComment(comment) );\n+        }\n+    }\n+    override void visit(ConditionalDeclaration cd)\n+    {\n+        if (comment)\n+        {\n+            cd.decl    .foreachDsymbol( s => s.addComment(comment) );\n+            cd.elsedecl.foreachDsymbol( s => s.addComment(comment) );\n+        }\n+    }\n+    override void visit(StaticForeachDeclaration sfd) {}\n+}\n+\n+\n struct Visibility\n {\n     ///\n@@ -765,16 +819,6 @@ extern (C++) class Dsymbol : ASTNode\n         assert(0);\n     }\n \n-    /****************************************\n-     * Add documentation comment to Dsymbol.\n-     * Ignore NULL comments.\n-     */\n-    void addComment(const(char)* comment)\n-    {\n-        import dmd.dsymbolsem;\n-        dmd.dsymbolsem.addComment(this, comment);\n-    }\n-\n     /// get documentation comment for this Dsymbol\n     final const(char)* comment()\n     {\n@@ -786,10 +830,10 @@ extern (C++) class Dsymbol : ASTNode\n         }\n         return null;\n     }\n-\n-    /* Shell around addComment() to avoid disruption for the moment */\n-    final void comment(const(char)* comment) { addComment(comment); }\n-\n+    final void addComment(const(char)* c)\n+    {\n+        .addComment(this, c);\n+    }\n     extern (D) __gshared const(char)*[void*] commentHashTable;\n \n \n@@ -1072,7 +1116,7 @@ public:\n     {\n         //printf(\"ScopeDsymbol::syntaxCopy('%s')\\n\", toChars());\n         ScopeDsymbol sds = s ? cast(ScopeDsymbol)s : new ScopeDsymbol(ident);\n-        sds.comment = comment;\n+        sds.addComment(comment);\n         sds.members = arraySyntaxCopy(members);\n         sds.endlinnum = endlinnum;\n         return sds;\ndiff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h\nindex f6665c59223..44b88445fd4 100644\n--- a/gcc/d/dmd/dsymbol.h\n+++ b/gcc/d/dmd/dsymbol.h\n@@ -242,7 +242,6 @@ public:\n     virtual Visibility visible();\n     virtual Dsymbol *syntaxCopy(Dsymbol *s);    // copy only syntax trees\n \n-    virtual void addComment(const utf8_t *comment);\n     const utf8_t *comment();                      // current value of comment\n \n     UnitTestDeclaration *ddocUnittest();\ndiff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d\nindex 3e372b58e99..16709bc1136 100644\n--- a/gcc/d/dmd/dsymbolsem.d\n+++ b/gcc/d/dmd/dsymbolsem.d\n@@ -143,6 +143,15 @@ void addObjcSymbols(Dsymbol _this, ClassDeclarations* classes, ClassDeclarations\n         objc.addSymbols(cd, classes, categories);\n }\n \n+private void fixupInvariantIdent(InvariantDeclaration invd, size_t offset)\n+{\n+    OutBuffer idBuf;\n+    idBuf.writestring(\"__invariant\");\n+    idBuf.print(offset);\n+\n+    invd.ident = Identifier.idPool(idBuf[]);\n+}\n+\n /************************************\n  * Maybe `ident` was a C or C++ name. Check for that,\n  * and suggest the D equivalent.\n@@ -2268,6 +2277,152 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor\n             dsym.inuse--;\n             sc2.pop();\n         }\n+        static bool hasDollarDimension(TypeSArray tsa)\n+        {\n+            auto d = tsa.dim;\n+            if (!d)\n+                return false;\n+            auto ide = d.isIdentifierExp();\n+            if (!ide)\n+                return false;\n+            return ide.ident == Id.dollar;\n+        }\n+        static bool hasUnresolvedDollar(Type t)\n+        {\n+            auto tsa = t.isTypeSArray();\n+            if (!tsa)\n+                return false;\n+            if (hasDollarDimension(tsa))\n+                return true;\n+            return hasUnresolvedDollar(tsa.next);\n+        }\n+\n+        static void resolveDollarToZero(Type t, Loc loc)\n+        {\n+            auto tsa = t.isTypeSArray();\n+            if (!tsa)\n+                return;\n+            if (hasDollarDimension(tsa)) {\n+                tsa.dim = new IntegerExp(loc, 0, Type.tsize_t);\n+            }\n+            resolveDollarToZero(tsa.next, loc);\n+        }\n+\n+        static bool inferExprLength(Expression e, out dinteger_t len)\n+        {\n+            if (!e)\n+                return false;\n+\n+            if (auto ale = e.isArrayLiteralExp())\n+            {\n+                len = ale.elements.length;\n+                return true;\n+            }\n+\n+            if (auto ce = e.isCatExp())\n+            {\n+                dinteger_t l1;\n+                dinteger_t l2;\n+                if (inferExprLength(ce.e1, l1) && inferExprLength(ce.e2, l2))\n+                {\n+                    len = l1 + l2;\n+                    return true;\n+                }\n+            }\n+\n+            if (!e.type)\n+                return false;\n+\n+            auto tsan = e.type.toBasetype().isTypeSArray();\n+            if (!tsan)\n+                return false;\n+\n+            auto dim = tsan.dim.isIntegerExp();\n+            if (!dim)\n+                return false;\n+\n+            len = dim.value;\n+            return true;\n+        }\n+\n+        static bool inferSArrayDim(TypeSArray tsa, Expression ie, Loc loc, Scope* sc)\n+        {\n+            if (!tsa || !ie)\n+                return false;\n+\n+            if (!hasDollarDimension(tsa))\n+                return false;\n+\n+            if (auto ale = ie.isArrayLiteralExp())\n+            {\n+                dinteger_t len = ale.elements.length;\n+                tsa.dim = new IntegerExp(loc, len, Type.tsize_t);\n+                if (auto innerTsa = tsa.next.isTypeSArray())\n+                {\n+                    if (ale.elements.length > 0)\n+                    {\n+                        auto firstElem = (*ale.elements)[0];\n+                        inferSArrayDim(innerTsa, firstElem, loc, sc);\n+                    }\n+                }\n+                return true;\n+            }\n+            else if (auto se = ie.isStringExp())\n+            {\n+                Type next = tsa.next.toBasetype();\n+                if (next.ty == TY.Tchar || next.ty == TY.Twchar || next.ty == TY.Tdchar)\n+                {\n+                    tsa.dim = new IntegerExp(loc, se.len, Type.tsize_t);\n+                    return true;\n+                }\n+                return false;\n+            }\n+\n+            // For other initializer forms, infer `$` only when the extent is\n+            // compile-time known: either a concatenation whose operands are\n+            // inferable, or any expression whose type is a static array.\n+            dinteger_t len;\n+            if (!inferExprLength(ie, len))\n+                return false;\n+\n+            tsa.dim = new IntegerExp(loc, len, Type.tsize_t);\n+            return true;\n+        }\n+\n+        auto tsa = dsym.type.isTypeSArray();\n+\n+        if (tsa && hasDollarDimension(tsa))\n+        {\n+            if (!dsym._init || dsym._init.isVoidInitializer())\n+            {\n+                .error(dsym.loc, \"cannot infer static array length from `$`, provide an initializer\");\n+                tsa.dim = new IntegerExp(dsym.loc, 0, Type.tsize_t);\n+            }\n+            else\n+            {\n+                Expression ie = dsym._init.initializerToExpression(null, sc.inCfile);\n+                if (ie && ie.op != EXP.error)\n+                {\n+                    ie = ie.expressionSemantic(sc);\n+                    ie = ie.optimize(WANTvalue);\n+                    bool dimInferred = inferSArrayDim(tsa, ie, dsym.loc, sc);\n+                    if (!dimInferred)\n+                    {\n+                        .error(dsym.loc, \"cannot infer static array length from `$`, provide an initializer\");\n+                        tsa.dim = new IntegerExp(dsym.loc, 0, Type.tsize_t);\n+                    }\n+                    if (auto ale = ie.isArrayLiteralExp())\n+                        dsym._init = new ExpInitializer(dsym.loc, ale);\n+                }\n+            }\n+        }\n+        if (tsa && hasUnresolvedDollar(tsa.next))\n+        {\n+            .error(dsym.loc, \"cannot infer static array length from `$`, provide an initializer\");\n+            resolveDollarToZero(tsa.next, dsym.loc);\n+            return;\n+        }\n+\n         //printf(\" semantic type = %s\\n\", dsym.type ? dsym.type.toChars() : \"null\");\n         if (dsym.type.ty == Terror)\n             dsym.errors = true;\n@@ -3434,7 +3589,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor\n \n         sc = sc.push();\n         sc.stc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.gshared);\n-        sc.inunion = scd.isunion ? scd : null;\n+        sc.inunion = scd.isunion ? scd : sc.inunion;\n         sc.resetAllFlags();\n         for (size_t i = 0; i < scd.decl.length; i++)\n         {\n@@ -9244,60 +9399,6 @@ Lfail:\n     return false;\n }\n \n-void addComment(Dsymbol d, const(char)* comment)\n-{\n-    scope v = new AddCommentVisitor(comment);\n-    d.accept(v);\n-}\n-\n-extern (C++) class AddCommentVisitor: Visitor\n-{\n-    alias visit = Visitor.visit;\n-\n-    const(char)* comment;\n-\n-    this(const(char)* comment)\n-    {\n-        this.comment = comment;\n-    }\n-\n-    override void visit(Dsymbol d)\n-    {\n-        if (!comment || !*comment)\n-            return;\n-\n-        //printf(\"addComment '%s' to Dsymbol %p '%s'\\n\", comment, this, toChars());\n-        void* h = cast(void*)d;      // just the pointer is the key\n-        auto p = h in d.commentHashTable;\n-        if (!p)\n-        {\n-            d.commentHashTable[h] = comment;\n-            return;\n-        }\n-        if (strcmp(*p, comment) != 0)\n-        {\n-            // Concatenate the two\n-            *p = Lexer.combineComments((*p).toDString(), comment.toDString(), true);\n-        }\n-    }\n-    override void visit(AttribDeclaration atd)\n-    {\n-        if (comment)\n-        {\n-            atd.include(null).foreachDsymbol( s => s.addComment(comment) );\n-        }\n-    }\n-    override void visit(ConditionalDeclaration cd)\n-    {\n-        if (comment)\n-        {\n-            cd.decl    .foreachDsymbol( s => s.addComment(comment) );\n-            cd.elsedecl.foreachDsymbol( s => s.addComment(comment) );\n-        }\n-    }\n-    override void visit(StaticForeachDeclaration sfd) {}\n-}\n-\n void checkCtorConstInit(Dsymbol d)\n {\n     scope v = new CheckCtorConstInitVisitor();\ndiff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d\nindex 40f1f07cbbe..c2bcb0d491e 100644\n--- a/gcc/d/dmd/dtemplate.d\n+++ b/gcc/d/dmd/dtemplate.d\n@@ -299,44 +299,6 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol\n         this.visibility = Visibility(Visibility.Kind.undefined);\n     }\n \n-    extern(D) void computeIsTrivialAlias(Dsymbol s)\n-    {\n-        /* Set isTrivialAliasSeq if this fits the pattern:\n-         *   template AliasSeq(T...) { alias AliasSeq = T; }\n-         * or set isTrivialAlias if this fits the pattern:\n-         *   template Alias(T) { alias Alias = qualifiers(T); }\n-         */\n-        if (!(parameters && parameters.length == 1))\n-            return;\n-\n-        auto ad = s.isAliasDeclaration();\n-        if (!ad || !ad.type)\n-            return;\n-\n-        auto ti = ad.type.isTypeIdentifier();\n-\n-        if (!ti || ti.idents.length != 0)\n-            return;\n-\n-        if (auto ttp = (*parameters)[0].isTemplateTupleParameter())\n-        {\n-            if (ti.ident is ttp.ident &&\n-                ti.mod == 0)\n-            {\n-                //printf(\"found isTrivialAliasSeq %s %s\\n\", s.toChars(), ad.type.toChars());\n-                isTrivialAliasSeq = true;\n-            }\n-        }\n-        else if (auto ttp = (*parameters)[0].isTemplateTypeParameter())\n-        {\n-            if (ti.ident is ttp.ident)\n-            {\n-                //printf(\"found isTrivialAlias %s %s\\n\", s.toChars(), ad.type.toChars());\n-                isTrivialAlias = true;\n-            }\n-        }\n-    }\n-\n     override TemplateDeclaration syntaxCopy(Dsymbol)\n     {\n         //printf(\"TemplateDeclaration.syntaxCopy()\\n\");\ndiff --git a/gcc/d/dmd/dversion.d b/gcc/d/dmd/dversion.d\nindex 17d888b17ed..2036f783042 100644\n--- a/gcc/d/dmd/dversion.d\n+++ b/gcc/d/dmd/dversion.d\n@@ -39,7 +39,7 @@ extern (C++) final class DebugSymbol : Dsymbol\n     {\n         assert(!s);\n         auto ds = new DebugSymbol(loc, ident);\n-        ds.comment = comment;\n+        ds.addComment(comment);\n         return ds;\n     }\n \n@@ -75,7 +75,7 @@ extern (C++) final class VersionSymbol : Dsymbol\n     {\n         assert(!s);\n         auto ds = new VersionSymbol(loc, ident);\n-        ds.comment = comment;\n+        ds.addComment(comment);\n         return ds;\n     }\n \ndiff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h\nindex a8e1c9fb921..d3896125bd8 100644\n--- a/gcc/d/dmd/expression.h\n+++ b/gcc/d/dmd/expression.h\n@@ -62,6 +62,7 @@ namespace dmd\n     bool isIdentical(const Expression *exp, const Expression *e);\n     bool equals(const Expression *exp, const Expression *e);\n     bool isLvalue(Expression *exp);\n+    bool canElideCopy(Expression *exp, Type *to, bool checkMod = false);\n     int32_t getFieldIndex(ClassReferenceExp *cre, Type *fieldtype, uint32_t fieldoffset);\n     void fillTupleExpExps(TupleExp *te, TupleDeclaration *tup);\n     Optional<bool> toBool(Expression *exp);\ndiff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d\nindex 3dec8c5e749..840dc0fd957 100644\n--- a/gcc/d/dmd/expressionsem.d\n+++ b/gcc/d/dmd/expressionsem.d\n@@ -209,7 +209,14 @@ dinteger_t toInteger(Expression _this)\n     // import dmd.hdrgen : EXPtoString;\n     //printf(\"Expression %s\\n\", EXPtoString(op).ptr);\n     if (!_this.type || !_this.type.isTypeError())\n+    {\n+        if (auto ide = _this.isIdentifierExp())\n+        {\n+            if (ide.ident == Id.dollar)\n+                return 0;\n+        }\n         error(_this.loc, \"integer constant expression expected instead of `%s`\", _this.toChars());\n+    }\n     return 0;\n }\n \n@@ -681,8 +688,19 @@ bool isLvalue(Expression _this)\n         if (tf && tf.isRef)\n         {\n             if (auto dve = _this.e1.isDotVarExp())\n+            {\n                 if (dve.var.isCtorDeclaration())\n-                    return false;\n+                {\n+                    // Allow taking the address of explicit constructor calls,\n+                    // but not (__stmp = S(), __stmp).__ctor().\n+\n+                    auto ve = lastComma(dve.e1).isVarExp();\n+                    if (ve && (ve.var.storage_class & STC.temp) != 0)\n+                        return false;\n+\n+                    return isLvalue(dve.e1);\n+                }\n+            }\n             return true; // function returns a reference\n         }\n         return false;\n@@ -761,8 +779,13 @@ bool isLvalue(Expression _this)\n  * Determine if copy elision is allowed when copying an expression to\n  * a typed storage. This basically elides a restricted subset of so-called\n  * \"pure\" rvalues, i.e. expressions with no reference semantics.\n+ *\n+ * Note: Please avoid using `checkMod` parameter because `canElideCopy()`\n+ * essentially defines a value category and should eventually be merged with\n+ * `isLvalue()` to return [isLvalue, allowEmplacement].\n+ * Checking type compatibility here is only a stopgap measure.\n  */\n-bool canElideCopy(Expression e, Type to, bool checkMod = true)\n+bool canElideCopy(Expression e, Type to, bool checkMod = false)\n {\n     if (checkMod && !MODimplicitConv(e.type.mod, to.mod))\n         return false;\n@@ -770,8 +793,19 @@ bool canElideCopy(Expression e, Type to, bool checkMod = true)\n     static bool visitCallExp(CallExp e)\n     {\n         if (auto dve = e.e1.isDotVarExp())\n+        {\n             if (dve.var.isCtorDeclaration())\n-                return true;\n+            {\n+                // Allow (__stmp = S(), __stmp).__ctor() to be elided,\n+                // but force a copy for (s2 = s1.__ctor()).\n+\n+                auto ve = lastComma(dve.e1).isVarExp();\n+                if (ve && (ve.var.storage_class & STC.temp) != 0)\n+                    return true;\n+\n+                return canElideCopy(dve.e1, e.type);\n+            }\n+        }\n \n         auto tb = e.e1.type.toBasetype();\n         if (tb.ty == Tdelegate || tb.ty == Tpointer)\n@@ -791,7 +825,7 @@ bool canElideCopy(Expression e, Type to, bool checkMod = true)\n             return false;\n \n         // If an aggregate can be elided, so are its fields\n-        return canElideCopy(e.e1, e.e1.type, false);\n+        return canElideCopy(e.e1, e.e1.type);\n     }\n \n     switch (e.op)\n@@ -808,8 +842,7 @@ bool canElideCopy(Expression e, Type to, bool checkMod = true)\n         case EXP.dotVariable:\n             return visitDotVarExp(e.isDotVarExp());\n         case EXP.structLiteral:\n-            auto sle = e.isStructLiteralExp();\n-            return !(checkMod && sle.useStaticInit && to.isMutable());\n+            return true;\n         case EXP.variable:\n             return (e.isVarExp().var.storage_class & STC.rvalue) != 0;\n         default:\n@@ -1921,7 +1954,7 @@ extern (D) Expression doCopyOrMove(Scope* sc, Expression e, Type t, bool nrvo, b\n     {\n         e = callCpCtor(sc, e, t, nrvo);\n     }\n-    else if (move && sd && sd.hasMoveCtor && !canElideCopy(e, t ? t : e.type, false))\n+    else if (move && sd && sd.hasMoveCtor && !canElideCopy(e, t ? t : e.type))\n     {\n         // #move\n         /* Rewrite as:\n@@ -3378,21 +3411,31 @@ private bool checkSafety(FuncDeclaration f, ref Loc loc, Scope* sc, Expressions*\n         return false;\n     }\n \n-    if (f.printf)\n+    if (f.printf && (f.isSafe() || f.isTrusted()))\n     {\n         TypeFunction tf = f.type.isTypeFunction();\n         assert(tf);\n         const isVa_list = tf.parameterList.varargs == VarArg.none;\n         const nparams = tf.parameterList.length;\n         const nargs = arguments ? arguments.length : 0;\n-        if (nparams == 1 && nargs)\n+        assert(nparams && nargs); // should have been verified already\n+        if (auto se = (*arguments)[nparams - 1 - isVa_list].isStringExp())\n         {\n-            if (auto se = (*arguments)[nparams - 1 - isVa_list].isStringExp())\n+            if (!isFormatSafe(se.peekString()))\n             {\n-                if (isFormatSafe(se.peekString()))\n-                    return false;\n+                if (sc.setUnsafe(false, loc,\n+                    \"calling `pragma(printf)` function `%s` with format string `%s`\", f, se))\n+                    .errorSupplemental(f.loc, \"`%s` is declared here\", f.toPrettyChars());\n+                return true;\n             }\n         }\n+        else\n+        {\n+            if (sc.setUnsafe(false, loc,\n+                \"calling `pragma(printf)` function `%s` with non-literal format string\", f))\n+                .errorSupplemental(f.loc, \"`%s` is declared here\", f.toPrettyChars());\n+            return true;\n+        }\n     }\n \n     if (!f.isSafe() && !f.isTrusted())\n@@ -5809,8 +5852,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n             {\n                 arguments.push(makeTemplateItem(Id.InterpolatedExpression, str));\n                 Expressions* mix = new Expressions(new StringExp(e.loc, str));\n-                // FIXME: i'd rather not use MixinExp but idk how to do it lol\n-                arguments.push(new MixinExp(e.loc, mix));\n+                auto mixinExp = new MixinExp(e.loc, mix);\n+                auto res = mixinExp.expressionSemantic(sc);\n+                res = resolveProperties(sc, res);\n+                arguments.push(res);\n             }\n         }\n \n@@ -6959,8 +7004,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n \n             if (!global.params.useGC && sc.needsCodegen())\n             {\n-                error(exp.loc, \"expression `%s` allocates with the GC and cannot be used with switch `-%s`\", exp.toErrMsg(), SwitchVariadic.ptr);\n-                return setError();\n+                if (sc.func)\n+                {\n+                    sc.func.skipCodegen = true; // same net result as calling checkGC\n+                    goto LskipNewArrayLowering; // not checked in sc.needsCodegen() !?\n+                }\n             }\n \n             if (!sc.needsCodegen())\n@@ -8483,7 +8531,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n             {\n                 exp.type = tf.next;\n                 auto casted_exp = exp.castTo(sc, t);\n-                if (auto cex = casted_exp.isCastExp())\n+                if (auto cex = lastComma(casted_exp).isCastExp())\n                 {\n                     lowerCastExp(cex, sc);\n                 }\n@@ -10900,7 +10948,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n             }\n         }\n \n-        if (auto cex = ex.isCastExp())\n+        if (auto cex = lastComma(ex).isCastExp())\n         {\n             lowerCastExp(cex, sc);\n         }\n@@ -12398,7 +12446,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n                                 }\n \n                                 /* Rewrite as:\n-                                 *  (e1 = e2).postblit();\n+                                 *  (e1 = e2).postblit(), e1;\n                                  *\n                                  * Blit assignment e1 = e2 returns a reference to the original e1,\n                                  * then call the postblit on it.\n@@ -12410,6 +12458,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n                                 e = new BlitExp(exp.loc, e, e2x);\n                                 e = new DotVarExp(exp.loc, e, sd.postblit, false);\n                                 e = new CallExp(exp.loc, e);\n+                                e = new CommaExp(exp.loc, e, e1x);\n                                 result = e.expressionSemantic(sc);\n                                 return;\n                             }\n@@ -15045,12 +15094,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor\n             return;\n         }\n \n-        // When array comparison is not lowered to `__equals`, `memcmp` is used, but\n-        // GC checks occur before the expression is lowered to `memcmp` in e2ir.d.\n-        // Thus, we will consider the literal arrays as on-stack arrays to avoid issues\n-        // during GC checks.\n+        // Remaining array comparisons are trivially memcmp-able.\n+        // Allocate array-literal operands on the stack, since they don't\n+        // escape during the comparison; enabling @nogc for these.\n         if (isArrayComparison)\n         {\n+            exp.e1 = exp.e1.optimize(WANTvalue);\n+            exp.e2 = exp.e2.optimize(WANTvalue);\n+\n             if (auto ale1 = exp.e1.isArrayLiteralExp())\n             {\n                 ale1.onstack = true;\n@@ -16642,6 +16693,8 @@ bool checkValue(Expression e)\n  */\n bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)\n {\n+    Expression root = e;\n+\n     if (!sc ||\n         !sc.previews.noSharedAccess ||\n         sc.intypeof ||\n@@ -16697,7 +16750,14 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)\n             if (e.placement)\n                 check(e.placement, false);\n             if (e.thisexp)\n-                check(e.thisexp, false);\n+            {\n+                // In a shared constructor, accessing the current\n+                // `this` is safe for nested allocation.\n+                // See test_nosharedaccess_ctor_nested_new.d\n+                if (!(sc.func && sc.func.isCtorDeclaration() && sc.func.type.isShared() &&\n+                      e.thisexp.isThisExp()))\n+                    check(e.thisexp, false);\n+            }\n             return false;\n         }\n \n@@ -16812,6 +16872,12 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)\n             case EXP.star:        return visitPtr(e.isPtrExp());\n             case EXP.dotVariable: return visitDotVar(e.isDotVarExp());\n             case EXP.index:       return visitIndex(e.isIndexExp());\n+            case EXP.structLiteral:\n+                // Allow constructing a shared struct literal as a value,\n+                // but keep rejecting later accesses through that temporary.\n+                if (e is root && e.type && e.type.isShared())\n+                    return false;\n+                return visit(e);\n         }\n     }\n \n@@ -19696,12 +19762,12 @@ private Expression buildAAIndexRValueX(Type t, Expression eaa, Expression ekey,\n     auto call = new CallExp(loc, func, arguments);\n     e0 = Expression.combine(e0, call);\n \n-    if (arrayBoundsCheck(sc.func))\n+    if (sc.func && arrayBoundsCheck(sc.func))\n     {\n         // __aaget = _d_aaGetRvalueX(aa, key), __aaget ? __aaget : onRangeError(__FILE__, __LINE__)\n         auto ei = new ExpInitializer(loc, e0);\n-        auto vartmp = Identifier.generateId(\"__aaget\");\n-        auto vardecl = new VarDeclaration(loc, null, vartmp, ei, STC.exptemp);\n+        auto id = Identifier.generateId(\"__aaget\");\n+        auto vardecl = new VarDeclaration(loc, null, id, ei, STC.exptemp);\n         auto declexp = new DeclarationExp(loc, vardecl);\n \n         //Expression idrange = new IdentifierExp(loc, Identifier.idPool(\"_d_arraybounds\"));\n@@ -19711,9 +19777,9 @@ private Expression buildAAIndexRValueX(Type t, Expression eaa, Expression ekey,\n         auto locargs = new Expressions(new FileInitExp(loc, EXP.file), new LineInitExp(loc));\n         auto ex = new CallExp(loc, idrange, locargs);\n \n-        auto idvar1 = new IdentifierExp(loc, vartmp);\n-        auto idvar2 = new IdentifierExp(loc, vartmp);\n-        auto cond = new CondExp(loc, idvar1, idvar2, ex);\n+        auto ve1 = new VarExp(loc, vardecl);\n+        auto ve2 = new VarExp(loc, vardecl);\n+        auto cond = new CondExp(loc, ve1, ve2, ex);\n         auto comma = new CommaExp(loc, declexp, cond);\n         return comma;\n     }\n@@ -19746,6 +19812,26 @@ Expression revertIndexAssignToRvalues(IndexExp ie, Scope* sc)\n     return lowerAAIndexRead(ie, sc);\n }\n \n+// Ditto, but traverses DotVarExp from `alias this` rewrites.\n+private Expression revertModifiableAAIndexReads(Expression e, Scope* sc)\n+{\n+    // Recurse through dot-accesses (alias this produces DotVarExp on an inner IndexExp)\n+    if (auto dve = e.isDotVarExp())\n+    {\n+        dve.e1 = revertModifiableAAIndexReads(dve.e1, sc);\n+        return e;\n+    }\n+    if (auto ie = e.isIndexExp())\n+    {\n+        // Recurse first to handle deeper nesting\n+        ie.e1 = revertModifiableAAIndexReads(ie.e1, sc);\n+        // Lower a modifiable AA IndexExp to an rvalue read\n+        if (ie.modifiable && ie.e1.type.isTypeAArray())\n+            return lowerAAIndexRead(ie, sc);\n+    }\n+    return e;\n+}\n+\n // helper for rewriteAAIndexAssign\n private Expression implicitConvertToStruct(Expression ev, StructDeclaration sd, Scope* sc)\n {\n@@ -19796,6 +19882,7 @@ private Expression rewriteAAIndexAssign(BinExp exp, Scope* sc, ref Type[2] alias\n     // find the AA of multi dimensional access\n     for (auto ieaa = ie.e1.isIndexExp(); ieaa && ieaa.e1.type.isTypeAArray(); ieaa = ieaa.e1.isIndexExp())\n         eaa = ieaa.e1;\n+    eaa = revertModifiableAAIndexReads(eaa, sc);\n     eaa = extractSideEffect(sc, \"__aatmp\", e0, eaa);\n     // collect all keys of multi dimensional access\n     Expressions ekeys;\n@@ -19834,7 +19921,7 @@ private Expression rewriteAAIndexAssign(BinExp exp, Scope* sc, ref Type[2] alias\n         auto tiargs = new Objects(taa.index, taa.next);\n         func = new DotTemplateInstanceExp(loc, func, hook, tiargs);\n \n-        auto arguments = new Expressions(eaa, ekeys[i-1], new IdentifierExp(loc, idfound));\n+        auto arguments = new Expressions(eaa, ekeys[i-1], new VarExp(loc, varfound));\n         eaa = new CallExp(loc, func, arguments);\n         if (i > 1)\n         {\n@@ -19891,7 +19978,7 @@ private Expression rewriteAAIndexAssign(BinExp exp, Scope* sc, ref Type[2] alias\n                 ex = new CastExp(ex.loc, ex, Type.tvoid);\n                 ey = new CastExp(ey.loc, ey, Type.tvoid);\n             }\n-            Expression condfound = new IdentifierExp(loc, idfound);\n+            Expression condfound = new VarExp(loc, varfound);\n             ex = new CondExp(loc, condfound, ex, ey);\n             ex = Expression.combine(e0, ex);\n             ex.isCommaExp().originalExp = exp;\ndiff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d\nindex 1f902e4f184..a2ccc4c2256 100644\n--- a/gcc/d/dmd/func.d\n+++ b/gcc/d/dmd/func.d\n@@ -1116,15 +1116,6 @@ extern (C++) final class InvariantDeclaration : FuncDeclaration\n     {\n         v.visit(this);\n     }\n-\n-    extern (D) void fixupInvariantIdent(size_t offset)\n-    {\n-        OutBuffer idBuf;\n-        idBuf.writestring(\"__invariant\");\n-        idBuf.print(offset);\n-\n-        ident = Identifier.idPool(idBuf[]);\n-    }\n }\n \n \ndiff --git a/gcc/d/dmd/funcsem.d b/gcc/d/dmd/funcsem.d\nindex e153e11067e..31b6397ecf5 100644\n--- a/gcc/d/dmd/funcsem.d\n+++ b/gcc/d/dmd/funcsem.d\n@@ -2769,6 +2769,7 @@ void buildResultVar(FuncDeclaration fd, Scope* sc, Type tret)\n          * fbody.dsymbolSemantic() running, vresult.type might be modified.\n          */\n         fd.vresult = new VarDeclaration(loc, tret, Id.result, null);\n+        fd.vresult._init = new VoidInitializer(loc); // hdrgen requires _init\n         fd.vresult.storage_class |= STC.nodtor | STC.temp;\n         if (!fd.isVirtual())\n             fd.vresult.storage_class |= STC.const_;\n@@ -2779,7 +2780,7 @@ void buildResultVar(FuncDeclaration fd, Scope* sc, Type tret)\n     if (sc && fd.vresult.semanticRun == PASS.initial)\n     {\n         TypeFunction tf = fd.type.toTypeFunction();\n-        if (tf.isRef)\n+        if (fd.isNRVO || tf.isRef)\n             fd.vresult.storage_class |= STC.ref_;\n         else if (target.isReturnOnStack(tf, fd.needThis()))\n             fd.vresult.nrvo = true;\ndiff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d\nindex 7b50af1685f..71e94c2a90c 100644\n--- a/gcc/d/dmd/hdrgen.d\n+++ b/gcc/d/dmd/hdrgen.d\n@@ -58,6 +58,7 @@ struct HdrGenState\n     bool fullDump;      /// true if generating a full AST dump file\n     bool importcHdr;    /// true if generating a .di file from an ImportC file\n     bool inCAlias;      /// Set to prevent ImportC translating typedefs as `alias X = X`\n+    bool inFuncReturn;  /// Set when printing function return type to avoid typedef name\n     bool doFuncBodies;  /// include function bodies in output\n     bool vcg_ast;       /// write out codegen-ast\n     bool skipConstraints;  // skip constraints when doing templates\n@@ -4096,7 +4097,9 @@ private void visitFuncIdentWithPostfix(TypeFunction t, const char[] ident, ref O\n         buf.write(\"static \");\n     if (t.next)\n     {\n+        hgs.inFuncReturn = true;\n         typeToBuffer(t.next, null, buf, hgs);\n+        hgs.inFuncReturn = false;\n         if (ident)\n             buf.put(' ');\n     }\n@@ -4165,7 +4168,9 @@ private void visitFuncIdentWithPrefix(TypeFunction t, const Identifier ident, Te\n     }\n     else if (t.next)\n     {\n+        hgs.inFuncReturn = true;\n         typeToBuffer(t.next, null, buf, hgs);\n+        hgs.inFuncReturn = false;\n         if (ident)\n             buf.put(' ');\n     }\n@@ -4547,7 +4552,7 @@ private void typeToBufferx(Type t, ref OutBuffer buf, ref HdrGenState hgs)\n         buf.put(\"noreturn\");\n     }\n \n-    if (hgs.importcHdr && !hgs.inCAlias && t.mcache && t.mcache.typedefIdent)\n+    if (hgs.importcHdr && !hgs.inCAlias && !hgs.inFuncReturn && t.mcache && t.mcache.typedefIdent)\n     {\n         buf.put(t.mcache.typedefIdent.toString());\n         return;\ndiff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d\nindex beb3de62b35..2b814a8074d 100644\n--- a/gcc/d/dmd/id.d\n+++ b/gcc/d/dmd/id.d\n@@ -418,6 +418,7 @@ immutable Msgtable[] msgtable =\n     { \"isAbstractClass\" },\n     { \"isArithmetic\" },\n     { \"isAssociativeArray\" },\n+    { \"isOverlapped\" },\n     { \"isBitfield\" },\n     { \"isFinalClass\" },\n     { \"isTemplate\" },\n@@ -483,6 +484,7 @@ immutable Msgtable[] msgtable =\n     { \"isCopyable\" },\n     { \"toType\" },\n     { \"parameters\" },\n+    { \"needsDestruction\" },\n \n     // For C++ mangling\n     { \"allocator\" },\n@@ -498,6 +500,7 @@ immutable Msgtable[] msgtable =\n     { \"udaOptional\", \"optional\"},\n     { \"udaMustUse\", \"mustuse\" },\n     { \"udaStandalone\", \"standalone\" },\n+    { \"udaSection\", \"section\" },\n \n     // Editions\n     { \"__edition_latest_do_not_use\", },\n@@ -540,6 +543,9 @@ immutable Msgtable[] msgtable =\n     { \"undef\" },\n     { \"ident\" },\n     { \"packed\" },\n+\n+    // for inline assembler\n+    { \"op\" },\n ];\n \n \ndiff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d\nindex 21ad68fb6ce..644577f72af 100644\n--- a/gcc/d/dmd/initsem.d\n+++ b/gcc/d/dmd/initsem.d\n@@ -1468,6 +1468,22 @@ Expression initializerToExpression(Initializer init, Type itype = null, const bo\n             }\n         }\n \n+        // enforce the element type only if the dimensions match, otherwise the value\n+        // might be used as an initializer for the whole array at another dimension\n+        Type isTypeArray(Type tn)\n+        {\n+            auto ty = tn ? tn.ty : Tnone;\n+            return ty == Tarray || ty == Tsarray || ty == Taarray || ty == Tvector ? tn : null;\n+        }\n+        Type tnext = isTypeArray(itype);\n+        auto initn = init;\n+        while (tnext && initn)\n+        {\n+            tnext = isTypeArray(tnext.nextOf());\n+            initn = initn.value.length ? initn.value[0].isArrayInitializer() : null;\n+        }\n+        Type telem = itype && !tnext && !initn ? itype.nextOf() : null;\n+\n         auto elements = new Expressions(edim);\n         elements.zero();\n         size_t j = 0;\n@@ -1478,7 +1494,7 @@ Expression initializerToExpression(Initializer init, Type itype = null, const bo\n             assert(j < edim);\n             if (Initializer iz = init.value[i])\n             {\n-                if (Expression ex = iz.initializerToExpression(null, isCfile))\n+                if (Expression ex = iz.initializerToExpression(telem, isCfile))\n                 {\n                     (*elements)[j] = ex;\n                     ++j;\ndiff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d\nindex b5b82a91df6..c51fdf6123e 100644\n--- a/gcc/d/dmd/lexer.d\n+++ b/gcc/d/dmd/lexer.d\n@@ -62,7 +62,11 @@ struct CompileEnv\n  */\n class Lexer\n {\n-    private __gshared OutBuffer stringbuffer;\n+    private __gshared\n+    {\n+        OutBuffer stringbuffer;\n+        OutBuffer stringbuffersecondary; // functions that use stringbuffer can call scan that needs this.\n+    }\n \n     BaseLoc* baseLoc;       // Used to generate `scanloc`, which is just an index into this data structure\n     Loc scanloc;            // for error messages\n@@ -1431,7 +1435,7 @@ class Lexer\n                     p++;\n                     break;\n                 default:\n-                    if (isalpha(*p) || (p != idstart && isdigit(*p)))\n+                    if (isAlphaASCII(*p) || (p != idstart && isdigit(*p)))\n                         continue;\n                     error(loc, \"unterminated named entity &%.*s;\", cast(int)(p - idstart + 1), idstart);\n                     c = '?';\n@@ -1766,7 +1770,7 @@ class Lexer\n         uint blankrol = 0;\n         uint startline = 0;\n         p++;\n-        stringbuffer.setsize(0);\n+        stringbuffersecondary.setsize(0);\n         while (1)\n         {\n             const s = p;\n@@ -1785,7 +1789,7 @@ class Lexer\n                 }\n                 if (hereid)\n                 {\n-                    stringbuffer.writeUTF8(c);\n+                    stringbuffersecondary.writeUTF8(c);\n                     continue;\n                 }\n                 break;\n@@ -1825,7 +1829,7 @@ class Lexer\n                     delimright = ']';\n                 else if (c == '<')\n                     delimright = '>';\n-                else if (isalpha(c) || c == '_' || (c >= 0x80 && charLookup.isStart(c)))\n+                else if (isAlphaASCII(c) || c == '_' || (c >= 0x80 && charLookup.isStart(c)))\n                 {\n                     // Start of identifier; must be a heredoc\n                     Token tok;\n@@ -1875,7 +1879,7 @@ class Lexer\n                     goto Ldone;\n \n                 // we're looking for a new identifier token\n-                if (startline && (isalpha(c) || c == '_' || (c >= 0x80 && charLookup.isStart(c))) && hereid)\n+                if (startline && (isAlphaASCII(c) || c == '_' || (c >= 0x80 && charLookup.isStart(c))) && hereid)\n                 {\n                     Token tok;\n                     auto psave = p;\n@@ -1890,7 +1894,7 @@ class Lexer\n                     }\n                     p = psave;\n                 }\n-                stringbuffer.writeUTF8(c);\n+                stringbuffersecondary.writeUTF8(c);\n                 startline = 0;\n             }\n         }\n@@ -1903,7 +1907,7 @@ class Lexer\n             error(\"delimited string must end in `\\\"`\");\n         else\n             error(token.loc, \"delimited string must end in `%c\\\"`\", delimright);\n-        result.setString(stringbuffer);\n+        result.setString(stringbuffersecondary);\n         stringPostfix(result);\n     }\n \n@@ -2404,7 +2408,7 @@ class Lexer\n             case '.':\n                 if (p[1] == '.')\n                     goto Ldone; // if \"..\"\n-                if (isalpha(p[1]) || p[1] == '_' || p[1] & 0x80)\n+                if (isAlphaASCII(p[1]) || p[1] == '_' || p[1] & 0x80)\n                 {\n                     if (Ccompile && (p[1] == 'f' || p[1] == 'F' || p[1] == 'l' || p[1] == 'L'))\n                         goto Lreal;  // if `0.f` or `0.L`\n@@ -2477,7 +2481,7 @@ class Lexer\n             case '.':\n                 if (p[1] == '.')\n                     goto Ldone; // if \"..\"\n-                if (base <= 10 && n > 0 && (isalpha(p[1]) || p[1] == '_' || p[1] & 0x80))\n+                if (base <= 10 && n > 0 && (isAlphaASCII(p[1]) || p[1] == '_' || p[1] & 0x80))\n                 {\n                     if (Ccompile && base == 10 &&\n                         (p[1] == 'e' || p[1] == 'E' || p[1] == 'f' || p[1] == 'F' || p[1] == 'l' || p[1] == 'L'))\ndiff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d\nindex 74364d05e3f..a64502bb6cf 100644\n--- a/gcc/d/dmd/mtype.d\n+++ b/gcc/d/dmd/mtype.d\n@@ -404,6 +404,10 @@ extern (C++) abstract class Type : ASTNode\n          * we bank on the idea that usually only one of variants exist.\n          * It will also speed up code because these are rarely referenced and\n          * so need not be in the cache.\n+         *\n+         * NOTE: The cache stores the naked type at the \"identity\" position.\n+         * For example, a \"shared const T\" type will have its naked \"T\" type\n+         * in the field \"scto\". See also: dmd.typesem.nakedOf(Type).\n          */\n         Type cto;       // MODFlags.const_\n         Type ito;       // MODFlags.immutable_\ndiff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d\nindex c9b8a0275b8..e8dde1414be 100644\n--- a/gcc/d/dmd/nogc.d\n+++ b/gcc/d/dmd/nogc.d\n@@ -294,16 +294,20 @@ Expression checkGC(Expression e, Scope* sc)\n     return e;\n }\n \n-extern (D) void printGCUsage(FuncDeclaration fd, Loc loc, const(char)* warn)\n+/// Returns: whether GC usage inside `fd` should be printed for the -vgc flag\n+extern (D) bool vgcEnabled(FuncDeclaration fd)\n {\n     if (!global.params.v.gc)\n-        return;\n+        return false;\n \n     Module m = fd.getModule();\n-    if (m && m.isRoot() && !fd.inUnittest())\n-    {\n+    return (m && m.isRoot() && !fd.inUnittest());\n+}\n+\n+extern (D) void printGCUsage(FuncDeclaration fd, Loc loc, const(char)* warn)\n+{\n+    if (vgcEnabled(fd))\n         message(loc, \"vgc: %s\", warn);\n-    }\n }\n \n /**\ndiff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d\nindex c8ca3a1a0f2..1bdcf44c338 100644\n--- a/gcc/d/dmd/parse.d\n+++ b/gcc/d/dmd/parse.d\n@@ -79,6 +79,21 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer\n         this.doUnittests = doUnittests;\n     }\n \n+    /** Instead of parsing text to get tokens, provide a list of tokens ending with null.\n+     * Note that the token list will be consumed (added to the tokenFreelist) by the lexer4.\n+     * Params:\n+     *    pToken = pointer to first token in list, take ownership of list\n+     *    linnum = line number to use for the tokens\n+     */\n+    extern (D)\n+    void setTokenList(ref Token* pToken, int linnum)\n+    {\n+        this.token = *pToken;\n+        pToken = null;          // take ownership\n+        this.baseLoc.startLine = linnum;\n+        this.linnum = linnum;\n+    }\n+\n     /++\n      + Parse a module, i.e. the optional `module x.y.z` declaration and all declarations\n      + found in the current file.\ndiff --git a/gcc/d/dmd/root/ctfloat.d b/gcc/d/dmd/root/ctfloat.d\nindex 87cac4c3501..f8ffdd009a4 100644\n--- a/gcc/d/dmd/root/ctfloat.d\n+++ b/gcc/d/dmd/root/ctfloat.d\n@@ -25,8 +25,12 @@ extern (C++) struct CTFloat\n \n     version (GNU)\n         enum yl2x_supported = false;\n+    else version (AArch64)\n+        enum yl2x_supported = false;\t// no x87 FPU\n     else\n-        enum yl2x_supported = __traits(compiles, core.math.yl2x(1.0L, 2.0L));\n+        enum yl2x_supported = is(real_t == real) &&\n+                              __traits(compiles, core.math.yl2x(1.0L, 2.0L));\n+\n     enum yl2xp1_supported = yl2x_supported;\n \n     pure static real_t fabs(real_t x);\ndiff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d\nindex 15677f1fc6f..c02bb86db73 100644\n--- a/gcc/d/dmd/semantic3.d\n+++ b/gcc/d/dmd/semantic3.d\n@@ -961,8 +961,10 @@ private extern(C++) final class Semantic3Visitor : Visitor\n \n                             /* https://issues.dlang.org/show_bug.cgi?id=10789\n                              * If NRVO is not possible, all returned lvalues should call their postblits.\n+                             * For functions with a __result variable, postblits will be called later\n+                             * during initialization of __result.\n                              */\n-                            if (!funcdecl.isNRVO)\n+                            if (!funcdecl.isNRVO && !funcdecl.vresult)\n                                 exp = doCopyOrMove(sc2, exp, f.next, true, true);\n \n                             if (tret.hasPointers())\n@@ -973,13 +975,25 @@ private extern(C++) final class Semantic3Visitor : Visitor\n \n                         if (funcdecl.vresult)\n                         {\n-                            // Create: return vresult = exp;\n-                            if (canElideCopy(exp, funcdecl.vresult.type, false))\n-                                exp = new ConstructExp(rs.loc, funcdecl.vresult, exp);\n-                            else\n-                                exp = new BlitExp(rs.loc, funcdecl.vresult, exp);\n+                            Scope* scret = sc2;\n+\n+                            if (rs.fesFunc)\n+                            {\n+                                // Create a scope with foreach body being `.parent`\n+                                // and `funcdecl` as `.func`. So the return value\n+                                // is aware of closure access, but picks up\n+                                // attributes and instantiates templated copy/move\n+                                // ctors in the context of `funcdecl`.\n+                                // BUG: remove this fragile hack\n+                                scret = rs.fesFunc._scope.push();\n+                                scret.parent = rs.fesFunc;\n+                                scret.func = funcdecl;\n+                            }\n \n-                            exp.type = funcdecl.vresult.type;\n+                            // Create: return (vresult = exp, vresult);\n+                            exp = new ConstructExp(rs.loc, funcdecl.vresult, exp);\n+                            exp = exp.expressionSemantic(scret);\n+                            exp = Expression.combine(exp, new VarExp(rs.loc, funcdecl.vresult));\n \n                             if (rs.caseDim)\n                                 exp = Expression.combine(exp, new IntegerExp(rs.caseDim));\n@@ -1888,9 +1902,32 @@ extern (D) bool checkClosure(FuncDeclaration fd)\n     else\n     {\n         fd.printGCUsage(fd.loc, \"using closure causes GC allocation\");\n+\n+        findClosureVars(fd, (FuncDeclaration f, VarDeclaration v) {\n+            if (!fd.vgcEnabled)\n+                return;\n+\n+            .message(f.loc, \"vgc: %s `%s` closes over variable `%s`\",\n+                f.kind, f.toErrMsg(), v.toErrMsg());\n+            if (v.ident != Id.This)\n+                .message(v.loc, \"vgc: `%s` declared here\", v.toErrMsg());\n+        });\n         return false;\n     }\n \n+    findClosureVars(fd, (FuncDeclaration f, VarDeclaration v) {\n+        .errorSupplemental(f.loc, \"%s `%s` closes over variable `%s`\",\n+            f.kind, f.toErrMsg(), v.toErrMsg());\n+        if (v.ident != Id.This)\n+            .errorSupplemental(v.loc, \"`%s` declared here\", v.toErrMsg());\n+    });\n+    return true;\n+}\n+\n+/// For an outer function `fd`, find inner functions that cause a closure to be generated for it.\n+/// Pass to `sink` each nested function along with the local variable that closes over `fd`'s stackframe\n+private void findClosureVars(FuncDeclaration fd, scope void delegate(FuncDeclaration, VarDeclaration) sink)\n+{\n     FuncDeclarations a;\n \n     if (fd.closureVars.length > 0)\n@@ -1913,16 +1950,11 @@ extern (D) bool checkClosure(FuncDeclaration fd)\n                     if (!a.contains(f))\n                     {\n                         a.push(f);\n-                        .errorSupplemental(f.loc, \"%s `%s` closes over variable `%s`\",\n-                            f.kind, f.toErrMsg(), v.toChars());\n-                        if (v.ident != Id.This)\n-                            .errorSupplemental(v.loc, \"`%s` declared here\", v.toChars());\n+                        sink(f, v);\n                     }\n                     break LcheckAncestorsOfANestedRef;\n                 }\n             }\n         }\n     }\n-\n-    return true;\n }\ndiff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d\nindex 0641c0a85ce..ff162aa79b7 100644\n--- a/gcc/d/dmd/statement.d\n+++ b/gcc/d/dmd/statement.d\n@@ -1308,6 +1308,7 @@ extern (C++) final class ReturnStatement : Statement\n {\n     Expression exp;\n     size_t caseDim;\n+    FuncDeclaration fesFunc; // nested function for foreach it is in\n \n     extern (D) this(Loc loc, Expression exp) @safe\n     {\ndiff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h\nindex d49f4e47dbe..7074052fd2e 100644\n--- a/gcc/d/dmd/statement.h\n+++ b/gcc/d/dmd/statement.h\n@@ -518,6 +518,7 @@ class ReturnStatement final : public Statement\n public:\n     Expression *exp;\n     size_t caseDim;\n+    FuncDeclaration *fesFunc;   // nested function for foreach it is in\n \n     ReturnStatement *syntaxCopy() override;\n \ndiff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d\nindex d602f8d30e6..2f7b442d3a5 100644\n--- a/gcc/d/dmd/statementsem.d\n+++ b/gcc/d/dmd/statementsem.d\n@@ -1657,7 +1657,8 @@ Statement statementSemanticVisit(Statement s, Scope* sc)\n             /* Declare param, which we will set to be the\n              * result of condition.\n              */\n-            auto ei = new ExpInitializer(ifs.loc, ifs.condition);\n+            // Make sure the location of the initializer reflects the condition, not the if statement.\n+            auto ei = new ExpInitializer(ifs.condition.loc, ifs.condition);\n             ifs.match = new VarDeclaration(ifs.loc, ifs.param.type, ifs.param.ident, ei);\n             ifs.match.parent = scd.func;\n             ifs.match.storage_class |= ifs.param.storageClass;\n@@ -2480,8 +2481,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)\n         //printf(\"ReturnStatement.dsymbolSemantic() %s\\n\", toChars(rs));\n \n         FuncDeclaration fd = sc.parent.isFuncDeclaration();\n+\n         if (fd.fes)\n+        {\n+            rs.fesFunc = fd;\n             fd = fd.fes.func; // fd is now function enclosing foreach\n+        }\n \n         auto tf = fd.type.isTypeFunction();\n \ndiff --git a/gcc/d/dmd/templatesem.d b/gcc/d/dmd/templatesem.d\nindex a2bed8a7cd1..304a7a8fd1f 100644\n--- a/gcc/d/dmd/templatesem.d\n+++ b/gcc/d/dmd/templatesem.d\n@@ -47,6 +47,7 @@ import dmd.mtype;\n import dmd.opover;\n import dmd.optimize;\n import dmd.root.array;\n+import dmd.root.string : toDString;\n import dmd.common.outbuffer;\n import dmd.rootobject;\n import dmd.semantic2;\n@@ -455,6 +456,44 @@ void computeOneMember(TemplateDeclaration td)\n     }\n }\n \n+private void computeIsTrivialAlias(TemplateDeclaration td, Dsymbol s)\n+{\n+    /* Set isTrivialAliasSeq if this fits the pattern:\n+     *   template AliasSeq(T...) { alias AliasSeq = T; }\n+     * or set isTrivialAlias if this fits the pattern:\n+     *   template Alias(T) { alias Alias = qualifiers(T); }\n+     */\n+    if (!(td.parameters && td.parameters.length == 1))\n+        return;\n+\n+    auto ad = s.isAliasDeclaration();\n+    if (!ad || !ad.type)\n+        return;\n+\n+    auto ti = ad.type.isTypeIdentifier();\n+\n+    if (!ti || ti.idents.length != 0)\n+        return;\n+\n+    if (auto ttp = (*td.parameters)[0].isTemplateTupleParameter())\n+    {\n+        if (ti.ident is ttp.ident &&\n+            ti.mod == 0)\n+        {\n+            //printf(\"found isTrivialAliasSeq %s %s\\n\", s.toChars(), ad.type.toChars());\n+            td.isTrivialAliasSeq = true;\n+        }\n+    }\n+    else if (auto ttp = (*td.parameters)[0].isTemplateTypeParameter())\n+    {\n+        if (ti.ident is ttp.ident)\n+        {\n+            //printf(\"found isTrivialAlias %s %s\\n\", s.toChars(), ad.type.toChars());\n+            td.isTrivialAlias = true;\n+        }\n+    }\n+}\n+\n bool declareParameter(TemplateParameter _this, Scope* sc)\n {\n     static bool typeDeclareParameter(TemplateTypeParameter _this, Scope* sc)\n@@ -873,11 +912,10 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList\n     }\n \n     timeTraceBeginEvent(TimeTraceEventType.sema1TemplateInstance);\n-    scope (exit) timeTraceEndEvent(TimeTraceEventType.sema1TemplateInstance, tempinst);\n-\n+    scope (exit) timeTraceEndEvent(TimeTraceEventType.sema1TemplateInstance, tempinst,\n+        () => tempinst.toPrettyChars().toDString());\n     // Get the enclosing template instance from the scope tinst\n     tempinst.tinst = sc.tinst;\n-\n     // Get the instantiating module from the scope minst\n     tempinst.minst = sc.minst;\n     // https://issues.dlang.org/show_bug.cgi?id=10920\ndiff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d\nindex ecb38c660cf..bcc004047e3 100644\n--- a/gcc/d/dmd/traits.d\n+++ b/gcc/d/dmd/traits.d\n@@ -443,6 +443,27 @@ Expression semanticTraits(TraitsExp e, Scope* sc)\n         });\n     }\n \n+    if (e.ident == Id.isOverlapped)\n+    {\n+        if (dim != 1)\n+            return dimError(1);\n+\n+        return isDeclX((d)\n+        {\n+            auto v = d.isVarDeclaration();\n+            if (!v || !v.isField())\n+                return false;\n+\n+            // Ensure semantic analysis is complete\n+            if (auto agg = v.toParent().isAggregateDeclaration())\n+            {\n+                if (agg.semanticRun < PASS.semanticdone)\n+                    agg.dsymbolSemantic(null);\n+            }\n+\n+            return v.overlapped;\n+        });\n+    }\n     if (e.ident == Id.isArithmetic)\n     {\n         return isTypeX(t => t.isIntegral() || t.isFloating());\n@@ -588,7 +609,8 @@ Expression semanticTraits(TraitsExp e, Scope* sc)\n             return ErrorExp.get();\n         }\n \n-        t = t.toBasetype();     // get the base in case `t` is an `enum`\n+        // get enum base or static array element type\n+        t = t.baseElemOf();\n \n         if (auto ts = t.isTypeStruct())\n         {\n@@ -597,6 +619,36 @@ Expression semanticTraits(TraitsExp e, Scope* sc)\n \n         return isCopyable(t) ? True() : False();\n     }\n+    if (e.ident == Id.needsDestruction)\n+    {\n+        if (dim != 1)\n+            return dimError(1);\n+\n+        auto o = (*e.args)[0];\n+        auto t = isType(o);\n+        if (!t)\n+        {\n+            error(e.loc, \"type expected as second argument of __traits `%s` instead of `%s`\",\n+                    e.ident.toChars(), o.toChars());\n+            return ErrorExp.get();\n+        }\n+        // FIXME should just check t.needsDestruction() but that doesn't run dsymbolSemantic\n+\n+        // T[0]\n+        if (!t.size())\n+            return False();\n+\n+        // get the base in case `t` is an `enum`\n+        // handle static arrays\n+        t = t.baseElemOf();\n+        if (auto ts = t.isTypeStruct())\n+        {\n+            ts.sym.dsymbolSemantic(sc);\n+            if (ts.sym.dtor)\n+                return True();\n+        }\n+        return False();\n+    }\n \n     if (e.ident == Id.isNested)\n     {\n@@ -1095,6 +1147,18 @@ Expression semanticTraits(TraitsExp e, Scope* sc)\n                 // Prevent semantic() from replacing Symbol with its initializer\n                 die.wantsym = true;\n             ex = ex.expressionSemantic(scx);\n+            if (ex)\n+            {\n+                import dmd.access : symbolIsVisible;\n+                import dmd.safe : setUnsafe;\n+                auto msym = getDsymbolWithoutExpCtx(ex);\n+                // https://github.com/dlang/dmd/issues/19721\n+                if (msym && !symbolIsVisible(sc, msym))\n+                {\n+                    if (sc.setUnsafe(false, e.loc, \"accessing member `%s`\", id))\n+                        return ErrorExp.get();\n+                }\n+            }\n             return ex;\n         }\n         else if (e.ident == Id.getVirtualFunctions ||\n@@ -1684,6 +1748,11 @@ Expression semanticTraits(TraitsExp e, Scope* sc)\n             errorSupplemental(e.loc, \"`%s` must evaluate to either a module, a struct, an union, a class, an interface or a template instantiation\", s.toChars());\n             return ErrorExp.get();\n         }\n+        // https://issues.dlang.org/show_bug.cgi?id=13668\n+        // https://github.com/dlang/dmd/issues/22524\n+        // resolve forward references\n+        if (sds.semanticRun < PASS.semanticdone)\n+            sds.dsymbolSemantic(sc);\n \n         auto idents = new Identifiers();\n \n@@ -1762,10 +1831,6 @@ Expression semanticTraits(TraitsExp e, Scope* sc)\n         auto cd = sds.isClassDeclaration();\n         if (cd && e.ident == Id.allMembers)\n         {\n-            if (cd.semanticRun < PASS.semanticdone)\n-                cd.dsymbolSemantic(null); // https://issues.dlang.org/show_bug.cgi?id=13668\n-                                   // Try to resolve forward reference\n-\n             void pushBaseMembersDg(ClassDeclaration cd)\n             {\n                 for (size_t i = 0; i < cd.baseclasses.length; i++)\n@@ -2344,7 +2409,7 @@ private void traitNotFound(TraitsExp e)\n         initialized = true;     // lazy initialization\n \n         // All possible traits\n-        __gshared Identifier*[59] idents =\n+        __gshared Identifier*[60] idents =\n         [\n             &Id.allMembers,\n             &Id.child,\n@@ -2376,6 +2441,7 @@ private void traitNotFound(TraitsExp e)\n             &Id.identifier,\n             &Id.isAbstractClass,\n             &Id.isAbstractFunction,\n+            &Id.isOverlapped,\n             &Id.isArithmetic,\n             &Id.isAssociativeArray,\n             &Id.isCopyable,\ndiff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d\nindex 779e6bfd7f5..34bb80cf03c 100644\n--- a/gcc/d/dmd/typesem.d\n+++ b/gcc/d/dmd/typesem.d\n@@ -464,57 +464,62 @@ void check(Type _this)\n  * For our new type '_this', which is type-constructed from t,\n  * fill in the cto, ito, sto, scto, wto shortcuts.\n  */\n-void fixTo(Type _this, Type t)\n+private void fixTo(Type _this, Type t)\n {\n     // If fixing this: immutable(T*) by t: immutable(T)*,\n     // cache t to this.xto won't break transitivity.\n-    Type mto = null;\n+    Type mto = null;            // the naked type of `t`\n     Type tn = _this.nextOf();\n+    if (_this.mod || t.mod)\n+    {\n+        _this.getMcache();\n+        t.getMcache();\n+    }\n     if (!tn || _this.ty != Tsarray && tn.mod == t.nextOf().mod)\n     {\n         switch (t.mod)\n         {\n         case 0:\n-            mto = t;\n+            mto = t;            // t is naked\n             break;\n \n         case MODFlags.const_:\n-            _this.getMcache();\n+            mto = t.mcache.cto; // cto is naked\n             _this.mcache.cto = t;\n             break;\n \n         case MODFlags.wild:\n-            _this.getMcache();\n+            mto = t.mcache.wto; // wto is naked\n             _this.mcache.wto = t;\n             break;\n \n         case MODFlags.wildconst:\n-            _this.getMcache();\n+            mto = t.mcache.wcto; // wcto is naked\n             _this.mcache.wcto = t;\n             break;\n \n         case MODFlags.shared_:\n-            _this.getMcache();\n+            mto = t.mcache.sto;  // sto is naked\n             _this.mcache.sto = t;\n             break;\n \n         case MODFlags.shared_ | MODFlags.const_:\n-            _this.getMcache();\n+            mto = t.mcache.scto; // scto is naked\n             _this.mcache.scto = t;\n             break;\n \n         case MODFlags.shared_ | MODFlags.wild:\n-            _this.getMcache();\n+            mto = t.mcache.swto; // swto is naked\n             _this.mcache.swto = t;\n             break;\n \n         case MODFlags.shared_ | MODFlags.wildconst:\n-            _this.getMcache();\n+            mto = t.mcache.swcto; // swcto is naked\n             _this.mcache.swcto = t;\n             break;\n \n         case MODFlags.immutable_:\n-            _this.getMcache();\n+            mto = t.mcache.ito;  // ito is naked\n             _this.mcache.ito = t;\n             break;\n \n@@ -524,11 +529,6 @@ void fixTo(Type _this, Type t)\n     }\n     assert(_this.mod != t.mod);\n \n-    if (_this.mod)\n-    {\n-        _this.getMcache();\n-        t.getMcache();\n-    }\n     switch (_this.mod)\n     {\n     case 0:\n@@ -3314,6 +3314,15 @@ Type typeSemantic(Type type, Loc loc, Scope* sc)\n         Type tbn = tn.toBasetype();\n         if (mtype.dim)\n         {\n+            if (auto ide = mtype.dim.isIdentifierExp())\n+            {\n+                if (ide.ident == Id.dollar)\n+                {\n+                    mtype.next = tn;\n+                    mtype.transitive();\n+                    return mtype.addMod(tn.mod).merge();\n+                }\n+            }\n             auto errors = global.errors;\n             mtype.dim = semanticLength(sc, tbn, mtype.dim);\n             mtype.dim = mtype.dim.implicitCastTo(sc, Type.tsize_t);\n@@ -8536,15 +8545,12 @@ Type mutableOf(Type type)\n         type.getMcache();\n         if (type.isShared())\n         {\n-            if (type.isWild())\n-                t = type.mcache.swcto; // shared wild const -> shared\n-            else\n-                t = type.mcache.sto; // shared const => shared\n+            t = type.mcache.sto; // shared (wild) const => shared\n         }\n         else\n         {\n             if (type.isWild())\n-                t = type.mcache.wcto; // wild const -> naked\n+                t = type.mcache.wcto; // wild const => naked\n             else\n                 t = type.mcache.cto; // const => naked\n         }\n@@ -8646,7 +8652,6 @@ Type unSharedOf(Type type)\n     {\n         t = type.nullAttributes();\n         t.mod = type.mod & ~MODFlags.shared_;\n-        t.ctype = type.ctype;\n         t = t.merge();\n         t.fixTo(type);\n     }\n@@ -9224,6 +9229,9 @@ MATCH implicitConvToWithoutAliasThis(TypeStruct from, Type to)\n     /* Check all the fields. If they can all be converted,\n      * allow the conversion.\n      */\n+    import dmd.dsymbolsem : size;\n+    if (from.sym.size(Loc.initial) == SIZE_INVALID)\n+        return MATCH.nomatch;\n     MATCH m = MATCH.constant;\n     uint offset = ~0; // must never match a field offset\n     foreach (v; from.sym.fields[])\ndiff --git a/gcc/d/expr.cc b/gcc/d/expr.cc\nindex 75a8b4e726d..5ce1f510dca 100644\n--- a/gcc/d/expr.cc\n+++ b/gcc/d/expr.cc\n@@ -2608,6 +2608,8 @@ public:\n \t    tree var = build_deref (e->sym);\n \t    init = compound_expr (modify_expr (var, init), var);\n \t  }\n+\telse if (e->type->isMutable ())\n+\t  init = force_target_expr (init);\n \n \tthis->result_ = init;\n \treturn;\ndiff --git a/gcc/d/runtime.def b/gcc/d/runtime.def\nindex 016f58756bf..fac37e90709 100644\n--- a/gcc/d/runtime.def\n+++ b/gcc/d/runtime.def\n@@ -66,26 +66,10 @@ DEF_D_RUNTIME (CALLFINALIZER, \"_d_callfinalizer\", RT(VOID), P1(VOIDPTR), 0)\n DEF_D_RUNTIME (CALLINTERFACEFINALIZER, \"_d_callinterfacefinalizer\", RT(VOID),\n \t       P1(VOIDPTR), 0)\n \n-/* Used for (array.length = n) expressions.  The `i' variant is for when the\n-   initializer is nonzero.  */\n-DEF_D_RUNTIME (ARRAYSETLENGTHT, \"_d_arraysetlengthT\", RT(ARRAY_VOID),\n-\t       P3(CONST_TYPEINFO, SIZE_T, ARRAYPTR_VOID), 0)\n-DEF_D_RUNTIME (ARRAYSETLENGTHIT, \"_d_arraysetlengthiT\", RT(ARRAY_VOID),\n-\t       P3(CONST_TYPEINFO, SIZE_T, ARRAYPTR_VOID), 0)\n-\n /* Used for allocating closures on the GC heap.  */\n DEF_D_RUNTIME (ALLOCMEMORY, \"_d_allocmemory\", RT(VOIDPTR), P1(SIZE_T),\n \t       ECF_MALLOC)\n \n-/* Used for copying an array into a slice, adds an enforcment that the source\n-   and destination are equal in size and do not overlap.  */\n-DEF_D_RUNTIME (ARRAYCOPY, \"_d_arraycopy\", RT(ARRAY_VOID),\n-\t       P3(SIZE_T, ARRAY_VOID, ARRAY_VOID), 0)\n-\n-/* Used for appending a single element to an array.  */\n-DEF_D_RUNTIME (ARRAYAPPENDCTX, \"_d_arrayappendcTX\", RT(ARRAY_BYTE),\n-\t       P3(CONST_TYPEINFO, ARRAYPTR_BYTE, SIZE_T), 0)\n-\n /* Same as appending a single element to an array, but specific for when the\n    source is a UTF-32 character, and the destination is a UTF-8 or 16 array.  */\n DEF_D_RUNTIME (ARRAYAPPENDCD, \"_d_arrayappendcd\", RT(ARRAY_VOID),\ndiff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc\nindex 340a1d67e17..c976179bb03 100644\n--- a/gcc/d/typeinfo.cc\n+++ b/gcc/d/typeinfo.cc\n@@ -925,13 +925,10 @@ public:\n \n \tfor (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass)\n \t  {\n-\t    if (!bcd->members)\n-\t      continue;\n-\n-\t    for (size_t i = 0; i < bcd->members->length; i++)\n+\t    for (size_t i = 0; i < bcd->fields.length; i++)\n \t      {\n-\t\tDsymbol *sm = (*bcd->members)[i];\n-\t\tif (dmd::hasPointers (sm))\n+\t\tVarDeclaration *vd = bcd->fields[i];\n+\t\tif (dmd::hasPointers (vd))\n \t\t  goto Lhaspointers;\n \t      }\n \t  }\ndiff --git a/gcc/testsuite/gdc.test/compilable/diag20916.d b/gcc/testsuite/gdc.test/compilable/diag20916.d\nnew file mode 100644\nindex 00000000000..aa30c94fcf3\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/diag20916.d\n@@ -0,0 +1,64 @@\n+// REQUIRED_ARGS: -verrors=simple\n+/*\n+TEST_OUTPUT:\n+---\n+compilable/diag20916.d(32): Deprecation: `alias fb this` is deprecated\n+compilable/diag20916.d(37):        instantiated from here: `jump2!(Foo)`\n+compilable/diag20916.d(42):        instantiated from here: `jump1!(Foo)`\n+compilable/diag20916.d(32): Deprecation: function `diag20916.FooBar.toString` is deprecated\n+compilable/diag20916.d(37):        instantiated from here: `jump2!(Foo)`\n+compilable/diag20916.d(42):        instantiated from here: `jump1!(Foo)`\n+compilable/diag20916.d(32): Deprecation: template `diag20916.Bar.toString()() const` is deprecated\n+compilable/diag20916.d(37):        instantiated from here: `jump2!(Bar)`\n+compilable/diag20916.d(43):        instantiated from here: `jump1!(Bar)`\n+compilable/diag20916.d(21): Deprecation: variable `diag20916.Something.something` is deprecated\n+compilable/diag20916.d(24):        instantiated from here: `nestedCheck!(Something)`\n+---\n+ */\n+\n+#line 1\n+struct FooBar\n+{\n+    deprecated string toString() const { return \"42\"; }\n+    int value = 42;\n+}\n+\n+struct Foo\n+{\n+    FooBar fb;\n+    deprecated alias fb this;\n+}\n+\n+struct Bar\n+{\n+    deprecated string toString()() const { return \"42\"; }\n+    int value = 42;\n+}\n+\n+template nestedCheck(T)\n+{\n+    enum nestedCheck = T.something.init == 0;\n+}\n+\n+struct Constraint (T) if(nestedCheck!T)\n+{\n+    T value;\n+}\n+struct Something { deprecated int something; }\n+\n+void jump2(T) (T value)\n+{\n+    assert(value.toString() == \"42\");\n+}\n+\n+void jump1(T) (T value)\n+{\n+    jump2(value);\n+}\n+\n+void main ()\n+{\n+    jump1(Foo.init);\n+    jump1(Bar.init);\n+    Constraint!Something c1;\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/imports/test22480b.d b/gcc/testsuite/gdc.test/compilable/imports/test22480b.d\nnew file mode 100644\nindex 00000000000..93f9202f091\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/imports/test22480b.d\n@@ -0,0 +1,13 @@\n+module immports.test22480b;\n+\n+auto parseAA()\n+{\n+\tbool[string] aa;\n+\taa[\"key\"] = true;\n+\tassert(\"key\" in aa);\n+\tassert(aa[\"key\"]);\n+\tassert(aa.length == 1);\n+\tassert(aa == aa);\n+\taa.rehash();\n+\treturn true;\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/issue22769.d b/gcc/testsuite/gdc.test/compilable/issue22769.d\nnew file mode 100644\nindex 00000000000..986fee38b95\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/issue22769.d\n@@ -0,0 +1,19 @@\n+// https://github.com/dlang/dmd/issues/22769\n+\n+int foo()() => 0;\n+\n+void bar()\n+{\n+    cast(void) i\"$(foo)\";\n+}\n+\n+struct OutBuffer\n+{\n+    void opOpAssign(string op, T...)(T args) {}\n+}\n+\n+void qux()\n+{\n+    OutBuffer buf;\n+    buf ~= i\"$(foo)\";\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/new_xdtor.d b/gcc/testsuite/gdc.test/compilable/new_xdtor.d\nnew file mode 100644\nindex 00000000000..e757a9fd637\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/new_xdtor.d\n@@ -0,0 +1,10 @@\n+// https://github.com/dlang/dmd/issues/22609\n+struct S\n+{\n+    private ~this() {}\n+}\n+\n+void f()\n+{\n+    auto x = new S;\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/struct_allMembers.d b/gcc/testsuite/gdc.test/compilable/struct_allMembers.d\nnew file mode 100644\nindex 00000000000..0304e944aab\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/struct_allMembers.d\n@@ -0,0 +1,14 @@\n+/*\n+TEST_OUTPUT:\n+---\n+S2: AliasSeq!(\"__dtor\", \"__xdtor\", \"opAssign\")\n+S3: AliasSeq!(\"field\", \"__xdtor\", \"opAssign\")\n+---\n+*/\n+\n+// allMembers should include __xdtor\n+pragma(msg, \"S2: \", __traits(allMembers, S2));\n+pragma(msg, \"S3: \", __traits(allMembers, S3));\n+\n+static struct S2 { ~this() {} }\n+static struct S3 { S2 field; }\ndiff --git a/gcc/testsuite/gdc.test/compilable/test22480.d b/gcc/testsuite/gdc.test/compilable/test22480.d\nnew file mode 100644\nindex 00000000000..bd187d0b938\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/test22480.d\n@@ -0,0 +1,10 @@\n+// EXTRA_FILES: imports/test22480b.d\n+import imports.test22480b;\n+\n+@nogc nothrow:\n+enum a = parseAA();\n+\n+extern(C) int main()\n+{\n+\treturn 0;\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/test22501.d b/gcc/testsuite/gdc.test/compilable/test22501.d\nnew file mode 100644\nindex 00000000000..dc6fb2dbd68\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/test22501.d\n@@ -0,0 +1,12 @@\n+// https://github.com/dlang/dmd/issues/22501\n+\n+struct A {\n+    ubyte[16] bytes;\n+\n+    enum something = A(cast(ubyte[16])[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);\n+\n+    @nogc nothrow pure\n+    bool isB() const {\n+        return bytes[0..12] == something.bytes[0..12];\n+    }\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/test22543.d b/gcc/testsuite/gdc.test/compilable/test22543.d\nnew file mode 100644\nindex 00000000000..7a6a36f2490\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/test22543.d\n@@ -0,0 +1,11 @@\n+// https://github.com/dlang/dmd/issues/22543\n+\n+enum int[string] aa = [\n+    \"a\": 42,\n+];\n+\n+int i = aa[\"a\"];\n+\n+void foo() {\n+    static int j = aa[\"a\"];\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/test22544.d b/gcc/testsuite/gdc.test/compilable/test22544.d\nnew file mode 100644\nindex 00000000000..b9d18f18b03\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/test22544.d\n@@ -0,0 +1,11 @@\n+// https://github.com/dlang/dmd/issues/22544\n+\n+struct S {\n+    int bar() { return 1; }\n+}\n+\n+void foo(string key) {\n+    int[string] aa;\n+    with (S())\n+        aa[key] = bar();\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/test22752.d b/gcc/testsuite/gdc.test/compilable/test22752.d\nnew file mode 100644\nindex 00000000000..6dc880550b4\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/test22752.d\n@@ -0,0 +1,23 @@\n+/*\n+REQUIRED_ARGS:\n+PERMUTE_ARGS:\n+*/\n+\n+struct S\n+{\n+    int isnot;\n+    int[] arguments;\n+}\n+\n+struct Array(T)\n+{\n+    static if (is(const(T) : T))\n+    {\n+        void insert()\n+        {\n+            static assert (is(const(T) : T));\n+        }\n+    }\n+}\n+\n+alias A = Array!S;\ndiff --git a/gcc/testsuite/gdc.test/compilable/test24295.d b/gcc/testsuite/gdc.test/compilable/test24295.d\nnew file mode 100644\nindex 00000000000..b80c18e306e\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/test24295.d\n@@ -0,0 +1,11 @@\n+// REQUIRED_ARGS: -betterC\n+\n+int f()\n+{\n+   int[] overlaps = new int[1];\n+   overlaps[0] = 3;\n+   return overlaps[0];\n+}\n+\n+enum res_f = f();\n+static assert(res_f == 3);\ndiff --git a/gcc/testsuite/gdc.test/compilable/test_isOverlapped.d b/gcc/testsuite/gdc.test/compilable/test_isOverlapped.d\nnew file mode 100644\nindex 00000000000..a32eb2df334\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/test_isOverlapped.d\n@@ -0,0 +1,181 @@\n+// REQUIRED_ARGS:\n+\n+struct S1\n+{\n+    int a;\n+    union\n+    {\n+        int x;\n+        float y;\n+    }\n+    int b;\n+}\n+\n+// Anonymous union fields are overlapped\n+static assert(__traits(isOverlapped, S1.x));\n+static assert(__traits(isOverlapped, S1.y));\n+// Regular fields are not overlapped\n+static assert(!__traits(isOverlapped, S1.a));\n+static assert(!__traits(isOverlapped, S1.b));\n+\n+// Named union as a field type\n+struct S2\n+{\n+    union U\n+    {\n+        int x;\n+        float y;\n+    }\n+    U u;\n+}\n+// The instance 'u' itself is not overlapped (it's a regular field)\n+static assert(!__traits(isOverlapped, S2.u));\n+static assert(__traits(isOverlapped, S2.U.x));\n+static assert(__traits(isOverlapped, S2.U.y));\n+\n+// Named union accessed directly - its fields are overlapped\n+union NamedUnion\n+{\n+    int x;\n+    float y;\n+}\n+static assert(__traits(isOverlapped, NamedUnion.x));\n+static assert(__traits(isOverlapped, NamedUnion.y));\n+\n+// Anonymous struct (not a union) - fields are NOT overlapped\n+struct S3\n+{\n+    struct\n+    {\n+        int x;\n+        float y;\n+    }\n+}\n+static assert(!__traits(isOverlapped, S3.x));\n+static assert(!__traits(isOverlapped, S3.y));\n+\n+// Named union with nested anonymous union\n+struct S4\n+{\n+    union Outer\n+    {\n+        int x;  // This IS overlapped (it's in a named union)\n+        // Anonymous union nested inside the named union Outer\n+        union\n+        {\n+            int nested1;\n+            float nested2;\n+        }\n+    }\n+    Outer outer;\n+}\n+static assert(!__traits(isOverlapped, S4.outer));       // regular field, not overlapped\n+static assert(__traits(isOverlapped, S4.Outer.nested1)); // in union (both named and anonymous)\n+static assert(__traits(isOverlapped, S4.Outer.nested2)); // in union (both named and anonymous)\n+static assert(__traits(isOverlapped, S4.Outer.x));      // in named union - NOW true!\n+\n+// Class with anonymous union\n+class C1\n+{\n+    union\n+    {\n+        int x;\n+        float y;\n+    }\n+}\n+static assert(__traits(isOverlapped, C1.x));\n+static assert(__traits(isOverlapped, C1.y));\n+\n+// Non-field arguments should return false (not error)\n+static assert(!__traits(isOverlapped, S1));    // aggregate type\n+static assert(!__traits(isOverlapped, int));   // type\n+static assert(!__traits(isOverlapped, 42));    // literal value\n+\n+// Deeply nested anonymous unions within anonymous structs\n+struct S5\n+{\n+    union\n+    {\n+        int x;\n+        struct\n+        {\n+            union\n+            {\n+                int y;\n+                float z;\n+            }\n+        }\n+    }\n+}\n+static assert(__traits(isOverlapped, S5.x));  // outer anonymous union\n+static assert(__traits(isOverlapped, S5.y));  // inner anonymous union\n+static assert(__traits(isOverlapped, S5.z));  // inner anonymous union\n+\n+// Union as top-level type\n+union TopLevelUnion1\n+{\n+    int a;\n+    float b;\n+    struct\n+    {\n+        int c;\n+        int d;\n+    }\n+}\n+static assert(__traits(isOverlapped, TopLevelUnion1.a));\n+static assert(__traits(isOverlapped, TopLevelUnion1.b));\n+static assert(__traits(isOverlapped, TopLevelUnion1.c));\n+static assert(!__traits(isOverlapped, TopLevelUnion1.d));\n+\n+union TopLevelUnion2\n+{\n+    int a;\n+    double b;\n+    struct\n+    {\n+        int c;\n+        int d; // Now d is overlapped with b\n+    }\n+}\n+static assert(__traits(isOverlapped, TopLevelUnion2.a));\n+static assert(__traits(isOverlapped, TopLevelUnion2.b));\n+static assert(__traits(isOverlapped, TopLevelUnion2.c));\n+static assert(__traits(isOverlapped, TopLevelUnion2.d));\n+\n+// Bug #22621\n+struct Bug22621\n+{\n+    struct D\n+    {\n+        void* ptr;\n+    }\n+\n+    union\n+    {\n+        struct\n+        {\n+            D d;\n+        }\n+        uint b;\n+    }\n+}\n+static assert(__traits(isOverlapped, Bug22621.b));\n+// Bug #22621: DMD correctly detects that d is overlapped, but the destructor\n+// logic doesn't properly handle it - it calls d's destructor even when only b was initialized\n+static assert(__traits(isOverlapped, Bug22621.d));  // Correctly detected!\n+\n+// Struct with both overlapped and non-overlapped fields\n+struct S6\n+{\n+    int regular1;\n+    union\n+    {\n+        int overlapped1;\n+        float overlapped2;\n+    }\n+    int regular2;\n+}\n+static assert(!__traits(isOverlapped, S6.regular1));\n+static assert(__traits(isOverlapped, S6.overlapped1));\n+static assert(__traits(isOverlapped, S6.overlapped2));\n+static assert(!__traits(isOverlapped, S6.regular2));\ndiff --git a/gcc/testsuite/gdc.test/compilable/test_nosharedaccess_ctor_nested_new.d b/gcc/testsuite/gdc.test/compilable/test_nosharedaccess_ctor_nested_new.d\nnew file mode 100644\nindex 00000000000..3b28e232912\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/test_nosharedaccess_ctor_nested_new.d\n@@ -0,0 +1,13 @@\n+// REQUIRED_ARGS: -preview=nosharedaccess\n+\n+class Outer\n+{\n+    class Inner\n+    {\n+    }\n+\n+    shared this()\n+    {\n+        auto i = new shared Inner;\n+    }\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/test_nosharedaccess_shared_struct_literal.d b/gcc/testsuite/gdc.test/compilable/test_nosharedaccess_shared_struct_literal.d\nnew file mode 100644\nindex 00000000000..4bb99010b84\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/compilable/test_nosharedaccess_shared_struct_literal.d\n@@ -0,0 +1,15 @@\n+// REQUIRED_ARGS: -preview=nosharedaccess\n+\n+import core.atomic;\n+\n+struct List\n+{\n+    size_t gen;\n+    List* next;\n+}\n+\n+void main()\n+{\n+    shared(List) head;\n+    assert(cas(&head, shared(List)(0, null), shared(List)(1, cast(List*)1)));\n+}\ndiff --git a/gcc/testsuite/gdc.test/compilable/traits.d b/gcc/testsuite/gdc.test/compilable/traits.d\nindex 09538b1dd4b..025a82c9795 100644\n--- a/gcc/testsuite/gdc.test/compilable/traits.d\n+++ b/gcc/testsuite/gdc.test/compilable/traits.d\n@@ -169,6 +169,7 @@ class C1 {}\n static assert( __traits(isCopyable, S1));\n static assert( __traits(isCopyable, S2));\n static assert(!__traits(isCopyable, S3));\n+static assert(!__traits(isCopyable, S3[1]));\n static assert(!__traits(isCopyable, S4));\n static assert(__traits(isCopyable, C1));\n static assert(__traits(isCopyable, int));\ndiff --git a/gcc/testsuite/gdc.test/compilable/vgc3.d b/gcc/testsuite/gdc.test/compilable/vgc3.d\nindex efdc5cd5eb3..6e587530d33 100644\n--- a/gcc/testsuite/gdc.test/compilable/vgc3.d\n+++ b/gcc/testsuite/gdc.test/compilable/vgc3.d\n@@ -44,8 +44,12 @@ void testCall()\n /*\n TEST_OUTPUT:\n ---\n-compilable/vgc3.d(51): vgc: using closure causes GC allocation\n-compilable/vgc3.d(63): vgc: using closure causes GC allocation\n+compilable/vgc3.d(55): vgc: using closure causes GC allocation\n+compilable/vgc3.d(58): vgc: function `bar` closes over variable `x`\n+compilable/vgc3.d(57): vgc: `x` declared here\n+compilable/vgc3.d(67): vgc: using closure causes GC allocation\n+compilable/vgc3.d(70): vgc: function `bar` closes over variable `x`\n+compilable/vgc3.d(69): vgc: `x` declared here\n ---\n */\n auto testClosure1()\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d b/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d\nindex e23ed04305f..1ff06ca20f6 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d\n@@ -2,7 +2,7 @@\n REQUIRED_ARGS: -m64\n TEST_OUTPUT:\n ---\n-fail_compilation/fail19898a.d(10): Error: expression `__key2 < __limit3` of type `__vector(int[4])` does not have a boolean value\n+fail_compilation/fail19898a.d(10): Error: expression `__key$n$ < __limit$n$` of type `__vector(int[4])` does not have a boolean value\n ---\n */\n void f (__vector(int[4]) n)\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d b/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d\nindex 5101da5617b..a59af4a688f 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d\n@@ -3,8 +3,8 @@ REQUIRED_ARGS: -m64\n TEST_OUTPUT:\n ---\n fail_compilation/fail19898b.d(17): Error: cannot implicitly convert expression `m` of type `S` to `__vector(int[4])`\n-fail_compilation/fail19898b.d(17): Error: expression `__key2 != __limit3` of type `__vector(int[4])` does not have a boolean value\n-fail_compilation/fail19898b.d(17): Error: cannot cast expression `__key2` of type `__vector(int[4])` to `S`\n+fail_compilation/fail19898b.d(17): Error: expression `__key$n$ != __limit$n$` of type `__vector(int[4])` does not have a boolean value\n+fail_compilation/fail19898b.d(17): Error: cannot cast expression `__key$n$` of type `__vector(int[4])` to `S`\n ---\n */\n struct S\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/getMember_private.d b/gcc/testsuite/gdc.test/fail_compilation/getMember_private.d\nnew file mode 100644\nindex 00000000000..647e6098e3b\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/getMember_private.d\n@@ -0,0 +1,26 @@\n+/*\n+EXTRA_FILES: imports/fail5385.d\n+TEST_OUTPUT:\n+---\n+fail_compilation/getMember_private.d(17): Error: accessing member `x` is not allowed in a `@safe` function\n+fail_compilation/getMember_private.d(19): Error: accessing member `privX` is not allowed in a `@safe` function\n+---\n+*/\n+\n+import imports.a10169, imports.fail5385;\n+\n+B b;\n+\n+void f() @safe\n+{\n+    // instance field\n+    __traits(getMember, b, \"x\")++;\n+    // static field\n+    __traits(getMember, C, \"privX\")++;\n+}\n+\n+void g() @system // OK\n+{\n+    __traits(getMember, b, \"x\")++;\n+    __traits(getMember, C, \"privX\")++;\n+}\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/issue22147.d b/gcc/testsuite/gdc.test/fail_compilation/issue22147.d\nnew file mode 100644\nindex 00000000000..77c49678927\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/issue22147.d\n@@ -0,0 +1,16 @@\n+/*\n+TEST_OUTPUT:\n+---\n+fail_compilation/issue22147.d(15): Error: operator `/` is not defined for type `T`\n+fail_compilation/issue22147.d(9):        perhaps overload the operator with `auto opBinaryRight(string op : \"/\")(int lhs) {}`\n+---\n+*/\n+\n+struct T\n+{\n+}\n+\n+void test()\n+{\n+    auto result = 10 / T();  // int / T requires opBinaryRight on T\n+}\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/safeprintf.d b/gcc/testsuite/gdc.test/fail_compilation/safeprintf.d\nindex 60bff2a8795..4f2dd42e4be 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/safeprintf.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/safeprintf.d\n@@ -2,22 +2,41 @@\n DISABLED: win32 win64 freebsd32 openbsd32 linux32 osx32\n TEST_OUTPUT:\n ---\n-fail_compilation/safeprintf.d(20): Error: `@safe` function `safeprintf.func` cannot call `@system` function `safeprintf.printf`\n-fail_compilation/safeprintf.d(15):        `safeprintf.printf` is declared here\n-fail_compilation/safeprintf.d(21): Error: `@safe` function `safeprintf.func` cannot call `@system` function `safeprintf.printf`\n-fail_compilation/safeprintf.d(15):        `safeprintf.printf` is declared here\n-fail_compilation/safeprintf.d(22): Error: `@safe` function `safeprintf.func` cannot call `@system` function `safeprintf.printf`\n-fail_compilation/safeprintf.d(15):        `safeprintf.printf` is declared here\n-fail_compilation/safeprintf.d(22): Deprecation: format specifier `\"%Z\"` is invalid\n+fail_compilation/safeprintf.d(29): Error: calling `pragma(printf)` function `printf` with format string `\"s: %s\\n\"` is not allowed in a `@safe` function\n+fail_compilation/safeprintf.d(21):        `safeprintf.printf` is declared here\n+fail_compilation/safeprintf.d(30): Error: calling `pragma(printf)` function `printf` with format string `\"s: %S\\n\"` is not allowed in a `@safe` function\n+fail_compilation/safeprintf.d(21):        `safeprintf.printf` is declared here\n+fail_compilation/safeprintf.d(31): Error: calling `pragma(printf)` function `printf` with format string `\"s: %Z\\n\"` is not allowed in a `@safe` function\n+fail_compilation/safeprintf.d(21):        `safeprintf.printf` is declared here\n+fail_compilation/safeprintf.d(31): Deprecation: format specifier `\"%Z\"` is invalid\n+fail_compilation/safeprintf.d(32): Error: calling `pragma(printf)` function `printf` with non-literal format string is not allowed in a `@safe` function\n+fail_compilation/safeprintf.d(21):        `safeprintf.printf` is declared here\n+fail_compilation/safeprintf.d(33): Error: calling `pragma(printf)` function `bar` with format string `\"%s\"` is not allowed in a `@safe` function\n+fail_compilation/safeprintf.d(22):        `safeprintf.bar` is declared here\n+fail_compilation/safeprintf.d(34): Error: `@safe` function `safeprintf.func` cannot call `@system` function `safeprintf.sys_printf`\n+fail_compilation/safeprintf.d(23):        `safeprintf.sys_printf` is declared here\n ---\n */\n \n-extern (C) @system pragma(printf) int printf(const(char)* format, ...);\n+extern (C) @trusted pragma(printf) int printf(const(char)* format, ...);\n+extern(C) pragma(printf) @trusted void bar(int, const char*, ...);\n+extern (C) @system pragma(printf) int sys_printf(const(char)* format, ...);\n \n @safe void func(int i, char* s, dchar* d)\n {\n-    printf(\"i: %d\\n\", i);\n+    printf(\"no specs\"); // OK\n+    printf(\"i: %d\\n\", i); // OK\n     printf(\"s: %s\\n\", s);\n     printf(\"s: %S\\n\", d);\n     printf(\"s: %Z\\n\", s);\n+    printf(s, i); // non-literal\n+    bar(1, \"%s\", s); // preceding args\n+    sys_printf(\"%d\", i); // not safe\n+}\n+\n+// no errors\n+@system void sys(char* s)\n+{\n+    printf(s); // non-literal\n+    printf(\"%s\", s);\n }\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/staticarray.d b/gcc/testsuite/gdc.test/fail_compilation/staticarray.d\nnew file mode 100644\nindex 00000000000..87b16ef360f\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/staticarray.d\n@@ -0,0 +1,12 @@\n+/*\n+TEST_OUTPUT:\n+---\n+fail_compilation/staticarray.d(10): Error: cannot infer static array length from `$`, provide an initializer\n+fail_compilation/staticarray.d(11): Error: cannot infer static array length from `$`, provide an initializer\n+fail_compilation/staticarray.d(12): Error: cannot infer static array length from `$`, provide an initializer\n+---\n+*/\n+\n+int[$] arr1;\n+int[$] arr2 = void;\n+int[$][1] arr3 = 1;\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/test17977.d b/gcc/testsuite/gdc.test/fail_compilation/test17977.d\nindex b79d36c71fc..30475ae59c8 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/test17977.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/test17977.d\n@@ -3,7 +3,7 @@ https://issues.dlang.org/show_bug.cgi?id=15399\n REQUIRED_ARGS: -preview=dip1000\n TEST_OUTPUT:\n ---\n-fail_compilation/test17977.d(19): Error: assigning address of variable `__slList3` to `elem` with longer lifetime is not allowed in a `@safe` function\n+fail_compilation/test17977.d(19): Error: assigning address of variable `__slList$n$` to `elem` with longer lifetime is not allowed in a `@safe` function\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/test24295.d b/gcc/testsuite/gdc.test/fail_compilation/test24295.d\ndeleted file mode 100644\nindex 58b6e92df8f..00000000000\n--- a/gcc/testsuite/gdc.test/fail_compilation/test24295.d\n+++ /dev/null\n@@ -1,13 +0,0 @@\n-// REQUIRED_ARGS: -betterC\n-\n-/*\n-TEST_OUTPUT:\n----\n-fail_compilation/test24295.d(12): Error: expression `new int[](1$?:32=u|64=LU$)` allocates with the GC and cannot be used with switch `-betterC`\n----\n-*/\n-\n-void f()\n-{\n-   int[] overlaps = new int[1];\n-}\ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/test9150.d b/gcc/testsuite/gdc.test/fail_compilation/test9150.d\nindex 5f66b360fec..bad84438db8 100644\n--- a/gcc/testsuite/gdc.test/fail_compilation/test9150.d\n+++ b/gcc/testsuite/gdc.test/fail_compilation/test9150.d\n@@ -3,7 +3,7 @@\n /*\n TEST_OUTPUT:\n ---\n-fail_compilation/test9150.d(14): Error: mismatched array lengths 5 and 3 for assignment `row[] = __r2[__key3]`\n+fail_compilation/test9150.d(14): Error: mismatched array lengths 5 and 3 for assignment `row[] = __r$n$[__key$n$]`\n ---\n */\n \ndiff --git a/gcc/testsuite/gdc.test/fail_compilation/test_isOverlapped_errors.d b/gcc/testsuite/gdc.test/fail_compilation/test_isOverlapped_errors.d\nnew file mode 100644\nindex 00000000000..ef0a1782dd8\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/fail_compilation/test_isOverlapped_errors.d\n@@ -0,0 +1,17 @@\n+/*\n+TEST_OUTPUT:\n+---\n+fail_compilation/test_isOverlapped_errors.d(100): Error: expected 1 arguments for `isOverlapped` but had 0\n+fail_compilation/test_isOverlapped_errors.d(101): Error: expected 1 arguments for `isOverlapped` but had 2\n+---\n+*/\n+\n+struct S\n+{\n+    union { int x; }\n+    int y;\n+}\n+\n+#line 100\n+enum a = __traits(isOverlapped);\n+enum b = __traits(isOverlapped, S, S.x);\ndiff --git a/gcc/testsuite/gdc.test/runnable/b10562.d b/gcc/testsuite/gdc.test/runnable/b10562.d\nindex cf79d164461..01ac9b8dea3 100644\n--- a/gcc/testsuite/gdc.test/runnable/b10562.d\n+++ b/gcc/testsuite/gdc.test/runnable/b10562.d\n@@ -90,4 +90,12 @@ void main()\n         // arr = slice;\n         // assert(arr == [[ slice, slice, slice ], [ slice, slice, slice ]]);\n     }\n+    {\n+        // https://github.com/dlang/dmd/issues/22386\n+        const int[3][2] a = [[1:2, 3],[0: 0, 1:2, 2:3]];\n+        assert(a == [ [ 0, 2, 3 ], [ 0, 2, 3 ] ]);\n+\n+        const int[3][2] b = [[1:2, 2:3],[0: 0, 1:2, 2:3]];\n+        assert(b == [ [ 0, 2, 3 ], [ 0, 2, 3 ] ]);\n+    }\n }\ndiff --git a/gcc/testsuite/gdc.test/runnable/extra-files/sectiondefs.d b/gcc/testsuite/gdc.test/runnable/extra-files/sectiondefs.d\nnew file mode 100644\nindex 00000000000..764057839ad\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/runnable/extra-files/sectiondefs.d\n@@ -0,0 +1,13 @@\n+module extrafiles.sectiondefs;\n+import core.attribute;\n+\n+version(Windows)\n+    enum PlatformEntryName(string Name) = \".\" ~ Name ~ \"$N\";\n+else\n+    enum PlatformEntryName(string Name) = Name;\n+\n+@section(PlatformEntryName!\"myInts\")\n+__gshared int anInt = 9;\n+\n+@section(PlatformEntryName!\"my8Ints\")\n+__gshared int[8] an8Int = [64, 72, 9, 81, 21, 59, 45, 2];\ndiff --git a/gcc/testsuite/gdc.test/runnable/foreach5.d b/gcc/testsuite/gdc.test/runnable/foreach5.d\nindex b0befcceb62..024db2a864c 100644\n--- a/gcc/testsuite/gdc.test/runnable/foreach5.d\n+++ b/gcc/testsuite/gdc.test/runnable/foreach5.d\n@@ -1208,6 +1208,36 @@ void testLDC326()\n     }\n }\n \n+/***************************************/\n+// https://github.com/dlang/dmd/issues/22629\n+\n+struct Collection2\n+{\n+    this(ref Collection2) {}\n+\n+    int opApply(int delegate(Collection2))\n+    {\n+        return 0;\n+    }\n+}\n+\n+Collection2 testForeach2(ref Collection2 level1, ref Collection2 level2)\n+{\n+    foreach (first; level1) {\n+        foreach (second; level2)\n+            return second;\n+    }\n+\n+    return Collection2();\n+}\n+\n+void test22629()\n+{\n+    Collection2 c1, c2;\n+    testForeach2(c1, c2);\n+}\n+\n+\n /***************************************/\n \n int main()\n@@ -1241,6 +1271,7 @@ int main()\n     test14653();\n     test17041();\n     testLDC326();\n+    test22629();\n \n     printf(\"Success\\n\");\n     return 0;\ndiff --git a/gcc/testsuite/gdc.test/runnable/issue22621.d b/gcc/testsuite/gdc.test/runnable/issue22621.d\nnew file mode 100644\nindex 00000000000..e596341c630\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/runnable/issue22621.d\n@@ -0,0 +1,40 @@\n+// Test for Issue 22621\n+// Destructor should not be called on uninitialized overlapped field\n+\n+int dtorCalls = 0;\n+\n+struct D\n+{\n+    int magic = 0xC0FFEE;\n+\n+    ~this() @safe\n+    {\n+        // d's destructor should NOT be called,\n+        // while dd's destructor should be called.\n+        dtorCalls++;\n+        assert(magic == 0xC0FFEE, \"Destructor called on uninitialized field!\");\n+    }\n+}\n+\n+struct SUS\n+{\n+    union {\n+        struct {\n+            D d;\n+        }\n+        uint b;\n+    }\n+    D dd;\n+}\n+\n+void main()\n+{\n+    {\n+        // Initialize only 'b', not 'd'\n+        // Without the fix, d's destructor would be called on garbage memory\n+        SUS sus = SUS(b:0xDEADBEEF);\n+    }\n+\n+    // Just dd's destructor should be called, so dtorCalls should be 1\n+    assert(dtorCalls == 1, \"Destructor was incorrectly called!\");\n+}\ndiff --git a/gcc/testsuite/gdc.test/runnable/issue22639.d b/gcc/testsuite/gdc.test/runnable/issue22639.d\nnew file mode 100644\nindex 00000000000..4a1a99faafd\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/runnable/issue22639.d\n@@ -0,0 +1,35 @@\n+// REQUIRED_ARGS: -betterC\n+\n+struct Arr(T, int CAPACITY)\n+{\n+    int count = 0;\n+    T[CAPACITY] items;\n+    int opApply(scope int delegate(T) dg)\n+    {\n+        int result;\n+        for (int i = 0; i < count; i++)\n+            if ((result = dg(items[i])) != 0)\n+                break;\n+        return result;\n+    }\n+}\n+\n+struct Foo {}\n+struct Bar {\n+    Arr!(Foo*, 32) array;\n+    Foo* get()\n+    {\n+        foreach(Foo* it; array)\n+        {\n+            return it;\n+        }\n+        return null;\n+    }\n+}\n+\n+Foo* foo;\n+Bar bar;\n+extern(C) void main()\n+{\n+    foo = bar.get();\n+}\ndiff --git a/gcc/testsuite/gdc.test/runnable/lexer.d b/gcc/testsuite/gdc.test/runnable/lexer.d\nindex 0e1068a4289..daae3fa9876 100644\n--- a/gcc/testsuite/gdc.test/runnable/lexer.d\n+++ b/gcc/testsuite/gdc.test/runnable/lexer.d\n@@ -42,6 +42,18 @@ foo\n \n     s = q{{foo}\"}\"};\n     assert(s == \"{foo}\\\"}\\\"\");\n+\n+    // https://github.com/dlang/dmd/issues/22535\n+    s = q\"EOS\n+*是是是*\n+ηš„ηš„ηš„.\n+*000*\n+EOS\";\n+    assert(s == \"*是是是*\n+ηš„ηš„ηš„.\n+*000*\n+\");\n+    assert(s.length == 29);\n }\n \n /*********************************************************/\ndiff --git a/gcc/testsuite/gdc.test/runnable/rvalue1.d b/gcc/testsuite/gdc.test/runnable/rvalue1.d\nindex e50ccd08395..78c50919899 100644\n--- a/gcc/testsuite/gdc.test/runnable/rvalue1.d\n+++ b/gcc/testsuite/gdc.test/runnable/rvalue1.d\n@@ -286,6 +286,7 @@ struct V12\n {\n     S12 s;\n     this(int) { s = S12(1); }\n+    int opApply(int delegate(Object)) { return 0; }\n }\n \n S12 foo12()\n@@ -293,10 +294,33 @@ S12 foo12()\n     return __rvalue(V12(1).s);\n }\n \n+S12 bar12()\n+{\n+    S12 s = S12(1); // NRVO\n+    foreach (_; V12(1))\n+        return s;\n+    return s;\n+}\n+\n+S12 baz12()\n+{\n+    S12 s1 = S12(1);\n+    S12 s2 = S12(1); // No NRVO\n+    foreach (_; V12(1))\n+        return s1;\n+    return s2;\n+}\n+\n void test12()\n {\n     S12 s = foo12();\n     assert(&s == s.ptr);\n+\n+    S12 s2 = bar12();\n+    assert(&s2 == s2.ptr);\n+\n+    S12 s3 = baz12();\n+    assert(&s3 == s3.ptr);\n }\n \n /********************************/\ndiff --git a/gcc/testsuite/gdc.test/runnable/sctor.d b/gcc/testsuite/gdc.test/runnable/sctor.d\nindex b587e6efe80..ad418d4d176 100644\n--- a/gcc/testsuite/gdc.test/runnable/sctor.d\n+++ b/gcc/testsuite/gdc.test/runnable/sctor.d\n@@ -465,6 +465,42 @@ void test19389()\n     assert(bar.b.x == 7); // fails\n }\n \n+/***************************************************/\n+// https://github.com/dlang/dmd/issues/22604\n+\n+struct S22604\n+{\n+    S22604* ptr;\n+\n+    this(int)\n+    {\n+        ptr = &this;\n+    }\n+\n+    this(this)\n+    {\n+        ptr = &this;\n+    }\n+}\n+\n+struct T22604\n+{\n+    S22604 a, b, c, d;\n+\n+    this(int)\n+    {\n+        a = b = c = d = S22604(1);\n+    }\n+}\n+\n+void test22604()\n+{\n+    T22604 t = T22604(1);\n+    assert(t.a.ptr is &t.a);\n+    assert(t.b.ptr is &t.b);\n+    assert(t.c.ptr is &t.c);\n+    assert(t.d.ptr is &t.d);\n+}\n \n /***************************************************/\n \n@@ -478,6 +514,7 @@ int main()\n     test14944();\n     test15869();\n     test19389();\n+    test22604();\n \n     printf(\"Success\\n\");\n     return 0;\ndiff --git a/gcc/testsuite/gdc.test/runnable/staticarray.d b/gcc/testsuite/gdc.test/runnable/staticarray.d\nnew file mode 100644\nindex 00000000000..39cfb0a439a\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/runnable/staticarray.d\n@@ -0,0 +1,83 @@\n+void main()\n+{\n+\tint[3] arr1 = [1,2,3];\n+\tint[$] arr2 = [1,2,3];\n+\tconst(int)[$] arr13 = [1,2,3];\n+\tassert(arr1.length == 3);\n+\tassert(arr2.length == 3);\n+\tassert(arr13.length == 3);\n+\tstatic assert(arr2.length == 3);\n+\tstatic assert(arr13.length == 3);\n+\tstatic assert(is(typeof(arr13) == const(int)[3]));\n+\tassert(arr1 == arr2);\n+\n+\tint[$] arr3 = [10] ~ [20];\n+\tassert(arr3.length == 2);\n+\tassert(arr3[0] == 10);\n+\tassert(arr3[1] == 20);\n+\tstatic assert(arr3.length == 2);\n+\n+\tint[$] arrConcatA = [2];\n+\tint[$] arrConcatB = [2];\n+\tint[$] arrConcatC = arrConcatA ~ arrConcatB;\n+\tassert(arrConcatC.length == 2);\n+\tassert(arrConcatC[0] == 2);\n+\tassert(arrConcatC[1] == 2);\n+\tstatic assert(arrConcatC.length == 2);\n+\tstatic assert(is(typeof(arrConcatC) == int[2]));\n+\n+\tint[$][$] arr4 = [[10], [10]];\n+\tassert(arr4.length == 2);\n+\tassert(arr4[0].length == 1);\n+\tstatic assert(arr4.length == 2);\n+\tstatic assert(arr4[0].length == 1);\n+\n+\tstatic assert(!__traits(compiles,\n+\t{\n+\t\tint[$] arr5 = 3;\n+\t}));\n+\n+\tstatic assert(!__traits(compiles,\n+\t{\n+\t\tint[$] arr6 = new int[2];\n+\t}));\n+\n+\tint[N] arrn(size_t N)()\n+\t{\n+\t    int[N] res;\n+\t    return res;\n+\t}\n+\tint[$] arr7 = arrn!(2)();\n+\tassert(arr7.length == 2);\n+\tstatic assert(arr7.length == 2);\n+\n+\tint[2][$] arr8 = [[1, 2], [3, 4], [5, 6]];\n+\tassert(arr8.length == 3);\n+\tassert(arr8[0].length == 2);\n+\tstatic assert(arr8.length == 3);\n+\tstatic assert(arr8[0].length == 2);\n+\n+\tint[$][$][$] arr9 = [[[1, 2]], [[3, 4]]];\n+\tassert(arr9.length == 2);\n+\tassert(arr9[0].length == 1);\n+\tassert(arr9[0][0].length == 2);\n+\tstatic assert(arr9.length == 2);\n+\tstatic assert(arr9[0].length == 1);\n+\tstatic assert(arr9[0][0].length == 2);\n+\n+\tstatic assert(!__traits(compiles,\n+\t{\n+\t\tfloat[$] arr10 = 3.0f;\n+\t}));\n+\n+\tstatic assert(!__traits(compiles,\n+\t{\n+\t\tstring[$] arr11 = \"abc\";\n+\t}));\n+\n+\tchar[$] arr12 = \"abc\";\n+\tassert(arr12.length == 3);\n+\tassert(arr12[0] == 'a');\n+\tassert(arr12[1] == 'b');\n+\tassert(arr12[2] == 'c');\n+}\ndiff --git a/gcc/testsuite/gdc.test/runnable/structlit_rvalue.d b/gcc/testsuite/gdc.test/runnable/structlit_rvalue.d\nindex c8f63c71f3d..86ef405c1f1 100644\n--- a/gcc/testsuite/gdc.test/runnable/structlit_rvalue.d\n+++ b/gcc/testsuite/gdc.test/runnable/structlit_rvalue.d\n@@ -1,15 +1,67 @@\n-void refCounted(ProcessPipes val)\n+struct S22585_1\n {\n-    val = ProcessPipes.init;\n+    char[32] a;\n+    int b = 1;\n+\n+    this(ref S22585_1 s)\n+    {\n+        s.b = 2;\n+    }\n+}\n+\n+struct T22585_1\n+{\n+    S22585_1 s;\n+}\n+\n+void copyConstruct(S22585_1) {}\n+\n+void mutate(ref S22585_1 s)\n+{\n+    s.b = 2;\n+}\n+\n+struct S22585_2\n+{\n+    char[32] a;\n+    int b = 1;\n+    ~this() {}\n+}\n+\n+struct T22585_2\n+{\n+    S22585_2 s;\n+}\n+\n+pragma(inline, true)\n+S22585_2 inlinedRvalue1()\n+{\n+    bool b;\n+    return (b ? T22585_2.init : T22585_2.init).s;\n+}\n+\n+void mutateCopyOf(S22585_2 s)\n+{\n+    s.b = 2;\n+}\n+\n+pragma(inline, true)\n+S22585_2 inlinedRvalue2()\n+{\n+    return S22585_2.init;\n }\n \n-struct ProcessPipes\n+void assignCopyOf(S22585_2 s)\n {\n-    char[33] arr;\n-    ~this() @safe {}\n+    s = S22585_2.init;\n }\n \n void main()\n {\n-    refCounted(ProcessPipes.init);\n+    bool b;\n+    copyConstruct((b ? T22585_1.init : T22585_1.init).s);\n+    mutate((b ? T22585_1.init : T22585_1.init).s);\n+    mutateCopyOf(inlinedRvalue1());\n+    inlinedRvalue2.b = 2;\n+    assignCopyOf(S22585_2.init);\n }\ndiff --git a/gcc/testsuite/gdc.test/runnable/test20275.d b/gcc/testsuite/gdc.test/runnable/test20275.d\nindex cbdf1f6e7f8..1288397264b 100644\n--- a/gcc/testsuite/gdc.test/runnable/test20275.d\n+++ b/gcc/testsuite/gdc.test/runnable/test20275.d\n@@ -1,4 +1,5 @@\n // EXTRA_SOURCES: imports/δ½ ε₯½.d\n+// UNICODE_NAMES:\n \n import imports.δ½ ε₯½;\n \ndiff --git a/gcc/testsuite/gdc.test/runnable/test22422.d b/gcc/testsuite/gdc.test/runnable/test22422.d\nnew file mode 100644\nindex 00000000000..d51b93799aa\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/runnable/test22422.d\n@@ -0,0 +1,21 @@\n+// https://github.com/dlang/dmd/issues/22422\n+\n+class C {}\n+class D {}\n+\n+struct S {\n+    ~this() {}\n+    D opIndex(size_t) { return new D; }\n+}\n+\n+S makeS() {\n+    return S();\n+}\n+\n+C foo() {\n+    return cast(C) makeS()[0];\n+}\n+\n+void main() {\n+    assert(foo() is null);\n+}\ndiff --git a/gcc/testsuite/gdc.test/runnable/test22594.d b/gcc/testsuite/gdc.test/runnable/test22594.d\nnew file mode 100644\nindex 00000000000..0c16ba6e17a\n--- /dev/null\n+++ b/gcc/testsuite/gdc.test/runnable/test22594.d\n@@ -0,0 +1,23 @@\n+// https://github.com/dlang/dmd/issues/22594\n+// PERMUTE_ARGS:\n+\n+import core.memory : GC;\n+\n+class C(Ts...) {\n+    Ts tuple;\n+}\n+\n+void main() {\n+    alias NoPointers = C!int;\n+    alias WithPointers = C!(void*);\n+\n+    assert(typeid(NoPointers).m_flags & TypeInfo_Class.ClassFlags.noPointers);\n+    assert(!(typeid(WithPointers).m_flags & TypeInfo_Class.ClassFlags.noPointers));\n+\n+    auto noPointers = new NoPointers;\n+    // FIXME: regressed with v2.103\n+    //assert(GC.getAttr(cast(void*) noPointers) & GC.BlkAttr.NO_SCAN);\n+\n+    auto withPointers = new WithPointers;\n+    assert(!(GC.getAttr(cast(void*) withPointers) & GC.BlkAttr.NO_SCAN));\n+}\ndiff --git a/gcc/testsuite/gdc.test/runnable/testaa2.d b/gcc/testsuite/gdc.test/runnable/testaa2.d\nindex 9247bbf84e7..7104b12dd8c 100644\n--- a/gcc/testsuite/gdc.test/runnable/testaa2.d\n+++ b/gcc/testsuite/gdc.test/runnable/testaa2.d\n@@ -335,6 +335,14 @@ void foo() @safe\n     aa[key] = 123;\n }\n \n+// https://github.com/dlang/dmd/issues/22560\n+void test22560()\n+{\n+    enum E { a }\n+    bool[E] aa;\n+    static assert(!__traits(compiles, aa[0]));\n+}\n+\n /************************************************/\n \n void testEvaluationOrder()\ndiff --git a/gcc/testsuite/gdc.test/runnable/testaa3.d b/gcc/testsuite/gdc.test/runnable/testaa3.d\nindex 734c0c4cba0..1ba165b55e6 100644\n--- a/gcc/testsuite/gdc.test/runnable/testaa3.d\n+++ b/gcc/testsuite/gdc.test/runnable/testaa3.d\n@@ -393,6 +393,73 @@ void test22354()\n     assert(aa[\"x\"].length == 1);  // FAILS: length is still 0\n }\n \n+// https://github.com/dlang/dmd/issues/22406\n+void testShared()\n+{\n+    shared int[int] processes = [1: 1, 2:4, 3:9];\n+\n+    cast(void)processes.sizeof;\n+    cast(void)processes.length;\n+    cast(void)processes.dup;\n+    cast(void)processes.rehash;\n+    //cast(void)processes.clear;\n+    //cast(void)processes.keys;\n+    //cast(void)processes.values;\n+    //cast(void)processes.byKey;\n+    //cast(void)processes.byValue;\n+    //cast(void)processes.byKeyValue;\n+    processes.remove(3);\n+    assert(2 in processes);\n+\n+    immutable int[int] iprocesses = [1: 1, 2:4, 3:9];\n+\n+    cast(void)iprocesses.sizeof;\n+    cast(void)iprocesses.length;\n+    cast(void)iprocesses.dup;\n+    //cast(void)iprocesses.rehash;\n+    //cast(void)iprocesses.clear;\n+    cast(void)iprocesses.keys;\n+    cast(void)iprocesses.values;\n+    cast(void)iprocesses.byKey;\n+    cast(void)iprocesses.byValue;\n+    cast(void)iprocesses.byKeyValue;\n+    //iprocesses.remove(3);\n+    assert(2 in iprocesses);\n+}\n+\n+// https://github.com/dlang/dmd/issues/22556\n+void test22556()\n+{\n+    static struct RefCounted(T)\n+    {\n+        this(this) {}\n+    }\n+    struct S {}\n+    alias R = RefCounted!S;\n+    shared R[string] foo;\n+\n+    (cast (R[string]) foo).clear; // WORKS\n+    (cast() foo).clear; // FAILS with 2.112.0, WORKS with 2.111.0\n+    static assert(!__traits(compiles, foo.clear));\n+}\n+\n+/***************************************************/\n+\n+// https://github.com/dlang/dmd/issues/22567\n+void test22567()\n+{\n+    struct S\n+    {\n+        string[string] data;\n+        alias this = data;\n+    }\n+\n+    S[string] foo;\n+    foo[\"bar\"] = S();\n+    foo[\"bar\"][\"baz\"] = \"boom\";\n+    assert(foo[\"bar\"][\"baz\"] == \"boom\");\n+}\n+\n /***************************************************/\n \n void main()\n@@ -421,4 +488,7 @@ void main()\n     test12403();\n     test21066();\n     test22354();\n+    testShared();\n+    test22567();\n+    test22556();\n }\ndiff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE\nindex 434ad554b84..a5b457e873c 100644\n--- a/libphobos/libdruntime/MERGE\n+++ b/libphobos/libdruntime/MERGE\n@@ -1,4 +1,4 @@\n-e7c34c13de2930f2becc484e12b2c2cf1a16f6e8\n+662104f52607c175ecb80633bd261932aa004561\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/core/atomic.d b/libphobos/libdruntime/core/atomic.d\nindex 7e97b9d53fa..7ca0ecd4e12 100644\n--- a/libphobos/libdruntime/core/atomic.d\n+++ b/libphobos/libdruntime/core/atomic.d\n@@ -33,6 +33,13 @@ import core.internal.atomic;\n import core.internal.attributes : betterC;\n import core.internal.traits : hasUnsharedIndirections;\n \n+// Low-level atomic helpers still need to hand shared reference payloads to the\n+// backend intrinsics under `-preview=nosharedaccess`.\n+private T unsharedLoadRef(T)(scope ref shared T value) pure nothrow @nogc @trusted\n+{\n+    return *cast(T*)&value;\n+}\n+\n /**\n  * Specifies the memory ordering semantics of an atomic operation.\n  *\n@@ -259,7 +266,7 @@ in (atomicPtrIsProperlyAligned(here), \"Argument `here` is not properly aligned\")\n {\n     static assert (is (V : T), \"Can't assign `exchangeWith` of type `\" ~ shared(V).stringof ~ \"` to `\" ~ shared(T).stringof ~ \"`.\");\n \n-    return cast(shared)core.internal.atomic.atomicExchange!ms(cast(T*)here, cast(V)exchangeWith);\n+    return cast(shared)core.internal.atomic.atomicExchange!ms(cast(T*)here, unsharedLoadRef(exchangeWith));\n }\n \n /**\n@@ -326,7 +333,7 @@ template cas(MemoryOrder succ = MemoryOrder.seq, MemoryOrder fail = MemoryOrder.\n     in (atomicPtrIsProperlyAligned(here), \"Argument `here` is not properly aligned\")\n     {\n         return atomicCompareExchangeStrongNoResult!(succ, fail)(\n-            cast(T*)here, cast(V1)ifThis, cast(V2)writeThis);\n+            cast(T*)here, unsharedLoadRef(ifThis), unsharedLoadRef(writeThis));\n     }\n \n     /// Compare-and-exchange for non-`shared` types\n@@ -378,7 +385,7 @@ template cas(MemoryOrder succ = MemoryOrder.seq, MemoryOrder fail = MemoryOrder.\n     in (atomicPtrIsProperlyAligned(here), \"Argument `here` is not properly aligned\")\n     {\n         return atomicCompareExchangeStrong!(succ, fail)(\n-            cast(T*)here, cast(T*)ifThis, cast(V)writeThis);\n+            cast(T*)here, cast(T*)ifThis, unsharedLoadRef(writeThis));\n     }\n }\n \n@@ -835,11 +842,11 @@ version (CoreUnittest)\n         T         base = cast(T)null;\n         shared(T) atom = cast(shared(T))null;\n \n-        assert(base !is val, T.stringof);\n-        assert(atom is base, T.stringof);\n+        assert(atomicLoad(base) !is atomicLoad(val), T.stringof);\n+        assert(atomicLoad(atom) is atomicLoad(base), T.stringof);\n \n-        assert(atomicExchange(&atom, val) is base, T.stringof);\n-        assert(atom is val, T.stringof);\n+        assert(atomicExchange(&atom, atomicLoad(val)) is atomicLoad(base), T.stringof);\n+        assert(atomicLoad(atom) is atomicLoad(val), T.stringof);\n     }\n \n     void testCAS(T)(T val) pure nothrow @nogc @trusted\n@@ -852,25 +859,26 @@ version (CoreUnittest)\n         T         base = cast(T)null;\n         shared(T) atom = cast(shared(T))null;\n \n-        assert(base !is val, T.stringof);\n-        assert(atom is base, T.stringof);\n+        assert(atomicLoad(base) !is atomicLoad(val), T.stringof);\n+        assert(atomicLoad(atom) is atomicLoad(base), T.stringof);\n \n-        assert(cas(&atom, base, val), T.stringof);\n-        assert(atom is val, T.stringof);\n-        assert(!cas(&atom, base, base), T.stringof);\n-        assert(atom is val, T.stringof);\n+        assert(cas(&atom, atomicLoad(base), atomicLoad(val)), T.stringof);\n+        assert(atomicLoad(atom) is atomicLoad(val), T.stringof);\n+        assert(!cas(&atom, atomicLoad(base), atomicLoad(base)), T.stringof);\n+        assert(atomicLoad(atom) is atomicLoad(val), T.stringof);\n \n-        atom = cast(shared(T))null;\n+        atomicStore(atom, cast(shared(T))null);\n \n-        shared(T) arg = base;\n-        assert(cas(&atom, &arg, val), T.stringof);\n-        assert(arg is base, T.stringof);\n-        assert(atom is val, T.stringof);\n+        shared(T) arg = cast(shared(T))null;\n+        atomicStore(arg, atomicLoad(base));\n+        assert(cas(&atom, &arg, atomicLoad(val)), T.stringof);\n+        assert(atomicLoad(arg) is atomicLoad(base), T.stringof);\n+        assert(atomicLoad(atom) is atomicLoad(val), T.stringof);\n \n-        arg = base;\n-        assert(!cas(&atom, &arg, base), T.stringof);\n-        assert(arg is val, T.stringof);\n-        assert(atom is val, T.stringof);\n+        atomicStore(arg, atomicLoad(base));\n+        assert(!cas(&atom, &arg, atomicLoad(base)), T.stringof);\n+        assert(atomicLoad(arg) is atomicLoad(val), T.stringof);\n+        assert(atomicLoad(atom) is atomicLoad(val), T.stringof);\n     }\n \n     void testLoadStore(MemoryOrder ms = MemoryOrder.seq, T)(T val = T.init + 1) pure nothrow @nogc @trusted\n@@ -878,23 +886,34 @@ version (CoreUnittest)\n         T         base = cast(T) 0;\n         shared(T) atom = cast(T) 0;\n \n-        assert(base !is val);\n-        assert(atom is base);\n-        atomicStore!(ms)(atom, val);\n-        base = atomicLoad!(ms)(atom);\n+        assert(atomicLoad(base) !is atomicLoad(val));\n+        assert(atomicLoad(atom) is atomicLoad(base));\n+        atomicStore!(ms)(atom, atomicLoad(val));\n+        auto loaded = atomicLoad!(ms)(atom);\n \n-        assert(base is val, T.stringof);\n-        assert(atom is val);\n+        assert(loaded is atomicLoad(val), T.stringof);\n+        assert(atomicLoad(atom) is atomicLoad(val));\n     }\n \n \n-    void testType(T)(T val = T.init + 1) pure nothrow @nogc @safe\n+    // This test-only helper synthesizes distinct sentinel values for low-level\n+    // atomic operations, including shared pointers that cannot be formed in\n+    // @safe code.\n+    private T testValue(T)() pure nothrow @nogc @trusted\n+    {\n+        static if (is(T == U*, U))\n+            return cast(T)1;\n+        else\n+            return T.init + 1;\n+    }\n+\n+    void testType(T)(T val = testValue!T()) pure nothrow @nogc @safe\n     {\n         static if (T.sizeof < 8 || has64BitXCHG)\n-            testXCHG!(T)(val);\n-        testCAS!(T)(val);\n-        testLoadStore!(MemoryOrder.seq, T)(val);\n-        testLoadStore!(MemoryOrder.raw, T)(val);\n+            testXCHG!(T)(atomicLoad(val));\n+        testCAS!(T)(atomicLoad(val));\n+        testLoadStore!(MemoryOrder.seq, T)(atomicLoad(val));\n+        testLoadStore!(MemoryOrder.raw, T)(atomicLoad(val));\n     }\n \n     @betterC @safe pure nothrow unittest\n@@ -946,30 +965,30 @@ version (CoreUnittest)\n                 shared(Big) arg;\n                 shared(Big) val = Big(1, 2);\n \n-                assert(cas(&atom, arg, val), Big.stringof);\n-                assert(atom is val, Big.stringof);\n-                assert(!cas(&atom, arg, val), Big.stringof);\n-                assert(atom is val, Big.stringof);\n+                assert(cas(&atom, atomicLoad(arg), atomicLoad(val)), Big.stringof);\n+                assert(atomicLoad(atom) is atomicLoad(val), Big.stringof);\n+                assert(!cas(&atom, atomicLoad(arg), atomicLoad(val)), Big.stringof);\n+                assert(atomicLoad(atom) is atomicLoad(val), Big.stringof);\n \n-                atom = Big();\n-                assert(cas(&atom, &arg, val), Big.stringof);\n-                assert(arg is base, Big.stringof);\n-                assert(atom is val, Big.stringof);\n+                atomicStore(atom, Big());\n+                assert(cas(&atom, &arg, atomicLoad(val)), Big.stringof);\n+                assert(atomicLoad(arg) is atomicLoad(base), Big.stringof);\n+                assert(atomicLoad(atom) is atomicLoad(val), Big.stringof);\n \n-                arg = Big();\n-                assert(!cas(&atom, &arg, base), Big.stringof);\n-                assert(arg is val, Big.stringof);\n-                assert(atom is val, Big.stringof);\n+                atomicStore(arg, Big());\n+                assert(!cas(&atom, &arg, atomicLoad(base)), Big.stringof);\n+                assert(atomicLoad(arg) is atomicLoad(val), Big.stringof);\n+                assert(atomicLoad(atom) is atomicLoad(val), Big.stringof);\n             }();\n         }\n \n         shared(size_t) i;\n \n         atomicOp!\"+=\"(i, cast(size_t) 1);\n-        assert(i == 1);\n+        assert(atomicLoad(i) == 1);\n \n         atomicOp!\"-=\"(i, cast(size_t) 1);\n-        assert(i == 0);\n+        assert(atomicLoad(i) == 0);\n \n         shared float f = 0.1f;\n         atomicOp!\"+=\"(f, 0.1f);\n@@ -995,10 +1014,12 @@ version (CoreUnittest)\n \n             align(16) shared DoubleValue a;\n             atomicStore(a, DoubleValue(1,2));\n-            assert(a.value1 == 1 && a.value2 ==2);\n+            auto initial = atomicLoad(a);\n+            assert(initial.value1 == 1 && initial.value2 == 2);\n \n             while (!cas(&a, DoubleValue(1,2), DoubleValue(3,4))){}\n-            assert(a.value1 == 3 && a.value2 ==4);\n+            auto updated = atomicLoad(a);\n+            assert(updated.value1 == 3 && updated.value2 == 4);\n \n             align(16) DoubleValue b = atomicLoad(a);\n             assert(b.value1 == 3 && b.value2 ==4);\n@@ -1056,7 +1077,8 @@ version (CoreUnittest)\n     @betterC pure nothrow unittest\n     {\n         static struct S { int val; }\n-        auto s = shared(S)(1);\n+        shared S s;\n+        atomicStore(s, S(1));\n \n         shared(S*) ptr;\n \n@@ -1070,7 +1092,7 @@ version (CoreUnittest)\n         // head shared\n         shared(S*) ifThis2 = writeThis;\n         shared(S*) writeThis2 = null;\n-        assert(cas(&ptr, ifThis2, writeThis2));\n+        assert(cas(&ptr, atomicLoad(ifThis2), atomicLoad(writeThis2)));\n         assert(ptr is null);\n     }\n \n@@ -1174,12 +1196,12 @@ version (CoreUnittest)\n         shared ulong a = 2;\n         uint b = 1;\n         atomicOp!\"-=\"(a, b);\n-        assert(a == 1);\n+        assert(atomicLoad(a) == 1);\n \n         shared uint c = 2;\n         ubyte d = 1;\n         atomicOp!\"-=\"(c, d);\n-        assert(c == 1);\n+        assert(atomicLoad(c) == 1);\n     }\n \n     pure nothrow @safe unittest // https://issues.dlang.org/show_bug.cgi?id=16230\n@@ -1232,6 +1254,6 @@ version (CoreUnittest)\n         shared uint si2 = 38;\n         shared uint* psi = &si1;\n \n-        assert((&psi).cas(cast(const) psi, &si2));\n+        assert((&psi).cas(cast(const) atomicLoad(psi), &si2));\n     }\n }\ndiff --git a/libphobos/libdruntime/core/attribute.d b/libphobos/libdruntime/core/attribute.d\nindex 2b35b8d7c0e..5e9a97ff987 100644\n--- a/libphobos/libdruntime/core/attribute.d\n+++ b/libphobos/libdruntime/core/attribute.d\n@@ -83,6 +83,32 @@ else\n     // GDC and LDC declare this attribute in their own modules.\n }\n \n+/**\n+* When applied to a global variable, causes it to be emitted to a\n+* non-standard object file/executable section.\n+*\n+* The target platform might impose certain restrictions on the format for\n+* section names.\n+*\n+* Examples:\n+* ---\n+* import core.attributes;\n+*\n+* @section(\"mySection\") int myGlobal;\n+* ---\n+*/\n+version (DigitalMars)\n+{\n+    struct section\n+    {\n+        string name;\n+    }\n+}\n+else\n+{\n+    // GDC and LDC declare this attribute in their own modules.\n+}\n+\n /**\n  * Use this attribute to attach an Objective-C selector to a method.\n  *\ndiff --git a/libphobos/libdruntime/core/gc/config.d b/libphobos/libdruntime/core/gc/config.d\nindex 32de5ab1409..c3b79e0926b 100644\n--- a/libphobos/libdruntime/core/gc/config.d\n+++ b/libphobos/libdruntime/core/gc/config.d\n@@ -25,6 +25,12 @@ struct Config\n     @MemVal size_t minPoolSize = 1  << 20;  // initial and minimum pool size (bytes)\n     @MemVal size_t maxPoolSize = 64 << 20;  // maximum pool size (bytes)\n     @MemVal size_t incPoolSize = 3  << 20;  // pool size increment (bytes)\n+\n+    // Limit under which the GC will try to keep its heap (bytes)\n+    // The GC does this on a best effort basis, and exceeding this size\n+    // might lead to a performance cliff.\n+    @MemVal size_t heapSizeLimit = size_t.max;\n+\n     uint parallel = 99;      // number of additional threads for marking (limited by cpuid.threadsPerCPU-1)\n     float heapSizeFactor = 2.0; // heap size to used memory ratio\n     string cleanup = \"collect\"; // select gc cleanup method none|collect|finalize\ndiff --git a/libphobos/libdruntime/core/internal/array/capacity.d b/libphobos/libdruntime/core/internal/array/capacity.d\nindex 833918664d9..cbcc3d3b6d2 100644\n--- a/libphobos/libdruntime/core/internal/array/capacity.d\n+++ b/libphobos/libdruntime/core/internal/array/capacity.d\n@@ -142,7 +142,10 @@ do\n     auto attrs = __typeAttrs!T((*p).ptr) | BlkAttr.APPENDABLE;\n \n     // use this static enum to avoid recomputing TypeInfo for every call.\n-    static enum ti = typeid(T);\n+    version (D_TypeInfo)\n+        static enum ti = typeid(T);\n+    else\n+        static enum ti = null;\n     auto ptr = GC.malloc(reqsize, attrs, ti);\n     if (ptr is null)\n     {\n@@ -222,7 +225,16 @@ size_t _d_arraysetlengthT(Tarr : T[], T)(return ref scope Tarr arr, size_t newle\n     // Call the implementation with the unqualified array and sharedness flag\n     size_t result = _d_arraysetlengthT_(unqual_arr, newlength, isShared);\n \n-    arr = cast(Tarr) unqual_arr;\n+    static if (isShared)\n+    {\n+        // This low-level primitive mutates the caller's shared slice header, so\n+        // the caller must already provide whatever synchronization makes that\n+        // header update valid; the cast only preserves that existing contract\n+        // under `-preview=nosharedaccess`.\n+        *cast(UnqT[]*) &arr = unqual_arr;\n+    }\n+    else\n+        arr = cast(Tarr) unqual_arr;\n     // Return the result\n     return result;\n }\n@@ -392,6 +404,8 @@ version (D_ProfileGC)\n     shared S[] arr2;\n     _d_arraysetlengthT!(typeof(arr2))(arr2, 16);\n     assert(arr2.length == 16);\n-    foreach (s; arr2)\n+    // The resized slice has not been published yet, so the test may inspect\n+    // the backing storage directly to verify initialization.\n+    foreach (s; (() @trusted => *cast(S[]*) &arr2)())\n         assert(s == S.init);\n }\ndiff --git a/libphobos/libdruntime/core/internal/array/construction.d b/libphobos/libdruntime/core/internal/array/construction.d\nindex 4797244993f..4b47e20b0a4 100644\n--- a/libphobos/libdruntime/core/internal/array/construction.d\n+++ b/libphobos/libdruntime/core/internal/array/construction.d\n@@ -672,7 +672,10 @@ void* _d_arrayliteralTX(T)(size_t length) @trusted pure nothrow\n         static if (is(T == struct) && hasElaborateDestructor!T)\n             attrs |= BlkAttr.FINALIZE;\n \n-        return GC.malloc(allocsize, attrs, typeid(T));\n+        version (D_TypeInfo)\n+            return GC.malloc(allocsize, attrs, typeid(T));\n+        else\n+            return GC.malloc(allocsize, attrs, null);\n     }\n }\n \ndiff --git a/libphobos/libdruntime/core/internal/array/duplication.d b/libphobos/libdruntime/core/internal/array/duplication.d\nindex a9b599cfc35..ff9e1edb4da 100644\n--- a/libphobos/libdruntime/core/internal/array/duplication.d\n+++ b/libphobos/libdruntime/core/internal/array/duplication.d\n@@ -29,13 +29,32 @@ U[] _dup(T, U)(scope T[] a) pure nothrow @trusted if (__traits(isPOD, T))\n \n U[] _dupCtfe(T, U)(scope T[] a)\n {\n+    import core.internal.traits : Unqual;\n+\n     static if (is(T : void))\n         assert(0, \"Cannot dup a void[] array at compile time.\");\n     else\n     {\n         U[] res;\n-        foreach (ref e; a)\n-            res ~= e;\n+        static if (is(T == shared SharedPayload, SharedPayload))\n+        {\n+            // CTFE still needs a low-level element copy path for shared POD\n+            // arrays because `.dup` models the runtime bitcopy before any\n+            // synchronization policy is applied to the duplicated slice.\n+            Unqual!U[] tmp;\n+            foreach (i; 0 .. a.length)\n+                // This cast is only to make the CTFE path express the same raw\n+                // element copy that the runtime POD implementation performs\n+                // with memcpy; it is not meant as a synchronized access pattern\n+                // for published shared data.\n+                tmp ~= (cast(Unqual!T[]) a)[i];\n+            res = cast(typeof(res)) tmp;\n+        }\n+        else\n+        {\n+            foreach (ref e; a)\n+                res ~= e;\n+        }\n         return res;\n     }\n }\n@@ -327,9 +346,9 @@ U[] _dup(T, U)(T[] a) if (!__traits(isPOD, T))\n         {\n             if (l != 0xDEADBEEF)\n             {\n-                import core.stdc.stdio : fflush, printf, stdout;\n+                import core.stdc.stdio : fflush, printf;\n                 printf(\"Unexpected value: %lld\\n\", l);\n-                fflush(stdout);\n+                fflush(null);\n                 assert(false);\n             }\n         }\ndiff --git a/libphobos/libdruntime/core/internal/array/equality.d b/libphobos/libdruntime/core/internal/array/equality.d\nindex 7a7dc5ceb26..a94c6b6a887 100644\n--- a/libphobos/libdruntime/core/internal/array/equality.d\n+++ b/libphobos/libdruntime/core/internal/array/equality.d\n@@ -49,25 +49,39 @@ bool __equals(T1, T2, size_t N, size_t M)(scope ref T1[N] lhs, scope ref T2[M] r\n private\n bool isEqual(T1, T2)(scope T1[] lhs, scope T2[] rhs, size_t length)\n {\n-    // Returns a reference to an array element, eliding bounds check and\n-    // casting void to ubyte.\n-    pragma(inline, true)\n-    static ref at(T)(scope T[] r, size_t i) @trusted\n-        // exclude opaque structs due to https://issues.dlang.org/show_bug.cgi?id=20959\n-        if (!(is(T == struct) && !is(typeof(T.sizeof))))\n+    static if (is(T1 == T2) &&\n+               (__traits(isIntegral, T1) || is(T1 == char) || is(T1 == wchar) ||\n+                is(T1 == dchar) || is(T1 == bool) || is(T1 == class)))\n     {\n-        static if (is(T == void))\n-            return (cast(ubyte[]) r)[i];\n-        else\n-            return r[i];\n+        foreach (i; 0 .. length)\n+        {\n+            if (lhs.ptr[i] != rhs.ptr[i])\n+                return false;\n+        }\n+        return true;\n     }\n-\n-    foreach (const i; 0 .. length)\n+    else\n     {\n-        if (at(lhs, i) != at(rhs, i))\n-            return false;\n+        // Returns a reference to an array element, eliding bounds check and\n+        // casting void to ubyte.\n+        pragma(inline, true)\n+        static ref at(T)(scope T[] r, size_t i) @trusted\n+        // exclude opaque structs due to https://issues.dlang.org/show_bug.cgi?id=20959\n+        if (!(is(T == struct) && !is(typeof(T.sizeof))))\n+        {\n+            static if (is(T == void))\n+                return (cast(ubyte[]) r)[i];\n+            else\n+                return r[i];\n+        }\n+\n+        foreach (const i; 0 .. length)\n+        {\n+            if (at(lhs, i) != at(rhs, i))\n+                return false;\n+        }\n+        return true;\n     }\n-    return true;\n }\n \n @safe unittest\ndiff --git a/libphobos/libdruntime/core/internal/array/utils.d b/libphobos/libdruntime/core/internal/array/utils.d\nindex 9eae8f092b2..40caa39c89e 100644\n--- a/libphobos/libdruntime/core/internal/array/utils.d\n+++ b/libphobos/libdruntime/core/internal/array/utils.d\n@@ -151,12 +151,22 @@ void[] __arrayAlloc(T)(size_t arrSize) @trusted\n     static if (!hasIndirections!T)\n         attr |= BlkAttr.NO_SCAN;\n \n-    auto ptr = GC.malloc(arrSize, attr, typeid(T));\n+    version(D_TypeInfo)\n+        auto ptr = GC.malloc(arrSize, attr, typeid(T));\n+    else\n+        auto ptr = GC.malloc(arrSize, attr, null);\n     if (ptr)\n         return ptr[0 .. arrSize];\n     return null;\n }\n \n+// https://github.com/dlang/dmd/issues/22517\n+@system unittest\n+{\n+    auto arr = new void[10];\n+    assert((GC.getAttr(&arr[0]) & BlkAttr.NO_SCAN) == 0);\n+}\n+\n /**\n Given an array of length `size` that needs to be expanded to `newlength`,\n compute a new capacity.\ndiff --git a/libphobos/libdruntime/core/internal/atomic.d b/libphobos/libdruntime/core/internal/atomic.d\nindex 43e50acacb7..9daddf844a7 100644\n--- a/libphobos/libdruntime/core/internal/atomic.d\n+++ b/libphobos/libdruntime/core/internal/atomic.d\n@@ -13,6 +13,84 @@ module core.internal.atomic;\n import core.atomic : has128BitCAS, MemoryOrder;\n \n version (DigitalMars)\n+version (AArch64)\n+{\n+    /* These functions are all stubbed out. They await someone who knows what\n+       they are doing with AArch64 atomics.\n+       TODO AArch64\n+     */\n+    enum IsAtomicLockFree(T) = T.sizeof <= size_t.sizeof * 2;\n+\n+    inout(T) atomicLoad(MemoryOrder order = MemoryOrder.seq, T)(inout(T)* src) pure nothrow @nogc @trusted\n+        if (CanCAS!T)\n+    {\n+        return *src;\n+    }\n+\n+    void atomicStore(MemoryOrder order = MemoryOrder.seq, T)(T* dest, T value) pure nothrow @nogc @trusted\n+        if (CanCAS!T)\n+    {\n+        *dest = value;\n+    }\n+\n+    T atomicFetchAdd(MemoryOrder order = MemoryOrder.seq, bool result = true, T)(T* dest, T value) pure nothrow @nogc @trusted\n+        if (is(T : ulong))\n+    {\n+\treturn *dest + value;\n+    }\n+\n+    T atomicFetchSub(MemoryOrder order = MemoryOrder.seq, bool result = true, T)(T* dest, T value) pure nothrow @nogc @trusted\n+        if (is(T : ulong))\n+    {\n+        return atomicFetchAdd(dest, cast(T)-cast(IntOrLong!T)value);\n+    }\n+\n+    T atomicExchange(MemoryOrder order = MemoryOrder.seq, bool result = true, T)(T* dest, T value) pure nothrow @nogc @trusted\n+    if (CanCAS!T)\n+    {\n+        size_t storage = void;\n+        return *cast(T*)&storage;\n+    }\n+\n+    alias atomicCompareExchangeWeak = atomicCompareExchangeStrong;\n+\n+    bool atomicCompareExchangeStrong(MemoryOrder succ = MemoryOrder.seq, MemoryOrder fail = MemoryOrder.seq, T)(T* dest, T* compare, T value) pure nothrow @nogc @trusted\n+        if (CanCAS!T)\n+    {\n+        if (*dest != *compare)\n+        {\n+            *compare = *dest;\n+            return false;\n+        }\n+        *dest = value;\n+        return true;\n+    }\n+\n+    alias atomicCompareExchangeWeakNoResult = atomicCompareExchangeStrongNoResult;\n+\n+    bool atomicCompareExchangeStrongNoResult(MemoryOrder succ = MemoryOrder.seq, MemoryOrder fail = MemoryOrder.seq, T)(T* dest, const T compare, T value) pure nothrow @nogc @trusted\n+        if (CanCAS!T)\n+    {\n+        if (*dest != compare)\n+            return false;\n+        *dest = value;\n+        return true;\n+    }\n+\n+    void atomicFence(MemoryOrder order = MemoryOrder.seq)() pure nothrow @nogc @trusted\n+    {\n+    }\n+\n+    void atomicSignalFence(MemoryOrder order = MemoryOrder.seq)() pure nothrow @nogc @trusted\n+    {\n+        // no-op, dmd doesn't reorder instructions\n+    }\n+\n+    void pause() pure nothrow @nogc @trusted\n+    {\n+    }\n+}\n+else // X86 and X86_64\n {\n     private\n     {\ndiff --git a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d\nindex ae40bd363da..1c7025a2062 100644\n--- a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d\n+++ b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d\n@@ -2113,10 +2113,25 @@ struct Gcx\n      */\n     void updateCollectThresholds() nothrow\n     {\n-        static float max(float a, float b) nothrow\n-        {\n-            return a >= b ? a : b;\n-        }\n+        import core.internal.util.math : min, max;\n+\n+        // Reserve half of the remaining heap budget to small and large heaps.\n+        immutable maxPageUsed = config.heapSizeLimit / PAGESIZE;\n+        immutable usedPages = usedSmallPages + usedLargePages;\n+        immutable heapBudget = maxPageUsed > usedPages\n+            ? maxPageUsed - usedPages\n+            : 0;\n+\n+        immutable smTargetHeap = usedSmallPages + heapBudget / 2;\n+        immutable lgTargetHeap = usedLargePages + heapBudget / 2;\n+\n+        // Compute the target sizes based on the growth factor.\n+        immutable smTargetGrowth = usedSmallPages * config.heapSizeFactor;\n+        immutable lgTargetGrowth = usedLargePages * config.heapSizeFactor;\n+\n+        // Collect when either is reached.\n+        immutable smTarget = min(smTargetHeap, smTargetGrowth);\n+        immutable lgTarget = min(lgTargetHeap, lgTargetGrowth);\n \n         // instantly increases, slowly decreases\n         static float smoothDecay(float oldVal, float newVal) nothrow\n@@ -2128,9 +2143,7 @@ struct Gcx\n             return max(newVal, decay);\n         }\n \n-        immutable smTarget = usedSmallPages * config.heapSizeFactor;\n         smallCollectThreshold = smoothDecay(smallCollectThreshold, smTarget);\n-        immutable lgTarget = usedLargePages * config.heapSizeFactor;\n         largeCollectThreshold = smoothDecay(largeCollectThreshold, lgTarget);\n     }\n \n@@ -3525,8 +3538,8 @@ Lmark:\n                         cstdlib.free(Gcx.instance.scanThreadData);\n                         Gcx.instance.numScanThreads = 0;\n                         Gcx.instance.scanThreadData = null;\n-                        Gcx.instance.busyThreads = 0;\n-                        Gcx.instance.stackLock = shared(AlignedSpinLock)(SpinLock.Contention.brief);\n+                        atomicStore(Gcx.instance.busyThreads, 0);\n+                        (cast() Gcx.instance.stackLock) = AlignedSpinLock(SpinLock.Contention.brief);\n \n                         memset(&Gcx.instance.evStackFilled, 0, Gcx.instance.evStackFilled.sizeof);\n                         memset(&Gcx.instance.evDone, 0, Gcx.instance.evDone.sizeof);\ndiff --git a/libphobos/libdruntime/core/internal/lifetime.d b/libphobos/libdruntime/core/internal/lifetime.d\nindex 053b3edc69d..fb28b11f084 100644\n--- a/libphobos/libdruntime/core/internal/lifetime.d\n+++ b/libphobos/libdruntime/core/internal/lifetime.d\n@@ -94,7 +94,14 @@ if (!is(T == const) && !is(T == immutable) && !is(T == inout))\n {\n     import core.internal.traits : hasElaborateAssign;\n \n-    static if (__traits(isZeroInit, T))\n+    static if (is(T == shared U, U))\n+    {\n+        // Initialization happens before the shared object is published, so the\n+        // helper has to operate on the backing storage instead of performing an\n+        // ordinary shared write that `-preview=nosharedaccess` rejects.\n+        emplaceInitializer(*cast(U*) &chunk);\n+    }\n+    else static if (__traits(isZeroInit, T))\n     {\n         import core.stdc.string : memset;\n         memset(cast(void*) &chunk, 0, T.sizeof);\n@@ -135,7 +142,9 @@ if (!is(T == const) && !is(T == immutable) && !is(T == inout))\n         {\n             shared T dst = void;\n             emplaceInitializer(dst);\n-            assert(dst is shared(T).init);\n+            // The initializer has not been published yet, so the test may read\n+            // the backing storage directly to verify that emplace wrote T.init.\n+            assert((() @trusted => (*cast(T*) &dst) is T.init)());\n         }\n \n         // const T\ndiff --git a/libphobos/libdruntime/core/internal/newaa.d b/libphobos/libdruntime/core/internal/newaa.d\nindex 55bc16e5e8b..bd95fb1ea6b 100644\n--- a/libphobos/libdruntime/core/internal/newaa.d\n+++ b/libphobos/libdruntime/core/internal/newaa.d\n@@ -463,6 +463,18 @@ size_t _d_aaLen(K, V)(inout V[K] a)\n     auto aa = _toAA!(K, V)(a);\n     return aa ? aa.length : 0;\n }\n+/// ditto\n+size_t _d_aaLen(K, V)(shared V[K] a)\n+{\n+    // accept shared for backward compatibility, should be deprecated\n+    return _d_aaLen(cast(V[K]) a);\n+}\n+/// ditto\n+size_t _d_aaLen(K, V)(const shared V[K] a)\n+{\n+    // accept shared for backward compatibility, should be deprecated\n+    return _d_aaLen(cast(V[K]) a);\n+}\n \n /******************************\n  * Lookup key in aa.\n@@ -631,6 +643,18 @@ auto _d_aaIn(T : V[K], K, V, K2)(inout T a, auto ref scope K2 key)\n         return &p.entry.value;\n     return null;\n }\n+/// ditto\n+auto _d_aaIn(T : V[K], K, V, K2)(shared T a, auto ref scope K2 key)\n+{\n+    // accept shared for backward compatibility, should be deprecated\n+    return _d_aaIn(cast(V[K]) a, key);\n+}\n+/// ditto\n+auto _d_aaIn(T : V[K], K, V, K2)(const shared T a, auto ref scope K2 key)\n+{\n+    // accept shared for backward compatibility, should be deprecated\n+    return _d_aaIn(cast(V[K]) a, key);\n+}\n \n // fake purity for backward compatibility with runtime hooks\n private extern(C) bool gc_inFinalizer() pure nothrow @safe;\ndiff --git a/libphobos/libdruntime/core/internal/traits.d b/libphobos/libdruntime/core/internal/traits.d\nindex 7ffee2ec0be..df9f4200e54 100644\n--- a/libphobos/libdruntime/core/internal/traits.d\n+++ b/libphobos/libdruntime/core/internal/traits.d\n@@ -285,38 +285,9 @@ template hasElaborateMove(S)\n     }\n }\n \n-// std.traits.hasElaborateDestructor\n-template hasElaborateDestructor(S)\n-{\n-    static if (__traits(isStaticArray, S))\n-    {\n-        enum bool hasElaborateDestructor = S.sizeof && hasElaborateDestructor!(BaseElemOf!S);\n-    }\n-    else static if (is(S == struct))\n-    {\n-        // Once https://issues.dlang.org/show_bug.cgi?id=24865 is fixed, then\n-        // this should be the implementation, but until that's fixed, we need the\n-        // uncommented code.\n-        // enum hasElaborateDestructor = __traits(hasMember, S, \"__xdtor\");\n-\n-        enum hasElaborateDestructor = hasDtor([__traits(allMembers, S)]);\n-    }\n-    else\n-    {\n-        enum bool hasElaborateDestructor = false;\n-    }\n-}\n-\n-private bool hasDtor(string[] members)\n-{\n-    foreach (name; members)\n-    {\n-        if (name == \"__xdtor\")\n-            return true;\n-    }\n-\n-    return false;\n-}\n+// Used by std.traits.hasElaborateDestructor\n+// TODO inline this in druntime\n+enum hasElaborateDestructor(S) = __traits(needsDestruction, S);\n \n @safe unittest\n {\n@@ -331,6 +302,7 @@ private bool hasDtor(string[] members)\n     static assert( hasElaborateDestructor!(HasDestructor[42]));\n     static assert(!hasElaborateDestructor!(HasDestructor[0]));\n     static assert(!hasElaborateDestructor!(HasDestructor[]));\n+    static assert( hasElaborateDestructor!(immutable HasDestructor));\n \n     static struct HasDestructor2 { HasDestructor s; }\n     static assert( hasElaborateDestructor!HasDestructor2);\n@@ -365,6 +337,25 @@ private bool hasDtor(string[] members)\n     static assert(!hasElaborateDestructor!S6);\n }\n \n+// https://github.com/dlang/dmd/issues/21967\n+version (CoreUnittest)\n+private struct Test21967\n+{\n+    // Note: Foward referencing was failing due to:\n+    // https://github.com/dlang/dmd/issues/22524\n+    static assert(hasElaborateDestructor!C);\n+    enum before = hasElaborateDestructor!C;\n+    static assert(before);\n+\n+    struct C\n+    {\n+        ~this() {}\n+    }\n+    static assert(hasElaborateDestructor!C);\n+    enum after = hasElaborateDestructor!C;\n+    static assert(after);\n+}\n+\n // std.traits.hasElaborateCopyDestructor\n template hasElaborateCopyConstructor(S)\n {\n@@ -572,9 +563,11 @@ template hasIndirections(T)\n     else static if (__traits(isAssociativeArray, T) || is(T == class) || is(T == interface))\n         enum hasIndirections = true;\n     else static if (is(T == E[N], E, size_t N))\n-        enum hasIndirections = T.sizeof && (is(immutable E == immutable void) || hasIndirections!(BaseElemOf!E));\n+        enum hasIndirections = T.sizeof && hasIndirections!(BaseElemOf!E);\n     else static if (isFunctionPointer!T)\n         enum hasIndirections = false;\n+    else static if (is(immutable(T) == immutable(void)))\n+        enum hasIndirections = true;\n     else\n         enum hasIndirections = isPointer!T || isDelegate!T || isDynamicArray!T;\n }\n@@ -735,11 +728,11 @@ template hasIndirections(T)\n // https://github.com/dlang/dmd/issues/20812\n @safe unittest\n {\n-    static assert(!hasIndirections!void);\n-    static assert(!hasIndirections!(const void));\n-    static assert(!hasIndirections!(inout void));\n-    static assert(!hasIndirections!(immutable void));\n-    static assert(!hasIndirections!(shared void));\n+    static assert( hasIndirections!void);\n+    static assert( hasIndirections!(const void));\n+    static assert( hasIndirections!(inout void));\n+    static assert( hasIndirections!(immutable void));\n+    static assert( hasIndirections!(shared void));\n \n     static assert( hasIndirections!(void*));\n     static assert( hasIndirections!(const void*));\ndiff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d\nindex ad98b2f2c56..cd38648bc22 100644\n--- a/libphobos/libdruntime/core/lifetime.d\n+++ b/libphobos/libdruntime/core/lifetime.d\n@@ -77,9 +77,11 @@ T* emplace(T, Args...)(T* chunk, auto ref Args args)\n @betterC\n @system unittest\n {\n+    import core.atomic : atomicLoad;\n+\n     shared int i;\n     emplace(&i, 42);\n-    assert(i == 42);\n+    assert(atomicLoad(i) == 42);\n }\n \n /**\n@@ -1246,9 +1248,21 @@ void copyEmplace(S, T)(ref S source, ref T target) @system\n     if (is(immutable S == immutable T))\n {\n     import core.internal.traits : BaseElemOf, hasElaborateCopyConstructor, Unconst, Unqual;\n+    enum isSharedReference = is(S == shared U, U) && is(T == shared V, V) &&\n+        (is(U == class) || is(U == interface)) &&\n+        (is(V == class) || is(V == interface));\n \n     // cannot have the following as simple template constraint due to nested-struct special case...\n-    static if (!__traits(compiles, (ref S src) { T tgt = src; }))\n+    static if (isSharedReference)\n+    {\n+        static assert(__traits(compiles, (ref S src, ref T tgt)\n+        {\n+            import core.atomic : atomicLoad, atomicStore;\n+            atomicStore(tgt, atomicLoad(src));\n+        }), \"cannot copy shared reference \" ~ T.stringof ~ \" from \" ~ S.stringof ~\n+            \" via atomic load/store\");\n+    }\n+    else static if (!__traits(compiles, (ref S src) { T tgt = src; }))\n     {\n         alias B = BaseElemOf!T;\n         enum isNestedStruct = is(B == struct) && __traits(isNested, B);\n@@ -1308,6 +1322,11 @@ void copyEmplace(S, T)(ref S source, ref T target) @system\n             blit(); // all elements at once\n         }\n     }\n+    else static if (isSharedReference)\n+    {\n+        import core.atomic : atomicLoad, atomicStore;\n+        atomicStore(target, atomicLoad(source));\n+    }\n     else\n     {\n         *cast(Unconst!(T)*) &target = *cast(Unconst!(T)*) &source;\n@@ -2396,7 +2415,7 @@ template _d_delstructImpl(T)\n         private enum errorMessage = \"Cannot delete struct if compiling without support for runtime type information!\";\n \n         /**\n-         * TraceGC wrapper around $(REF _d_delstruct, core,lifetime,_d_delstructImpl).\n+         * TraceGC wrapper around $(REF _d_delstruct, core,lifetime).\n          *\n          * Bugs:\n          *   This function template was ported from a much older runtime hook that\n@@ -2762,7 +2781,10 @@ if (is(T == class))\n         static if (!hasIndirections!T)\n             attr |= BlkAttr.NO_SCAN;\n \n-        p = GC.malloc(init.length, attr, typeid(T));\n+        version(D_TypeInfo)\n+            p = GC.malloc(init.length, attr, typeid(T));\n+        else\n+            p = GC.malloc(init.length, attr, null);\n         debug(PRINTF) printf(\" p = %p\\n\", p);\n     }\n \n@@ -2834,7 +2856,10 @@ T* _d_newitemT(T)() @trusted\n     if (TypeInfoSize!T)\n         flags |= GC.BlkAttr.FINALIZE;\n \n-    auto p = GC.malloc(itemSize, flags, typeid(T));\n+    version(D_TypeInfo)\n+        auto p = GC.malloc(itemSize, flags, typeid(T));\n+    else\n+        auto p = GC.malloc(itemSize, flags, null);\n \n     emplaceInitializer(*(cast(T*) p));\n \ndiff --git a/libphobos/libdruntime/core/memory.d b/libphobos/libdruntime/core/memory.d\nindex 3b3cb8e6a66..a4e2d1f2694 100644\n--- a/libphobos/libdruntime/core/memory.d\n+++ b/libphobos/libdruntime/core/memory.d\n@@ -141,7 +141,7 @@ private\n     extern (C) GC.ProfileStats gc_profileStats ( ) nothrow @nogc @safe;\n }\n \n-version (CoreDoc)\n+version (CoreDdoc)\n {\n     /**\n      * The minimum size of a system page in bytes.\ndiff --git a/libphobos/libdruntime/core/stdc/stdatomic.d b/libphobos/libdruntime/core/stdc/stdatomic.d\nindex 966d29d8084..8f4bc6e2e1f 100644\n--- a/libphobos/libdruntime/core/stdc/stdatomic.d\n+++ b/libphobos/libdruntime/core/stdc/stdatomic.d\n@@ -244,7 +244,10 @@ bool atomic_flag_test_and_set_explicit_impl()(atomic_flag* obj, memory_order ord\n pragma(inline, true)\n void atomic_init(A, C)(out shared(A) obj, C desired) @trusted\n {\n-    obj = cast(shared) desired;\n+    // C11 atomic_init is a low-level initialization primitive for atomic storage\n+    // before it is published for concurrent access, so it must be able to write\n+    // the backing object without demonstrating ordinary shared access.\n+    *cast(A*) &obj = cast(A) desired;\n }\n \n ///\ndiff --git a/libphobos/libdruntime/core/stdc/stdint.d b/libphobos/libdruntime/core/stdc/stdint.d\nindex 4f9b98cd8ce..385f4ca5dde 100644\n--- a/libphobos/libdruntime/core/stdc/stdint.d\n+++ b/libphobos/libdruntime/core/stdc/stdint.d\n@@ -337,7 +337,10 @@ else version (OpenBSD)\n }\n else version (Solaris)\n {\n-    alias int8_t   = char;   ///\n+    version (GNU)\n+        alias int8_t = byte; ///\n+    else\n+        alias int8_t = char; ///\n     alias int16_t  = short;  ///\n     alias uint8_t  = ubyte;  ///\n     alias uint16_t = ushort; ///\n@@ -346,7 +349,10 @@ else version (Solaris)\n     alias int64_t  = long;   ///\n     alias uint64_t = ulong;  ///\n \n-    alias int_least8_t   = char;   ///\n+    version (GNU)\n+        alias int_least8_t = byte; ///\n+    else\n+        alias int_least8_t = char; ///\n     alias uint_least8_t  = ubyte;  ///\n     alias int_least16_t  = short;  ///\n     alias uint_least16_t = ushort; ///\n@@ -355,7 +361,10 @@ else version (Solaris)\n     alias int_least64_t  = long;   ///\n     alias uint_least64_t = ulong;  ///\n \n-    alias int_fast8_t   = char;  ///\n+    version (GNU)\n+        alias int_fast8_t = byte; ///\n+    else\n+        alias int_fast8_t = char; ///\n     alias uint_fast8_t  = ubyte; ///\n     alias int_fast16_t  = int;   ///\n     alias uint_fast16_t = uint;  ///\ndiff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d\nindex fcecb9ed562..adb9f9d9a00 100644\n--- a/libphobos/libdruntime/core/stdc/stdio.d\n+++ b/libphobos/libdruntime/core/stdc/stdio.d\n@@ -1475,10 +1475,22 @@ size_t fwrite(scope const void* ptr, size_t size, size_t nmemb, FILE* stream);\n // No unsafe pointer manipulation.\n @trusted\n {\n-    ///\n-    int fgetpos(FILE* stream, scope fpos_t * pos);\n-    ///\n-    int fsetpos(FILE* stream, scope const fpos_t* pos);\n+    version (NetBSD)\n+    {\n+        ///\n+        pragma(mangle, \"__fgetpos50\")\n+        int fgetpos(FILE* stream, scope fpos_t * pos);\n+        ///\n+        pragma(mangle, \"__fsetpos50\")\n+        int fsetpos(FILE* stream, scope const fpos_t* pos);\n+    }\n+    else\n+    {\n+        ///\n+        int fgetpos(FILE* stream, scope fpos_t * pos);\n+        ///\n+        int fsetpos(FILE* stream, scope const fpos_t* pos);\n+    }\n \n     ///\n     int    fseek(FILE* stream, c_long offset, int whence);\ndiff --git a/libphobos/libdruntime/core/stdc/time.d b/libphobos/libdruntime/core/stdc/time.d\nindex d7a57655fab..ead533718b7 100644\n--- a/libphobos/libdruntime/core/stdc/time.d\n+++ b/libphobos/libdruntime/core/stdc/time.d\n@@ -29,26 +29,55 @@ extern (C):\n nothrow:\n @nogc:\n \n-///\n-pragma(mangle, muslRedirTime64Mangle!(\"difftime\", \"__difftime64\"))\n-pure double  difftime(time_t time1, time_t time0); // MT-Safe\n-///\n-pragma(mangle, muslRedirTime64Mangle!(\"mktime\", \"__mktime64\"))\n-@system time_t  mktime(scope tm* timeptr); // @system: MT-Safe env locale\n-///\n-pragma(mangle, muslRedirTime64Mangle!(\"time\", \"__time64\"))\n-time_t  time(scope time_t* timer);\n+version (NetBSD)\n+{\n+    ///\n+    pragma(mangle, \"__difftime50\")\n+    pure double  difftime(time_t time1, time_t time0); // MT-Safe\n+    ///\n+    pragma(mangle, \"__mktime50\")\n+    @system time_t  mktime(scope tm* timeptr); // @system: MT-Safe env locale\n+    ///\n+    pragma(mangle, \"__time50\")\n+    time_t  time(scope time_t* timer);\n \n-///\n-@system char*   asctime(const scope tm* timeptr); // @system: MT-Unsafe race:asctime locale\n-///\n-pragma(mangle, muslRedirTime64Mangle!(\"ctime\", \"__ctime64\"))\n-@system char*   ctime(const scope time_t* timer); // @system: MT-Unsafe race:tmbuf race:asctime env locale\n-///\n-pragma(mangle, muslRedirTime64Mangle!(\"gmtime\", \"__gmtime64\"))\n-@system tm*     gmtime(const scope time_t* timer); // @system: MT-Unsafe race:tmbuf env locale\n-///\n-pragma(mangle, muslRedirTime64Mangle!(\"localtime\", \"__localtime64\"))\n-@system tm*     localtime(const scope time_t* timer); // @system: MT-Unsafe race:tmbuf env locale\n-///\n-@system size_t  strftime(scope char* s, size_t maxsize, const scope char* format, const scope tm* timeptr); // @system: MT-Safe env locale\n+    ///\n+    @system char*   asctime(const scope tm* timeptr); // @system: MT-Unsafe race:asctime locale\n+    ///\n+    pragma(mangle, \"__ctime50\")\n+    @system char*   ctime(const scope time_t* timer); // @system: MT-Unsafe race:tmbuf race:asctime env locale\n+    ///\n+    pragma(mangle, \"__gmtime50\")\n+    @system tm*     gmtime(const scope time_t* timer); // @system: MT-Unsafe race:tmbuf env locale\n+    ///\n+    pragma(mangle, \"__locatime50\")\n+    @system tm*     localtime(const scope time_t* timer); // @system: MT-Unsafe race:tmbuf env locale\n+    ///\n+    @system size_t  strftime(scope char* s, size_t maxsize, const scope char* format, const scope tm* timeptr); // @system: MT-Safe env locale\n+}\n+else\n+{\n+    ///\n+    pragma(mangle, muslRedirTime64Mangle!(\"difftime\", \"__difftime64\"))\n+    pure double  difftime(time_t time1, time_t time0); // MT-Safe\n+    ///\n+    pragma(mangle, muslRedirTime64Mangle!(\"mktime\", \"__mktime64\"))\n+    @system time_t  mktime(scope tm* timeptr); // @system: MT-Safe env locale\n+    ///\n+    pragma(mangle, muslRedirTime64Mangle!(\"time\", \"__time64\"))\n+    time_t  time(scope time_t* timer);\n+\n+    ///\n+    @system char*   asctime(const scope tm* timeptr); // @system: MT-Unsafe race:asctime locale\n+    ///\n+    pragma(mangle, muslRedirTime64Mangle!(\"ctime\", \"__ctime64\"))\n+    @system char*   ctime(const scope time_t* timer); // @system: MT-Unsafe race:tmbuf race:asctime env locale\n+    ///\n+    pragma(mangle, muslRedirTime64Mangle!(\"gmtime\", \"__gmtime64\"))\n+    @system tm*     gmtime(const scope time_t* timer); // @system: MT-Unsafe race:tmbuf env locale\n+    ///\n+    pragma(mangle, muslRedirTime64Mangle!(\"localtime\", \"__localtime64\"))\n+    @system tm*     localtime(const scope time_t* timer); // @system: MT-Unsafe race:tmbuf env locale\n+    ///\n+    @system size_t  strftime(scope char* s, size_t maxsize, const scope char* format, const scope tm* timeptr); // @system: MT-Safe env locale\n+}\ndiff --git a/libphobos/libdruntime/core/sync/condition.d b/libphobos/libdruntime/core/sync/condition.d\nindex 3acee7a7f45..9328f6d4886 100644\n--- a/libphobos/libdruntime/core/sync/condition.d\n+++ b/libphobos/libdruntime/core/sync/condition.d\n@@ -246,7 +246,7 @@ class Condition\n         }\n         else version (Posix)\n         {\n-            int rc = pthread_cond_wait( cast(pthread_cond_t*) &m_hndl, (cast(Mutex) m_assocMutex).handleAddr() );\n+            int rc = pthread_cond_wait( cast(pthread_cond_t*) &m_hndl, (cast(Mutex) mutex()).handleAddr() );\n             if ( rc )\n                 throw staticError!AssertError(\"Unable to wait for condition\", __FILE__, __LINE__);\n         }\n@@ -307,7 +307,7 @@ class Condition\n             mktspec( t, val );\n \n             int rc = pthread_cond_timedwait( cast(pthread_cond_t*) &m_hndl,\n-                                             (cast(Mutex) m_assocMutex).handleAddr(),\n+                                             (cast(Mutex) mutex()).handleAddr(),\n                                              &t );\n             if ( !rc )\n                 return true;\ndiff --git a/libphobos/libdruntime/core/sync/mutex.d b/libphobos/libdruntime/core/sync/mutex.d\nindex 8993f85071b..86a112119d8 100644\n--- a/libphobos/libdruntime/core/sync/mutex.d\n+++ b/libphobos/libdruntime/core/sync/mutex.d\n@@ -100,7 +100,8 @@ class Mutex :\n                 abort(\"Error: pthread_mutex_init failed.\");\n         }\n \n-        m_proxy.link = this;\n+        auto self = cast(Mutex) this;\n+        self.m_proxy.link = self;\n         this.__monitor = cast(void*) &m_proxy;\n     }\n \n@@ -183,13 +184,14 @@ class Mutex :\n     final void lock_nothrow(this Q)() nothrow @trusted @nogc\n         if (is(Q == Mutex) || is(Q == shared Mutex))\n     {\n+        auto self = cast(Mutex) this;\n         version (Windows)\n         {\n-            EnterCriticalSection(&m_hndl);\n+            EnterCriticalSection(&self.m_hndl);\n         }\n         else version (Posix)\n         {\n-            if (pthread_mutex_lock(&m_hndl) == 0)\n+            if (pthread_mutex_lock(&self.m_hndl) == 0)\n                 return;\n \n             SyncError syncErr = cast(SyncError) __traits(initSymbol, SyncError).ptr;\n@@ -221,13 +223,14 @@ class Mutex :\n     final void unlock_nothrow(this Q)() nothrow @trusted @nogc\n         if (is(Q == Mutex) || is(Q == shared Mutex))\n     {\n+        auto self = cast(Mutex) this;\n         version (Windows)\n         {\n-            LeaveCriticalSection(&m_hndl);\n+            LeaveCriticalSection(&self.m_hndl);\n         }\n         else version (Posix)\n         {\n-            if (pthread_mutex_unlock(&m_hndl) == 0)\n+            if (pthread_mutex_unlock(&self.m_hndl) == 0)\n                 return;\n \n             SyncError syncErr = cast(SyncError) __traits(initSymbol, SyncError).ptr;\n@@ -263,13 +266,14 @@ class Mutex :\n     final bool tryLock_nothrow(this Q)() nothrow @trusted @nogc\n         if (is(Q == Mutex) || is(Q == shared Mutex))\n     {\n+        auto self = cast(Mutex) this;\n         version (Windows)\n         {\n-            return TryEnterCriticalSection(&m_hndl) != 0;\n+            return TryEnterCriticalSection(&self.m_hndl) != 0;\n         }\n         else version (Posix)\n         {\n-            return pthread_mutex_trylock(&m_hndl) == 0;\n+            return pthread_mutex_trylock(&self.m_hndl) == 0;\n         }\n     }\n \ndiff --git a/libphobos/libdruntime/core/sync/rwmutex.d b/libphobos/libdruntime/core/sync/rwmutex.d\nindex cb581621ec5..e46b2f736f4 100644\n--- a/libphobos/libdruntime/core/sync/rwmutex.d\n+++ b/libphobos/libdruntime/core/sync/rwmutex.d\n@@ -20,6 +20,7 @@ public import core.sync.exception;\n import core.sync.condition;\n import core.sync.mutex;\n import core.memory;\n+import core.atomic : atomicLoad;\n \n \n ////////////////////////////////////////////////////////////////////////////////\n@@ -107,11 +108,11 @@ class ReadWriteMutex\n         if ( !m_commonMutex )\n             throw new SyncError( \"Unable to initialize mutex\" );\n \n-        m_readerQueue = new shared Condition( m_commonMutex );\n+        m_readerQueue = new shared Condition(atomicLoad(m_commonMutex));\n         if ( !m_readerQueue )\n             throw new SyncError( \"Unable to initialize mutex\" );\n \n-        m_writerQueue = new shared Condition( m_commonMutex );\n+        m_writerQueue = new shared Condition(atomicLoad(m_commonMutex));\n         if ( !m_writerQueue )\n             throw new SyncError( \"Unable to initialize mutex\" );\n \n@@ -139,7 +140,7 @@ class ReadWriteMutex\n     ///ditto\n     @property Policy policy() shared @safe nothrow\n     {\n-        return m_policy;\n+        return atomicLoad(m_policy);\n     }\n \n     ////////////////////////////////////////////////////////////////////////////\n@@ -161,7 +162,7 @@ class ReadWriteMutex\n     ///ditto\n     @property shared(Reader) reader() shared @safe nothrow\n     {\n-        return m_reader;\n+        return atomicLoad(m_reader);\n     }\n \n     /**\n@@ -178,7 +179,7 @@ class ReadWriteMutex\n     ///ditto\n     @property shared(Writer) writer() shared @safe nothrow\n     {\n-        return m_writer;\n+        return atomicLoad(m_writer);\n     }\n \n \n@@ -200,7 +201,7 @@ class ReadWriteMutex\n         this(this Q)() @trusted nothrow\n             if (is(Q == Reader) || is(Q == shared Reader))\n         {\n-            m_proxy.link = this;\n+            m_proxy.link = cast(typeof(m_proxy.link)) this;\n             this.__monitor = cast(void*) &m_proxy;\n         }\n \n@@ -223,15 +224,7 @@ class ReadWriteMutex\n         /// ditto\n         @trusted void lock() shared\n         {\n-            synchronized( m_commonMutex )\n-            {\n-                ++(cast()m_numQueuedReaders);\n-                scope(exit) --(cast()m_numQueuedReaders);\n-\n-                while ( shouldQueueReader )\n-                    m_readerQueue.wait();\n-                ++(cast()m_numActiveReaders);\n-            }\n+            (cast() this).lock();\n         }\n \n         /**\n@@ -252,14 +245,7 @@ class ReadWriteMutex\n         /// ditto\n         @trusted void unlock() shared\n         {\n-            synchronized( m_commonMutex )\n-            {\n-                if ( --(cast()m_numActiveReaders) < 1 )\n-                {\n-                    if ( m_numQueuedWriters > 0 )\n-                        m_writerQueue.notify();\n-                }\n-            }\n+            (cast() this).unlock();\n         }\n \n         /**\n@@ -284,13 +270,7 @@ class ReadWriteMutex\n         /// ditto\n         @trusted bool tryLock() shared\n         {\n-            synchronized( m_commonMutex )\n-            {\n-                if ( shouldQueueReader )\n-                    return false;\n-                ++(cast()m_numActiveReaders);\n-                return true;\n-            }\n+            return (cast() this).tryLock();\n         }\n \n         /**\n@@ -341,25 +321,7 @@ class ReadWriteMutex\n         /// ditto\n         @trusted bool tryLock(Duration timeout) shared\n         {\n-            const initialTime = MonoTime.currTime;\n-            synchronized( m_commonMutex )\n-            {\n-                ++(cast()m_numQueuedReaders);\n-                scope(exit) --(cast()m_numQueuedReaders);\n-\n-                while (shouldQueueReader)\n-                {\n-                    const timeElapsed = MonoTime.currTime - initialTime;\n-                    if (timeElapsed >= timeout)\n-                        return false;\n-                    auto nextWait = timeout - timeElapsed;\n-                    // Avoid problems calling wait(Duration) with huge arguments.\n-                    enum maxWaitPerCall = dur!\"hours\"(24 * 365);\n-                    m_readerQueue.wait(nextWait < maxWaitPerCall ? nextWait : maxWaitPerCall);\n-                }\n-                ++(cast()m_numActiveReaders);\n-                return true;\n-            }\n+            return (cast() this).tryLock(timeout);\n         }\n \n \n@@ -410,7 +372,7 @@ class ReadWriteMutex\n         this(this Q)() @trusted nothrow\n             if (is(Q == Writer) || is(Q == shared Writer))\n         {\n-            m_proxy.link = this;\n+            m_proxy.link = cast(typeof(m_proxy.link)) this;\n             this.__monitor = cast(void*) &m_proxy;\n         }\n \n@@ -434,15 +396,7 @@ class ReadWriteMutex\n         /// ditto\n         @trusted void lock() shared\n         {\n-            synchronized( m_commonMutex )\n-            {\n-                ++(cast()m_numQueuedWriters);\n-                scope(exit) --(cast()m_numQueuedWriters);\n-\n-                while ( shouldQueueWriter )\n-                    m_writerQueue.wait();\n-                ++(cast()m_numActiveWriters);\n-            }\n+            (cast() this).lock();\n         }\n \n \n@@ -477,27 +431,7 @@ class ReadWriteMutex\n         /// ditto\n         @trusted void unlock() shared\n         {\n-            synchronized( m_commonMutex )\n-            {\n-                if ( --(cast()m_numActiveWriters) < 1 )\n-                {\n-                    switch ( m_policy )\n-                    {\n-                    default:\n-                    case Policy.PREFER_READERS:\n-                        if ( m_numQueuedReaders > 0 )\n-                            m_readerQueue.notifyAll();\n-                        else if ( m_numQueuedWriters > 0 )\n-                            m_writerQueue.notify();\n-                        break;\n-                    case Policy.PREFER_WRITERS:\n-                        if ( m_numQueuedWriters > 0 )\n-                            m_writerQueue.notify();\n-                        else if ( m_numQueuedReaders > 0 )\n-                            m_readerQueue.notifyAll();\n-                    }\n-                }\n-            }\n+            (cast() this).unlock();\n         }\n \n \n@@ -523,13 +457,7 @@ class ReadWriteMutex\n         /// ditto\n         @trusted bool tryLock() shared\n         {\n-            synchronized( m_commonMutex )\n-            {\n-                if ( shouldQueueWriter )\n-                    return false;\n-                ++(cast()m_numActiveWriters);\n-                return true;\n-            }\n+            return (cast() this).tryLock();\n         }\n \n         /**\n@@ -580,25 +508,7 @@ class ReadWriteMutex\n         /// ditto\n         @trusted bool tryLock(Duration timeout) shared\n         {\n-            const initialTime = MonoTime.currTime;\n-            synchronized( m_commonMutex )\n-            {\n-                ++(cast()m_numQueuedWriters);\n-                scope(exit) --(cast()m_numQueuedWriters);\n-\n-                while (shouldQueueWriter)\n-                {\n-                    const timeElapsed = MonoTime.currTime - initialTime;\n-                    if (timeElapsed >= timeout)\n-                        return false;\n-                    auto nextWait = timeout - timeElapsed;\n-                    // Avoid problems calling wait(Duration) with huge arguments.\n-                    enum maxWaitPerCall = dur!\"hours\"(24 * 365);\n-                    m_writerQueue.wait(nextWait < maxWaitPerCall ? nextWait : maxWaitPerCall);\n-                }\n-                ++(cast()m_numActiveWriters);\n-                return true;\n-            }\n+            return (cast() this).tryLock(timeout);\n         }\n \n     private:\ndiff --git a/libphobos/libdruntime/core/sys/darwin/crt_externs.d b/libphobos/libdruntime/core/sys/darwin/crt_externs.d\nindex ec0788d7de4..a34db83c9d5 100644\n--- a/libphobos/libdruntime/core/sys/darwin/crt_externs.d\n+++ b/libphobos/libdruntime/core/sys/darwin/crt_externs.d\n@@ -8,7 +8,7 @@\n  */\n module core.sys.darwin.crt_externs;\n \n-version (CoreDoc)\n+version (CoreDdoc)\n {\n     /**\n      * In reality this will be $(REF mach_header, core, sys, darwin, mach, loader)\ndiff --git a/libphobos/libdruntime/core/sys/freebsd/config.d b/libphobos/libdruntime/core/sys/freebsd/config.d\nindex 932f166d2d0..144ef055372 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_16) enum __FreeBSD_version = 1600011;\n+     version (CoreDdoc)   enum __FreeBSD_version = 1600011; // keep at latest\n+else 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;\ndiff --git a/libphobos/libdruntime/core/sys/posix/aio.d b/libphobos/libdruntime/core/sys/posix/aio.d\nindex 3a537a4a575..674fab9fc99 100644\n--- a/libphobos/libdruntime/core/sys/posix/aio.d\n+++ b/libphobos/libdruntime/core/sys/posix/aio.d\n@@ -386,6 +386,18 @@ else version (OpenBSD)\n {\n     // OpenBSD does not implement aio.h\n }\n+else version (NetBSD)\n+{\n+    int aio_cancel(int fd, aiocb* aiocbp);\n+    int aio_error(const(aiocb)* aiocbp);\n+    int aio_fsync(int op, aiocb* aiocbp);\n+    int aio_read(aiocb* aiocbp);\n+    ssize_t aio_return(aiocb* aiocbp);\n+    pragma(mangle, \"__aio_suspend50\")\n+    int aio_suspend(const(aiocb*)* aiocb_list, int nitems, const(timespec)* timeout);\n+    int aio_write(aiocb* aiocbp);\n+    int lio_listio(int mode, const(aiocb*)* aiocb_list, int nitems, sigevent* sevp);\n+}\n else\n {\n     int aio_read(aiocb* aiocbp);\ndiff --git a/libphobos/libdruntime/core/sys/posix/dirent.d b/libphobos/libdruntime/core/sys/posix/dirent.d\nindex 18cee4c43cd..c77d6da22b2 100644\n--- a/libphobos/libdruntime/core/sys/posix/dirent.d\n+++ b/libphobos/libdruntime/core/sys/posix/dirent.d\n@@ -441,6 +441,26 @@ else\n     static assert(false, \"Unsupported platform\");\n }\n \n+//\n+// POSIX.1-2008\n+//\n+/*\n+int dirfd(DIR*);\n+*/\n+version (NetBSD)\n+{\n+    // On NetBSD, this is a macro in dirent.h, not a function.\n+    extern (D) int dirfd()(DIR* dir) nothrow @nogc\n+    {\n+        // ABI guarantees dd_fd remains the first field\n+        return *(cast(int*) dir);\n+    }\n+}\n+else\n+{\n+    nothrow @nogc int dirfd(DIR* dir);\n+}\n+\n // Only OS X out of the Darwin family needs special treatment.  Other Darwins\n // (iOS, TVOS, WatchOS) are fine with normal symbol names for these functions\n // in else below.\ndiff --git a/libphobos/libdruntime/core/sys/posix/locale.d b/libphobos/libdruntime/core/sys/posix/locale.d\nindex 0864f7c6325..821487afd29 100644\n--- a/libphobos/libdruntime/core/sys/posix/locale.d\n+++ b/libphobos/libdruntime/core/sys/posix/locale.d\n@@ -118,8 +118,17 @@ version (DarwinBSDLocale)\n     lconv*   localeconv();\n     /// Create a new locale\n     locale_t newlocale(int mask, const char* locale, locale_t base);\n-    /// Set the C library's notion of natural language formatting style\n-    char*    setlocale(int category, const char* locale);\n+    version (NetBSD)\n+    {\n+        /// Set the C library's notion of natural language formatting style\n+        pragma(mangle, \"__setlocale50\")\n+        char*    setlocale(int category, const char* locale);\n+    }\n+    else\n+    {\n+        /// Set the C library's notion of natural language formatting style\n+        char*    setlocale(int category, const char* locale);\n+    }\n     /// Set the per-thread locale\n     locale_t uselocale (locale_t locale);\n }\ndiff --git a/libphobos/libdruntime/core/sys/posix/netinet/in_.d b/libphobos/libdruntime/core/sys/posix/netinet/in_.d\nindex 09a4a5e07d1..75359ea213a 100644\n--- a/libphobos/libdruntime/core/sys/posix/netinet/in_.d\n+++ b/libphobos/libdruntime/core/sys/posix/netinet/in_.d\n@@ -547,7 +547,7 @@ version (CRuntime_Glibc)\n     }\n \n     // macros\n-    extern (D) int IN6_IS_ADDR_UNSPECIFIED()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_UNSPECIFIED()(const scope in6_addr* addr) pure\n     {\n         return (cast(uint32_t*) addr)[0] == 0 &&\n                (cast(uint32_t*) addr)[1] == 0 &&\n@@ -555,7 +555,7 @@ version (CRuntime_Glibc)\n                (cast(uint32_t*) addr)[3] == 0;\n     }\n \n-    extern (D) int IN6_IS_ADDR_LOOPBACK()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_LOOPBACK()(const scope in6_addr* addr) pure\n     {\n         return (cast(uint32_t*) addr)[0] == 0  &&\n                (cast(uint32_t*) addr)[1] == 0  &&\n@@ -563,29 +563,29 @@ version (CRuntime_Glibc)\n                (cast(uint32_t*) addr)[3] == htonl( 1 );\n     }\n \n-    extern (D) int IN6_IS_ADDR_MULTICAST()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_MULTICAST()(const scope in6_addr* addr) pure\n     {\n         return (cast(uint8_t*) addr)[0] == 0xff;\n     }\n \n-    extern (D) int IN6_IS_ADDR_LINKLOCAL()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_LINKLOCAL()(const scope in6_addr* addr) pure\n     {\n         return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfe800000 );\n     }\n \n-    extern (D) int IN6_IS_ADDR_SITELOCAL()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_SITELOCAL()(const scope in6_addr* addr) pure\n     {\n         return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfec00000 );\n     }\n \n-    extern (D) int IN6_IS_ADDR_V4MAPPED()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_V4MAPPED()(const scope in6_addr* addr) pure\n     {\n         return (cast(uint32_t*) addr)[0] == 0 &&\n                (cast(uint32_t*) addr)[1] == 0 &&\n                (cast(uint32_t*) addr)[2] == htonl( 0xffff );\n     }\n \n-    extern (D) int IN6_IS_ADDR_V4COMPAT()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_V4COMPAT()(const scope in6_addr* addr) pure\n     {\n         return (cast(uint32_t*) addr)[0] == 0 &&\n                (cast(uint32_t*) addr)[1] == 0 &&\n@@ -593,31 +593,31 @@ version (CRuntime_Glibc)\n                ntohl( (cast(uint32_t*) addr)[3] ) > 1;\n     }\n \n-    extern (D) int IN6_IS_ADDR_MC_NODELOCAL()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_MC_NODELOCAL()(const scope in6_addr* addr) pure\n     {\n         return IN6_IS_ADDR_MULTICAST( addr ) &&\n                ((cast(uint8_t*) addr)[1] & 0xf) == 0x1;\n     }\n \n-    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()(const scope in6_addr* addr) pure\n     {\n         return IN6_IS_ADDR_MULTICAST( addr ) &&\n                ((cast(uint8_t*) addr)[1] & 0xf) == 0x2;\n     }\n \n-    extern (D) int IN6_IS_ADDR_MC_SITELOCAL()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_MC_SITELOCAL()(const scope in6_addr* addr) pure\n     {\n         return IN6_IS_ADDR_MULTICAST(addr) &&\n                ((cast(uint8_t*) addr)[1] & 0xf) == 0x5;\n     }\n \n-    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()(const scope in6_addr* addr) pure\n     {\n         return IN6_IS_ADDR_MULTICAST( addr) &&\n                ((cast(uint8_t*) addr)[1] & 0xf) == 0x8;\n     }\n \n-    extern (D) int IN6_IS_ADDR_MC_GLOBAL()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_MC_GLOBAL()(const scope in6_addr* addr) pure\n     {\n         return IN6_IS_ADDR_MULTICAST( addr ) &&\n                ((cast(uint8_t*) addr)[1] & 0xf) == 0xe;\n@@ -670,7 +670,7 @@ else version (Darwin)\n     }\n \n     // macros\n-    extern (D) int IN6_IS_ADDR_UNSPECIFIED()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_UNSPECIFIED()(const scope in6_addr* addr) pure\n     {\n         return (cast(uint32_t*) addr)[0] == 0 &&\n                (cast(uint32_t*) addr)[1] == 0 &&\n@@ -678,7 +678,7 @@ else version (Darwin)\n                (cast(uint32_t*) addr)[3] == 0;\n     }\n \n-    extern (D) int IN6_IS_ADDR_LOOPBACK()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_LOOPBACK()(const scope in6_addr* addr) pure\n     {\n         return (cast(uint32_t*) addr)[0] == 0  &&\n                (cast(uint32_t*) addr)[1] == 0  &&\n@@ -686,29 +686,29 @@ else version (Darwin)\n                (cast(uint32_t*) addr)[3] == ntohl( 1 );\n     }\n \n-    extern (D) int IN6_IS_ADDR_MULTICAST()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_MULTICAST()(const scope in6_addr* addr) pure\n     {\n         return addr.s6_addr[0] == 0xff;\n     }\n \n-    extern (D) int IN6_IS_ADDR_LINKLOCAL()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_LINKLOCAL()(const scope in6_addr* addr) pure\n     {\n         return addr.s6_addr[0] == 0xfe && (addr.s6_addr[1] & 0xc0) == 0x80;\n     }\n \n-    extern (D) int IN6_IS_ADDR_SITELOCAL()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_SITELOCAL()(const scope in6_addr* addr) pure\n     {\n         return addr.s6_addr[0] == 0xfe && (addr.s6_addr[1] & 0xc0) == 0xc0;\n     }\n \n-    extern (D) int IN6_IS_ADDR_V4MAPPED()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_V4MAPPED()(const scope in6_addr* addr) pure\n     {\n         return (cast(uint32_t*) addr)[0] == 0 &&\n                (cast(uint32_t*) addr)[1] == 0 &&\n                (cast(uint32_t*) addr)[2] == ntohl( 0x0000ffff );\n     }\n \n-    extern (D) int IN6_IS_ADDR_V4COMPAT()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_V4COMPAT()(const scope in6_addr* addr) pure\n     {\n         return (cast(uint32_t*) addr)[0] == 0 &&\n                (cast(uint32_t*) addr)[1] == 0 &&\n@@ -717,31 +717,31 @@ else version (Darwin)\n                (cast(uint32_t*) addr)[3] != ntohl( 1 );\n     }\n \n-    extern (D) int IN6_IS_ADDR_MC_NODELOCAL()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_MC_NODELOCAL()(const scope in6_addr* addr) pure\n     {\n         return IN6_IS_ADDR_MULTICAST( addr ) &&\n                ((cast(uint8_t*) addr)[1] & 0xf) == 0x1;\n     }\n \n-    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()(const scope in6_addr* addr) pure\n     {\n         return IN6_IS_ADDR_MULTICAST( addr ) &&\n                ((cast(uint8_t*) addr)[1] & 0xf) == 0x2;\n     }\n \n-    extern (D) int IN6_IS_ADDR_MC_SITELOCAL()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_MC_SITELOCAL()(const scope in6_addr* addr) pure\n     {\n         return IN6_IS_ADDR_MULTICAST(addr) &&\n                ((cast(uint8_t*) addr)[1] & 0xf) == 0x5;\n     }\n \n-    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()(const scope in6_addr* addr) pure\n     {\n         return IN6_IS_ADDR_MULTICAST( addr) &&\n                ((cast(uint8_t*) addr)[1] & 0xf) == 0x8;\n     }\n \n-    extern (D) int IN6_IS_ADDR_MC_GLOBAL()(const scope in6_addr* add) pure\n+    extern (D) int IN6_IS_ADDR_MC_GLOBAL()(const scope in6_addr* addr) pure\n     {\n         return IN6_IS_ADDR_MULTICAST( addr ) &&\n                ((cast(uint8_t*) addr)[1] & 0xf) == 0xe;\ndiff --git a/libphobos/libdruntime/core/sys/posix/pwd.d b/libphobos/libdruntime/core/sys/posix/pwd.d\nindex d4b4a07673a..3402a9e263a 100644\n--- a/libphobos/libdruntime/core/sys/posix/pwd.d\n+++ b/libphobos/libdruntime/core/sys/posix/pwd.d\n@@ -201,8 +201,16 @@ else\n     static assert(false, \"Unsupported platform\");\n }\n \n-passwd* getpwnam(const scope char*);\n-passwd* getpwuid(uid_t);\n+version (NetBSD)\n+{\n+    pragma(mangle, \"__getpwnam50\") passwd* getpwnam(const scope char*);\n+    pragma(mangle, \"__getpwuid50\") passwd* getpwuid(uid_t);\n+}\n+else\n+{\n+    passwd* getpwnam(const scope char*);\n+    passwd* getpwuid(uid_t);\n+}\n \n //\n // Thread-Safe Functions (TSF)\n@@ -301,7 +309,7 @@ else version (FreeBSD)\n else version (NetBSD)\n {\n     void    endpwent();\n-    passwd* getpwent();\n+    pragma(mangle, \"__getpwent50\") passwd* getpwent();\n     void    setpwent();\n }\n else version (OpenBSD)\ndiff --git a/libphobos/libdruntime/core/sys/posix/sched.d b/libphobos/libdruntime/core/sys/posix/sched.d\nindex d5798358415..273be5e8191 100644\n--- a/libphobos/libdruntime/core/sys/posix/sched.d\n+++ b/libphobos/libdruntime/core/sys/posix/sched.d\n@@ -262,6 +262,7 @@ else version (NetBSD)\n {\n     int sched_get_priority_min(int);\n     int sched_get_priority_max(int);\n+    pragma(mangle, \"__sched_rr_get_interval50\")\n     int sched_rr_get_interval(pid_t, timespec*);\n }\n else version (OpenBSD)\ndiff --git a/libphobos/libdruntime/core/sys/posix/setjmp.d b/libphobos/libdruntime/core/sys/posix/setjmp.d\nindex 24497a27ae2..d1fcb1947c2 100644\n--- a/libphobos/libdruntime/core/sys/posix/setjmp.d\n+++ b/libphobos/libdruntime/core/sys/posix/setjmp.d\n@@ -257,8 +257,8 @@ else version (NetBSD)\n         static assert(0);\n     alias jmp_buf = _jmp_buf[_JBLEN];\n \n-    int  setjmp(ref jmp_buf);\n-    void longjmp(ref jmp_buf, int);\n+    pragma(mangle, \"__setjmp14\")  int  setjmp(ref jmp_buf);\n+    pragma(mangle, \"__longjmp14\") void longjmp(ref jmp_buf, int);\n }\n else version (OpenBSD)\n {\n@@ -486,8 +486,8 @@ else version (NetBSD)\n         static assert(0);\n     alias sigjmp_buf = _sigjmp_buf[_JBLEN + 1];\n \n-    int  sigsetjmp(ref sigjmp_buf);\n-    void siglongjmp(ref sigjmp_buf, int);\n+    pragma(mangle, \"__sigsetjmp14\")  int  sigsetjmp(ref sigjmp_buf);\n+    pragma(mangle, \"__siglongjmp14\") void siglongjmp(ref sigjmp_buf, int);\n }\n else version (OpenBSD)\n {\ndiff --git a/libphobos/libdruntime/core/sys/posix/signal.d b/libphobos/libdruntime/core/sys/posix/signal.d\nindex 73da7607c57..94ddd0403da 100644\n--- a/libphobos/libdruntime/core/sys/posix/signal.d\n+++ b/libphobos/libdruntime/core/sys/posix/signal.d\n@@ -3019,6 +3019,7 @@ else version (FreeBSD)\n else version (NetBSD)\n {\n     int sigqueue(pid_t, int, const sigval);\n+    pragma(mangle, \"__sigtimedwait50\")\n     int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*);\n     int sigwaitinfo(const scope sigset_t*, siginfo_t*);\n }\ndiff --git a/libphobos/libdruntime/core/sys/posix/stdc/time.d b/libphobos/libdruntime/core/sys/posix/stdc/time.d\nindex dee81ecc342..abeb715ad73 100644\n--- a/libphobos/libdruntime/core/sys/posix/stdc/time.d\n+++ b/libphobos/libdruntime/core/sys/posix/stdc/time.d\n@@ -146,6 +146,7 @@ else version (FreeBSD)\n else version (NetBSD)\n {\n     ///\n+    pragma(mangle, \"__tzset50\")\n     void tzset();                            // non-standard\n     ///\n     extern __gshared const(char)*[2] tzname; // non-standard\ndiff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d\nindex 8e8c16fab53..3a6a5d2407d 100644\n--- a/libphobos/libdruntime/core/sys/posix/stdlib.d\n+++ b/libphobos/libdruntime/core/sys/posix/stdlib.d\n@@ -459,14 +459,14 @@ else version (NetBSD)\n     c_long nrand48(ref ushort[3]);\n     int    posix_openpt(int);\n     char*  ptsname(int);\n-    int    putenv(char*);\n+    pragma(mangle, \"__putenv50\") int    putenv(char*);\n     c_long random();\n     char*  realpath(const scope char*, char*);\n     ushort *seed48(ref ushort[3]);\n     void   setkey(const scope char*);\n     char*  setstate(const scope char*);\n     void   srand48(c_long);\n-    void   srandom(uint);\n+    pragma(mangle, \"__srandom60\") void   srandom(uint);\n     int    unlockpt(int);\n }\n else version (OpenBSD)\ndiff --git a/libphobos/libdruntime/core/sys/posix/sys/msg.d b/libphobos/libdruntime/core/sys/posix/sys/msg.d\nindex 19e07bd6468..519811820f6 100644\n--- a/libphobos/libdruntime/core/sys/posix/sys/msg.d\n+++ b/libphobos/libdruntime/core/sys/posix/sys/msg.d\n@@ -200,7 +200,10 @@ struct msgbuf\n     char[1] mtext = 0;\n }\n \n-int msgctl(int msqid, int cmd, msqid_ds* __buf);\n+version (NetBSD)\n+    pragma(mangle, \"__msgctl50\") int msgctl(int msqid, int cmd, msqid_ds* __buf);\n+else\n+    int msgctl(int msqid, int cmd, msqid_ds* __buf);\n int msgget(key_t key, int msgflg);\n ssize_t msgrcv(int msqid, void* msgp, size_t msgsz, c_long msgtyp, int msgflg);\n int msgsnd(int msqid, msgbuf* msgp, int msgsz, int msgflg);\ndiff --git a/libphobos/libdruntime/core/sys/posix/sys/resource.d b/libphobos/libdruntime/core/sys/posix/sys/resource.d\nindex 3da8411d6af..eb62e4950fd 100644\n--- a/libphobos/libdruntime/core/sys/posix/sys/resource.d\n+++ b/libphobos/libdruntime/core/sys/posix/sys/resource.d\n@@ -530,7 +530,7 @@ else version (NetBSD)\n {\n     int getpriority(int, int);\n     int getrlimit(int, rlimit*);\n-    int getrusage(int, rusage*);\n+    pragma(mangle, \"__getrusage50\") int getrusage(int, rusage*);\n     int setpriority(int, int, int);\n     int setrlimit(int, const scope rlimit*);\n }\ndiff --git a/libphobos/libdruntime/core/sys/posix/sys/select.d b/libphobos/libdruntime/core/sys/posix/sys/select.d\nindex 064dfbcc5f8..5152d0fe17d 100644\n--- a/libphobos/libdruntime/core/sys/posix/sys/select.d\n+++ b/libphobos/libdruntime/core/sys/posix/sys/select.d\n@@ -268,7 +268,9 @@ else version (NetBSD)\n             _p.fds_bits[--_n] = 0;\n     }\n \n+    pragma(mangle, \"__pselect50\")\n     int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);\n+    pragma(mangle, \"__select50\")\n     int select(int, fd_set*, fd_set*, fd_set*, timeval*);\n }\n else version (OpenBSD)\ndiff --git a/libphobos/libdruntime/core/sys/posix/sys/shm.d b/libphobos/libdruntime/core/sys/posix/sys/shm.d\nindex 927778dd2a6..358fcf9e322 100644\n--- a/libphobos/libdruntime/core/sys/posix/sys/shm.d\n+++ b/libphobos/libdruntime/core/sys/posix/sys/shm.d\n@@ -219,7 +219,7 @@ else version (NetBSD)\n     enum SHMLBA = 1 << 12; // PAGE_SIZE = (1<<PAGE_SHIFT)\n \n     void* shmat(int, const scope void*, int);\n-    int   shmctl(int, int, shmid_ds*);\n+    pragma(mangle, \"__shmctl50\") int   shmctl(int, int, shmid_ds*);\n     int   shmdt(const scope void*);\n     int   shmget(key_t, size_t, int);\n }\ndiff --git a/libphobos/libdruntime/core/sys/posix/sys/socket.d b/libphobos/libdruntime/core/sys/posix/sys/socket.d\nindex 35f316bd935..0ae101db098 100644\n--- a/libphobos/libdruntime/core/sys/posix/sys/socket.d\n+++ b/libphobos/libdruntime/core/sys/posix/sys/socket.d\n@@ -1704,7 +1704,7 @@ else version (NetBSD)\n     ssize_t sendto(int, const scope void*, size_t, int, const scope sockaddr*, socklen_t);\n     int     setsockopt(int, int, int, const scope void*, socklen_t);\n     int     shutdown(int, int) @safe;\n-    int     socket(int, int, int) @safe;\n+    pragma(mangle, \"__socket30\") int     socket(int, int, int) @safe;\n     int     sockatmark(int) @safe;\n     int     socketpair(int, int, int, ref int[2]) @safe;\n }\ndiff --git a/libphobos/libdruntime/core/sys/posix/sys/stat.d b/libphobos/libdruntime/core/sys/posix/sys/stat.d\nindex ad59019e181..a14fc149d70 100644\n--- a/libphobos/libdruntime/core/sys/posix/sys/stat.d\n+++ b/libphobos/libdruntime/core/sys/posix/sys/stat.d\n@@ -2010,12 +2010,14 @@ else version (Darwin)\n         version (AArch64)\n         {\n             int fstat(int, stat_t*);\n+            int fstatat(int, const scope char*, stat_t*, int);\n             int lstat(const scope char*, stat_t*);\n             int stat(const scope char*, stat_t*);\n         }\n         else\n         {\n             pragma(mangle, \"fstat$INODE64\") int fstat(int, stat_t*);\n+            pragma(mangle, \"fstatat$INODE64\") int fstatat(int, const scope char*, stat_t*, int);\n             pragma(mangle, \"lstat$INODE64\") int lstat(const scope char*, stat_t*);\n             pragma(mangle, \"stat$INODE64\")  int stat(const scope char*, stat_t*);\n         }\n@@ -2023,11 +2025,11 @@ else version (Darwin)\n     else\n     {\n         int fstat(int, stat_t*);\n+        int fstatat(int, const scope char*, stat_t*, int);\n         int lstat(const scope char*, stat_t*);\n         int stat(const scope char*, stat_t*);\n     }\n     int   fchmodat(int, const scope char*, mode_t, int);\n-    int   fstatat(int, const scope char*, stat_t*, int);\n     int   futimens(int, ref const(timespec)[2]);\n     int   mkdirat(int, const scope char*, mode_t);\n     int   mkfifoat(int, const scope char*, mode_t);\n@@ -2352,7 +2354,7 @@ else version (FreeBSD)\n }\n else version (NetBSD)\n {\n-    int mknod(const scope char*, mode_t, dev_t);\n+    pragma(mangle, \"__mknod50\") int mknod(const scope char*, mode_t, dev_t);\n     int mknodat(int, const scope char*, mode_t, dev_t);\n }\n else version (OpenBSD)\ndiff --git a/libphobos/libdruntime/core/sys/posix/sys/statvfs.d b/libphobos/libdruntime/core/sys/posix/sys/statvfs.d\nindex dec253d3005..a8f3dd50654 100644\n--- a/libphobos/libdruntime/core/sys/posix/sys/statvfs.d\n+++ b/libphobos/libdruntime/core/sys/posix/sys/statvfs.d\n@@ -180,7 +180,9 @@ else version (NetBSD)\n         ST_NOSUID = 2\n     }\n \n+    pragma(mangle, \"__statvfs90\")\n     int statvfs (const char * file, statvfs_t* buf);\n+    pragma(mangle, \"__fstatvfs90\")\n     int fstatvfs (int fildes, statvfs_t *buf) @trusted;\n }\n else version (OpenBSD)\ndiff --git a/libphobos/libdruntime/core/sys/posix/sys/time.d b/libphobos/libdruntime/core/sys/posix/sys/time.d\nindex dda4caf0bf3..6dcd4878d19 100644\n--- a/libphobos/libdruntime/core/sys/posix/sys/time.d\n+++ b/libphobos/libdruntime/core/sys/posix/sys/time.d\n@@ -160,9 +160,13 @@ else version (NetBSD)\n         timeval it_value;\n     }\n \n+    pragma(mangle, \"__getitimer50\")\n     int getitimer(int, itimerval*);\n+    pragma(mangle, \"__gettimeofday50\")\n     int gettimeofday(timeval*, void*); // timezone_t* is normally void*\n+    pragma(mangle, \"__setitimer50\")\n     int setitimer(int, const scope itimerval*, itimerval*);\n+    pragma(mangle, \"__utimes50\")\n     int utimes(const scope char*, ref const(timeval)[2]);\n }\n else version (OpenBSD)\ndiff --git a/libphobos/libdruntime/core/sys/posix/sys/types.d b/libphobos/libdruntime/core/sys/posix/sys/types.d\nindex b6febde7136..cad60b4da4d 100644\n--- a/libphobos/libdruntime/core/sys/posix/sys/types.d\n+++ b/libphobos/libdruntime/core/sys/posix/sys/types.d\n@@ -251,7 +251,7 @@ else version (NetBSD)\n     alias pid_t = int;\n     //size_t (defined in core.stdc.stddef)\n     alias ssize_t = c_long;\n-    alias time_t = c_long;\n+    alias time_t = long; // _BSD_TIME_T_ mapped to __int64_t\n     alias uid_t = uint;\n }\n else version (OpenBSD)\n@@ -388,10 +388,10 @@ else version (NetBSD)\n {\n     alias fsblkcnt_t = ulong;\n     alias fsfilcnt_t = ulong;\n-    alias clock_t = c_long;\n+    alias clock_t = uint; // unsigned int\n     alias id_t = long;\n     alias key_t = c_long;\n-    alias suseconds_t = c_long;\n+    alias suseconds_t = int; // int\n     alias useconds_t = uint;\n }\n else version (OpenBSD)\ndiff --git a/libphobos/libdruntime/core/sys/posix/time.d b/libphobos/libdruntime/core/sys/posix/time.d\nindex a631ddc2bcb..4fc73aab8c5 100644\n--- a/libphobos/libdruntime/core/sys/posix/time.d\n+++ b/libphobos/libdruntime/core/sys/posix/time.d\n@@ -64,6 +64,7 @@ else version (FreeBSD)\n }\n else version (NetBSD)\n {\n+    pragma(mangle, \"__timegm50\")\n     time_t timegm(tm*); // non-standard\n }\n else version (OpenBSD)\n@@ -378,14 +379,20 @@ else version (NetBSD)\n     alias clockid_t = int; // <sys/_types.h>\n     alias timer_t = int;\n \n+    pragma(mangle, \"__clock_getres50\")\n     int clock_getres(clockid_t, timespec*);\n+    pragma(mangle, \"__clock_gettime50\")\n     int clock_gettime(clockid_t, timespec*);\n+    pragma(mangle, \"__clock_settime50\")\n     int clock_settime(clockid_t, const scope timespec*);\n+    pragma(mangle, \"__nanosleep50\")\n     int nanosleep(const scope timespec*, timespec*);\n     int timer_create(clockid_t, sigevent*, timer_t*);\n     int timer_delete(timer_t);\n+    pragma(mangle, \"__timer_gettime50\")\n     int timer_gettime(timer_t, itimerspec*);\n     int timer_getoverrun(timer_t);\n+    pragma(mangle, \"__timer_settime50\")\n     int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);\n }\n else version (OpenBSD)\n@@ -576,8 +583,11 @@ else version (FreeBSD)\n else version (NetBSD)\n {\n     char* asctime_r(const scope tm*, char*);\n+    pragma(mangle, \"__ctime_r50\")\n     char* ctime_r(const scope time_t*, char*);\n+    pragma(mangle, \"__gmtime_r50\")\n     tm*   gmtime_r(const scope time_t*, tm*);\n+    pragma(mangle, \"__localtime_r50\")\n     tm*   localtime_r(const scope time_t*, tm*);\n }\n else version (OpenBSD)\ndiff --git a/libphobos/libdruntime/core/sys/posix/unistd.d b/libphobos/libdruntime/core/sys/posix/unistd.d\nindex 71d501be8c2..ea6d866999c 100644\n--- a/libphobos/libdruntime/core/sys/posix/unistd.d\n+++ b/libphobos/libdruntime/core/sys/posix/unistd.d\n@@ -188,6 +188,8 @@ else version (NetBSD)\n {\n     off_t lseek(int, off_t, int) @trusted;\n     int   ftruncate(int, off_t) @trusted;\n+    // NetBSD 10.0\n+    pragma(mangle, \"__dup3100\") int   dup3(int, int, int) @trusted;\n     int   faccessat(int, const scope char*, int, int);\n     int   fchownat(int, const scope char*, uid_t, gid_t, int);\n     int   fexecve(int, const scope char**, const scope char**);\n@@ -671,7 +673,21 @@ version (CRuntime_Glibc)\n         _SC_LEVEL4_CACHE_LINESIZE,\n \n         _SC_IPV6 = _SC_LEVEL1_ICACHE_SIZE + 50,\n-        _SC_RAW_SOCKETS\n+        _SC_RAW_SOCKETS,\n+        _SC_V7_ILP32_OFF32,\n+        _SC_V7_ILP32_OFFBIG,\n+        _SC_V7_LP64_OFF64,\n+        _SC_V7_LPBIG_OFFBIG,\n+        _SC_SS_REPL_MAX,\n+        _SC_TRACE_EVENT_NAME_MAX,\n+        _SC_TRACE_NAME_MAX,\n+        _SC_TRACE_SYS_MAX,\n+        _SC_TRACE_USER_EVENT_MAX,\n+        _SC_XOPEN_STREAMS,\n+        _SC_THREAD_ROBUST_PRIO_INHERIT,\n+        _SC_THREAD_ROBUST_PRIO_PROTECT,\n+        _SC_MINSIGSTKSZ,\n+        _SC_SIGSTKSZ,\n     }\n }\n else version (Darwin)\n@@ -2702,7 +2718,7 @@ else version (NetBSD)\n     int        truncate(const scope char*, off_t);\n     useconds_t ualarm(useconds_t, useconds_t) @trusted;\n     int        usleep(useconds_t) @trusted;\n-    pid_t      vfork();\n+    pragma(mangle, \"__vfork14\") pid_t      vfork();\n }\n else version (OpenBSD)\n {\ndiff --git a/libphobos/libdruntime/core/sys/posix/utime.d b/libphobos/libdruntime/core/sys/posix/utime.d\nindex e7059d71283..16a26b23d95 100644\n--- a/libphobos/libdruntime/core/sys/posix/utime.d\n+++ b/libphobos/libdruntime/core/sys/posix/utime.d\n@@ -93,7 +93,7 @@ else version (NetBSD)\n         time_t  modtime;\n     }\n \n-    int utime(const scope char*, const scope utimbuf*);\n+    pragma(mangle, \"__utime50\") int utime(const scope char*, const scope utimbuf*);\n }\n else version (OpenBSD)\n {\ndiff --git a/libphobos/libdruntime/core/sys/windows/winuser.d b/libphobos/libdruntime/core/sys/windows/winuser.d\nindex dddaeb0535a..9d8c26440ed 100644\n--- a/libphobos/libdruntime/core/sys/windows/winuser.d\n+++ b/libphobos/libdruntime/core/sys/windows/winuser.d\n@@ -3720,8 +3720,8 @@ nothrow @nogc {\n alias GetNextWindow = GetWindow;\n \n extern (Windows) nothrow @nogc:\n-LONG DispatchMessageA(const(MSG)*);\n-LONG DispatchMessageW(const(MSG)*);\n+LRESULT DispatchMessageA(const(MSG)*);\n+LRESULT DispatchMessageW(const(MSG)*);\n int DlgDirListA(HWND, LPSTR, int, int, UINT);\n int DlgDirListW(HWND, LPWSTR, int, int, UINT);\n int DlgDirListComboBoxA(HWND, LPSTR, int, int, UINT);\n@@ -4034,8 +4034,8 @@ BOOL ScreenToClient(HWND, LPPOINT);\n BOOL ScrollDC(HDC, int, int, LPCRECT, LPCRECT, HRGN, LPRECT);\n BOOL ScrollWindow(HWND, int, int, LPCRECT, LPCRECT);\n int ScrollWindowEx(HWND, int, int, LPCRECT, LPCRECT, HRGN, LPRECT, UINT);\n-LONG SendDlgItemMessageA(HWND, int, UINT, WPARAM, LPARAM);\n-LONG SendDlgItemMessageW(HWND, int, UINT, WPARAM, LPARAM);\n+LRESULT SendDlgItemMessageA(HWND, int, UINT, WPARAM, LPARAM);\n+LRESULT SendDlgItemMessageW(HWND, int, UINT, WPARAM, LPARAM);\n LRESULT SendMessageA(HWND, UINT, WPARAM, LPARAM);\n BOOL SendMessageCallbackA(HWND, UINT, WPARAM, LPARAM, SENDASYNCPROC, ULONG_PTR);\n BOOL SendMessageCallbackW(HWND, UINT, WPARAM, LPARAM, SENDASYNCPROC, ULONG_PTR);\ndiff --git a/libphobos/libdruntime/core/thread/context.d b/libphobos/libdruntime/core/thread/context.d\nindex e477269b849..81b7478a6d8 100644\n--- a/libphobos/libdruntime/core/thread/context.d\n+++ b/libphobos/libdruntime/core/thread/context.d\n@@ -11,6 +11,7 @@\n \n module core.thread.context;\n \n+///\n struct StackContext\n {\n     void* bstack, tstack;\ndiff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d\nindex 6827dad6199..d2e6060a286 100644\n--- a/libphobos/libdruntime/core/thread/osthread.d\n+++ b/libphobos/libdruntime/core/thread/osthread.d\n@@ -653,7 +653,9 @@ class Thread : ThreadBase\n             auto local = atomicLoad(mixin(\"cache.\" ~ which));\n             if (local != local.min) return local;\n             // There will be benign races\n-            cache = loadPriorities;\n+            auto loaded = loadPriorities;\n+            static foreach (i, _; loaded.tupleof)\n+                atomicStore(cache.tupleof[i], loaded.tupleof[i]);\n             return atomicLoad(mixin(\"cache.\" ~ which));\n         }\n \n@@ -1527,6 +1529,27 @@ in (fn)\n             mov sp[RBP], RSP;\n         }\n     }\n+    else version (AArch64)\n+    {\n+\t// Callee-save registers, x19-x28 according to AAPCS64, section\n+\t// 5.1.1.  Include x29 fp because it optionally can be a callee\n+\t// saved reg\n+\tsize_t[11] regs = void;\n+\t// store the registers in pairs\n+\tasm pure nothrow @nogc\n+\t{\n+\t/*\n+\t    stp x19, x20, regs[0];\n+\t    stp x21, x22, regs[2];\n+\t    stp x23, x24, regs[4];\n+\t    stp x25, x26, regs[6];\n+\t    stp x27, x28, regs[8];\n+\t    str x29, regs[10];\n+\t    mov [sp], sp;\n+\t */\n+\t}\n+\tassert(0, \"implement AArch64 inline assembler for callWithStackShell()\"); // TODO AArch64\n+    }\n     else\n     {\n         static assert(false, \"Architecture not supported.\");\n@@ -1576,6 +1599,11 @@ private extern(D) void* getStackTop() nothrow @nogc\n         asm pure nothrow @nogc { naked; mov EAX, ESP; ret; }\n     else version (D_InlineAsm_X86_64)\n         asm pure nothrow @nogc { naked; mov RAX, RSP; ret; }\n+    else version (AArch64)\n+        //asm pure nothrow @nogc { naked; mov x0, SP; ret; }    // TODO AArch64\n+    {\n+        return null;\n+    }\n     else version (GNU)\n         return __builtin_frame_address(0);\n     else\ndiff --git a/libphobos/libdruntime/core/thread/package.d b/libphobos/libdruntime/core/thread/package.d\nindex d81ebbdcc82..a54442b3f13 100644\n--- a/libphobos/libdruntime/core/thread/package.d\n+++ b/libphobos/libdruntime/core/thread/package.d\n@@ -22,38 +22,36 @@ public import core.thread.context;\n \n // this test is here to avoid a cyclic dependency between\n // core.thread and core.atomic\n-unittest\n+@system unittest\n {\n     import core.atomic;\n \n-    // Use heap memory to ensure an optimizing\n-    // compiler doesn't put things in registers.\n-    uint* x = new uint();\n-    bool* f = new bool();\n-    uint* r = new uint();\n+    shared uint x;\n+    shared bool f;\n+    shared uint r;\n \n     auto thr = new Thread(()\n     {\n-        while (!*f)\n+        while (!atomicLoad(f))\n         {\n         }\n \n-        atomicFence();\n+        atomicFence(); // make sure load+store below happens after waiting for f\n \n-        *r = *x;\n+        cast() r = cast() x;\n     });\n \n-    thr.start();\n+    thr.start(); // new thread will wait until f is set\n \n-    *x = 42;\n+    cast() x = 42;\n \n-    atomicFence();\n+    atomicFence(); // make sure x is set before setting f\n \n-    *f = true;\n+    cast() f = true;\n \n     atomicFence();\n \n     thr.join();\n \n-    assert(*r == 42);\n+    assert(cast() r == 42);\n }\ndiff --git a/libphobos/libdruntime/core/thread/types.d b/libphobos/libdruntime/core/thread/types.d\nindex c816010e5ce..e630c39668e 100644\n--- a/libphobos/libdruntime/core/thread/types.d\n+++ b/libphobos/libdruntime/core/thread/types.d\n@@ -42,12 +42,21 @@ version (GNU)\n     else\n         enum isStackGrowingDown = false;\n }\n-else\n+else version (LDC)\n+{\n+    // The only LLVM targets as of LLVM 16 with stack growing *upwards* are\n+    // apparently NVPTX and AMDGPU, both without druntime support.\n+    // Note that there's an analogous `version = StackGrowsDown` in\n+    // core.thread.fiber.\n+    enum isStackGrowingDown = true;\n+}\n+else version (DigitalMars)\n {\n-    version (X86) enum isStackGrowingDown = true;\n-    else version (X86_64) enum isStackGrowingDown = true;\n-    else static assert(0, \"It is undefined how the stack grows on this architecture.\");\n+    // All dmd targets grow down\n+    enum isStackGrowingDown = true;\n }\n+else\n+    static assert(0, \"It is undefined how the stack grows on this architecture.\");\n \n package\n {\ndiff --git a/libphobos/libdruntime/etc/valgrind/valgrind.d b/libphobos/libdruntime/etc/valgrind/valgrind.d\nindex 21829fc23bf..3b70e75be0e 100644\n--- a/libphobos/libdruntime/etc/valgrind/valgrind.d\n+++ b/libphobos/libdruntime/etc/valgrind/valgrind.d\n@@ -3,7 +3,7 @@\n /// and compile with `-debug=VALGRIND` to access the declarations below.\n module etc.valgrind.valgrind;\n \n-version (StdDdoc)\n+version (CoreDdoc)\n {\n     /// Mark the memory covered by `mem` as unaddressable.\n     void makeMemNoAccess (const(void)[] mem) nothrow @nogc;\ndiff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d\nindex bb0c3d3c273..e6c6db6e5ba 100644\n--- a/libphobos/libdruntime/object.d\n+++ b/libphobos/libdruntime/object.d\n@@ -518,11 +518,15 @@ unittest\n // https://issues.dlang.org/show_bug.cgi?id=23291\n @system unittest\n {\n+    import core.atomic : atomicLoad;\n+\n     static shared class C { bool opEquals(const(shared(C)) rhs) const shared  { return true;}}\n     const(C) c = new C();\n     const(C)[] a = [c];\n     const(C)[] b = [c];\n-    assert(a[0] == b[0]);\n+    // Call the shared-aware overload directly to avoid `==` introducing\n+    // additional shared reads during lowering.\n+    assert(atomicLoad(a[0]).opEquals(atomicLoad(b[0])));\n }\n \n private extern(C) void _d_setSameMutex(shared Object ownee, shared Object owner) nothrow;\n@@ -541,6 +545,8 @@ void setSameMutex(shared Object ownee, shared Object owner)\n \n @system unittest\n {\n+    import core.atomic : atomicLoad;\n+\n     shared Object obj1 = new Object;\n     synchronized class C\n     {\n@@ -552,7 +558,7 @@ void setSameMutex(shared Object ownee, shared Object owner)\n     assert(obj1.__monitor != obj2.__monitor);\n     assert(obj1.__monitor is null);\n \n-    setSameMutex(obj1, obj2);\n+    setSameMutex(atomicLoad(obj1), atomicLoad(obj2));\n     assert(obj1.__monitor == obj2.__monitor);\n     assert(obj1.__monitor !is null);\n }\n@@ -2986,16 +2992,30 @@ alias AssociativeArray(Key, Value) = Value[Key];\n  *      aa =     The associative array.\n  */\n void clear(Value, Key)(Value[Key] aa) @trusted\n+if (!is(Value == shared))\n {\n     _aaClear(aa);\n }\n \n /** ditto */\n void clear(Value, Key)(Value[Key]* aa) @trusted\n+if (!is(Value == shared))\n {\n     (*aa).clear();\n }\n \n+/** ditto */\n+void clear(Value, Key)(shared(Value)[Key] aa)\n+{\n+    return (cast(Value[Key])aa).clear();\n+}\n+\n+/** ditto */\n+void clear(Value, Key)(shared(Value)[Key]* aa)\n+{\n+    (cast(Value[Key])*aa).clear();\n+}\n+\n ///\n @safe unittest\n {\n@@ -3066,11 +3086,23 @@ Value[Key] rehash(T : shared Value[Key], Value, Key)(T* aa)\n  */\n auto dup(T : V[K], K, V)(T aa)\n {\n+    import core.internal.traits : substInout, Unconst;\n+\n     // Bug10720 - check whether V is copyable\n-    static assert(is(typeof({ V v = aa[K.init]; })),\n-        \"cannot call \" ~ T.stringof ~ \".dup because \" ~ V.stringof ~ \" is not copyable\");\n+    static if (is(typeof({ Unconst!V v = aa[K.init]; })))\n+        alias Vret = Unconst!V;\n+    else static if (is(typeof({ V v = aa[K.init]; })))\n+        alias Vret = V;\n+    else\n+        static assert(false, \"cannot call \" ~ T.stringof ~ \".dup because \" ~ V.stringof ~ \" is not copyable\");\n+    alias Kret = typeof([K.init][0]); // strip const if possible by copy\n+\n+    alias K1 = substInout!K;\n+    alias V1 = substInout!Vret;\n \n-    return _aaDup(aa);\n+    auto naa = _aaDup((() @trusted => cast(V1[K1])aa)());\n+    auto maa = ((inout T) @trusted => cast(Vret[Kret])naa)(aa);\n+    return maa;\n }\n \n /** ditto */\ndiff --git a/libphobos/libdruntime/rt/critical_.d b/libphobos/libdruntime/rt/critical_.d\nindex 36552a3ce1a..8513c67037b 100644\n--- a/libphobos/libdruntime/rt/critical_.d\n+++ b/libphobos/libdruntime/rt/critical_.d\n@@ -21,14 +21,14 @@ import rt.monitor_, core.atomic;\n extern (C) void _d_critical_init() @nogc nothrow\n {\n     initMutex(cast(Mutex*)&gcs.mtx);\n-    head = &gcs;\n+    atomicStore(head, &gcs);\n }\n \n extern (C) void _d_critical_term() @nogc nothrow\n {\n     // This function is only ever called by the runtime shutdown code\n     // and therefore is single threaded so the following cast is fine.\n-    auto h = cast()head;\n+    auto h = cast(D_CRITICAL_SECTION*) atomicLoad(head);\n     for (auto p = h; p; p = p.next)\n         destroyMutex(cast(Mutex*)&p.mtx);\n }\n@@ -81,8 +81,8 @@ void ensureMutex(shared(D_CRITICAL_SECTION)* cs)\n         if (atomicLoad!(MemoryOrder.raw)(cs.next) is null)\n         {\n             initMutex(cast(Mutex*)&cs.mtx);\n-            auto ohead = head;\n-            head = cs;\n+            auto ohead = atomicLoad(head);\n+            atomicStore(head, cs);\n             atomicStore!(MemoryOrder.rel)(cs.next, ohead);\n         }\n         unlockMutex(cast(Mutex*)&gcs.mtx);\ndiff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d\nindex 0f7c8161527..ce1e03bbf34 100644\n--- a/libphobos/libdruntime/rt/dmain2.d\n+++ b/libphobos/libdruntime/rt/dmain2.d\n@@ -44,6 +44,9 @@ else version (Posix)\n     import core.stdc.string : strlen;\n }\n \n+version (DigitalMars) version (AArch64)\n+    version = UseMalloc;   // cuz alloca() is not implemented yet\n+\n // not sure why we can't define this in one place, but this is to keep this\n // module from importing core.runtime.\n struct UnitTestResult\n@@ -279,14 +282,30 @@ extern (C) int _d_run_main(int argc, char** argv, MainFunc mainFunc)\n         // assert(wargc == argc); /* argc can be broken by Unicode arguments */\n \n         // Allocate args[] on the stack - use wargc\n-        char[][] args = (cast(char[]*) alloca(wargc * (char[]).sizeof))[0 .. wargc];\n+        version (UseMalloc)\n+        {\n+            char[][] args = (cast(char[]*) malloc(wargc * (char[]).sizeof))[0 .. wargc];\n+            if (wargc)\n+                assert(args.ptr);\n+            scope (exit) free(args.ptr);\n+        }\n+        else\n+            char[][] args = (cast(char[]*) alloca(wargc * (char[]).sizeof))[0 .. wargc];\n \n         // This is required because WideCharToMultiByte requires int as input.\n         assert(wCommandLineLength <= cast(size_t) int.max, \"Wide char command line length must not exceed int.max\");\n \n         immutable size_t totalArgsLength = WideCharToMultiByte(CP_UTF8, 0, wCommandLine, cast(int)wCommandLineLength, null, 0, null, null);\n         {\n-            char* totalArgsBuff = cast(char*) alloca(totalArgsLength);\n+            version (UseMalloc)\n+            {\n+                char* totalArgsBuff = cast(char*) malloc(totalArgsLength);\n+                if (totalArgsLength)\n+                    assert(totalArgsBuff);\n+                scope (exit) free(totalArgsBuff);\n+            }\n+            else\n+                char* totalArgsBuff = cast(char*) alloca(totalArgsLength);\n             size_t j = 0;\n             foreach (i; 0 .. wargc)\n             {\n@@ -308,7 +327,15 @@ extern (C) int _d_run_main(int argc, char** argv, MainFunc mainFunc)\n     else version (Posix)\n     {\n         // Allocate args[] on the stack\n-        char[][] args = (cast(char[]*) alloca(argc * (char[]).sizeof))[0 .. argc];\n+        version (UseMalloc)\n+        {\n+            char[][] args = (cast(char[]*) malloc(argc * (char[]).sizeof))[0 .. argc];\n+            if (argc)\n+                assert(args.ptr);\n+            scope (exit) free(args.ptr);\n+        }\n+        else\n+            char[][] args = (cast(char[]*) alloca(argc * (char[]).sizeof))[0 .. argc];\n \n         size_t totalArgsLength = 0;\n         foreach (i, ref arg; args)\n@@ -434,7 +461,17 @@ private extern (C) int _d_run_main2(char[][] args, size_t totalArgsLength, MainF\n      */\n     {\n         _d_args = cast(string[]) args;\n-        auto buff = cast(char[]*) alloca(args.length * (char[]).sizeof + totalArgsLength);\n+\n+        auto length = args.length * (char[]).sizeof + totalArgsLength;\n+        version (UseMalloc)\n+        {\n+            auto buff = cast(char[]*) malloc(length);\n+            if (length)\n+                assert(buff);\n+            //scope (exit) buff;\n+        }\n+        else\n+            auto buff = cast(char[]*) alloca(length);\n \n         char[][] argsCopy = buff[0 .. args.length];\n         auto argBuff = cast(char*) (buff + args.length);\n@@ -515,9 +552,9 @@ private extern (C) int _d_run_main2(char[][] args, size_t totalArgsLength, MainF\n                 if (utResult.summarize)\n                 {\n                     if (utResult.passed == 0)\n-                        .fprintf(.stderr, \"No unittests run\\n\");\n+                        .fprintf(cast().stderr, \"No unittests run\\n\");\n                     else\n-                        .fprintf(.stderr, \"%d modules passed unittests\\n\",\n+                        .fprintf(cast().stderr, \"%d modules passed unittests\\n\",\n                                  cast(int)utResult.passed);\n                 }\n                 if (utResult.runMain)\n@@ -528,7 +565,7 @@ private extern (C) int _d_run_main2(char[][] args, size_t totalArgsLength, MainF\n             else\n             {\n                 if (utResult.summarize)\n-                    .fprintf(.stderr, \"%d/%d modules FAILED unittests\\n\",\n+                    .fprintf(cast().stderr, \"%d/%d modules FAILED unittests\\n\",\n                              cast(int)(utResult.executed - utResult.passed),\n                              cast(int)utResult.executed);\n                 result = EXIT_FAILURE;\n@@ -549,9 +586,9 @@ private extern (C) int _d_run_main2(char[][] args, size_t totalArgsLength, MainF\n     tryExec(&runAll);\n \n     // Issue 10344: flush stdout and return nonzero on failure\n-    if (.fflush(.stdout) != 0)\n+    if (.fflush(cast().stdout) != 0)\n     {\n-        .fprintf(.stderr, \"Failed to flush stdout: %s\\n\", .strerror(.errno));\n+        .fprintf(cast().stderr, \"Failed to flush stdout: %s\\n\", .strerror(.errno));\n         if (result == 0)\n         {\n             result = EXIT_FAILURE;\n@@ -628,7 +665,7 @@ extern (C) void _d_print_throwable(Throwable t)\n \n         // ensure the exception is shown at the beginning of the line, while also\n         // checking whether stderr is a valid file\n-        int written = fprintf(stderr, \"\\n\");\n+        int written = fprintf(cast()stderr, \"\\n\");\n         if (written <= 0)\n         {\n             WSink buf;\n@@ -654,7 +691,7 @@ extern (C) void _d_print_throwable(Throwable t)\n             }\n             return;\n         }\n-        auto hStdErr = windowsHandle(fileno(stderr));\n+        auto hStdErr = windowsHandle(fileno(cast()stderr));\n         CONSOLE_SCREEN_BUFFER_INFO sbi = void;\n         const isConsole = GetConsoleScreenBufferInfo(hStdErr, &sbi) != 0;\n         if (isConsole)\n@@ -682,7 +719,7 @@ extern (C) void _d_print_throwable(Throwable t)\n \n     void sink(in char[] buf) scope nothrow\n     {\n-        fwrite(buf.ptr, char.sizeof, buf.length, stderr);\n+        fwrite(buf.ptr, char.sizeof, buf.length, cast()stderr);\n     }\n     formatThrowable(t, &sink);\n }\ndiff --git a/libphobos/libdruntime/rt/minfo.d b/libphobos/libdruntime/rt/minfo.d\nindex 6f096744127..a70aabbeb64 100644\n--- a/libphobos/libdruntime/rt/minfo.d\n+++ b/libphobos/libdruntime/rt/minfo.d\n@@ -183,7 +183,7 @@ struct ModuleGroup\n         {\n         case \"deprecate\":\n             // Option deprecated in 2.101, remove in 2.111\n-            fprintf(stderr, \"`--DRT-oncycle=deprecate` is no longer supported, using `abort` instead\\n\");\n+            fprintf(cast()stderr, \"`--DRT-oncycle=deprecate` is no longer supported, using `abort` instead\\n\");\n             break;\n         case \"abort\":\n             onCycle = abort;\n@@ -375,7 +375,7 @@ struct ModuleGroup\n                                 case print:\n                                     // print the message\n                                     buildCycleMessage(idx, midx, (string x) {\n-                                                      fprintf(stderr, \"%.*s\", cast(int) x.length, x.ptr);\n+                                                      fprintf(cast()stderr, \"%.*s\", cast(int) x.length, x.ptr);\n                                                       });\n                                     // continue on as if this is correct.\n                                     break;\n@@ -520,7 +520,7 @@ struct ModuleGroup\n             !doSort(MItlsctor | MItlsdtor, _tlsctors))\n         {\n             // print a warning\n-            fprintf(stderr, \"Deprecation 16211 warning:\\n\"\n+            fprintf(cast()stderr, \"Deprecation 16211 warning:\\n\"\n                 ~ \"A cycle has been detected in your program that was undetected prior to DMD\\n\"\n                 ~ \"2.072. This program will continue, but will not operate when using DMD 2.074\\n\"\n                 ~ \"to compile. Use runtime option --DRT-oncycle=print to see the cycle details.\\n\");\ndiff --git a/libphobos/libdruntime/rt/monitor_.d b/libphobos/libdruntime/rt/monitor_.d\nindex 1d4ed2ea8fc..b63707ee959 100644\n--- a/libphobos/libdruntime/rt/monitor_.d\n+++ b/libphobos/libdruntime/rt/monitor_.d\n@@ -36,14 +36,14 @@ else\n //       may not be safe or desirable.  Thus, devt is only valid if impl is\n //       null.\n \n-extern (C) void _d_setSameMutex(shared Object ownee, shared Object owner) nothrow\n+extern (C) void _d_setSameMutex(shared Object ownee, shared Object owner) @trusted nothrow\n in\n {\n     assert(ownee.__monitor is null);\n }\n do\n {\n-    auto m = ensureMonitor(cast(Object) owner);\n+    auto m = ensureMonitor(cast(Object) cast(void*) owner);\n     if (m.impl is null)\n     {\n         atomicOp!\"+=\"(m.refs, size_t(1));\n@@ -238,19 +238,19 @@ private:\n \n __gshared Mutex gmtx;\n \n-@property ref shared(Monitor*) monitor(return scope Object h) pure nothrow @nogc\n+shared(Monitor*)* monitorPtr(return scope Object h) pure nothrow @nogc @trusted\n {\n-    return *cast(shared Monitor**)&h.__monitor;\n+    return cast(shared(Monitor*)*) &h.__monitor;\n }\n \n shared(Monitor)* getMonitor(Object h) pure @nogc\n {\n-    return atomicLoad!(MemoryOrder.acq)(h.monitor);\n+    return atomicLoad!(MemoryOrder.acq)(*monitorPtr(h));\n }\n \n void setMonitor(Object h, shared(Monitor)* m) pure @nogc\n {\n-    atomicStore!(MemoryOrder.rel)(h.monitor, m);\n+    atomicStore!(MemoryOrder.rel)(*monitorPtr(h), m);\n }\n \n shared(Monitor)* ensureMonitor(Object h)\ndiff --git a/libphobos/libdruntime/rt/profilegc.d b/libphobos/libdruntime/rt/profilegc.d\nindex e7d4f03e53a..dd12995f422 100644\n--- a/libphobos/libdruntime/rt/profilegc.d\n+++ b/libphobos/libdruntime/rt/profilegc.d\n@@ -151,7 +151,7 @@ shared static ~this()\n     {\n         qsort(counts.ptr, counts.length, Result.sizeof, &Result.qsort_cmp);\n \n-        FILE* fp = logfilename == \"\\0\" ? stdout : fopen((logfilename).ptr, \"w\");\n+        FILE* fp = logfilename == \"\\0\" ? cast()stdout : fopen((logfilename).ptr, \"w\");\n         if (fp)\n         {\n             fprintf(fp, \"bytes allocated, allocations, type, function, file:line\\n\");\n@@ -167,7 +167,7 @@ shared static ~this()\n         else\n         {\n             const err = errno;\n-            fprintf(stderr, \"cannot write profilegc log file '%.*s' (errno=%d)\",\n+            fprintf(cast()stderr, \"cannot write profilegc log file '%.*s' (errno=%d)\",\n                 cast(int) logfilename.length,\n                 logfilename.ptr,\n                 cast(int) err);\ndiff --git a/libphobos/libdruntime/rt/sections.d b/libphobos/libdruntime/rt/sections.d\nindex ce5a6682dfe..98a09a94eb0 100644\n--- a/libphobos/libdruntime/rt/sections.d\n+++ b/libphobos/libdruntime/rt/sections.d\n@@ -45,9 +45,11 @@ else version (Solaris)\n else version (Darwin)\n {\n     version (X86_64)\n-        public import rt.sections_osx_x86_64;\n+        public import rt.sections_osx_64;\n     else version (X86)\n         public import rt.sections_osx_x86;\n+    else version (AArch64)\n+        public import rt.sections_osx_64;\n     else\n         static assert(0, \"unimplemented\");\n }\ndiff --git a/libphobos/src/MERGE b/libphobos/src/MERGE\nindex d5e9b11a68c..25a0815d39d 100644\n--- a/libphobos/src/MERGE\n+++ b/libphobos/src/MERGE\n@@ -1,4 +1,4 @@\n-0c5c9e98443de1bb75c7c3560f58baa6ce725209\n+0c519ae39c00ebbb69b0e3a2e6e02710d7730915\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/Makefile.am b/libphobos/src/Makefile.am\nindex 13c35c22ddd..de74f5c3a27 100644\n--- a/libphobos/src/Makefile.am\n+++ b/libphobos/src/Makefile.am\n@@ -146,14 +146,15 @@ PHOBOS_DSOURCES = etc/c/curl.d etc/c/odbc/odbc32.d etc/c/odbc/odbc64.d \\\n \tstd/internal/unicode_comp.d std/internal/unicode_decomp.d \\\n \tstd/internal/unicode_grapheme.d std/internal/unicode_norm.d \\\n \tstd/internal/unicode_tables.d std/internal/windows/advapi32.d \\\n-\tstd/json.d std/logger/core.d std/logger/filelogger.d \\\n-\tstd/logger/multilogger.d std/logger/nulllogger.d std/logger/package.d \\\n-\tstd/math/algebraic.d std/math/constants.d std/math/exponential.d \\\n-\tstd/math/hardware.d std/math/operations.d std/math/package.d \\\n-\tstd/math/remainder.d std/math/rounding.d std/math/traits.d \\\n-\tstd/math/trigonometry.d std/mathspecial.d std/meta.d std/mmfile.d \\\n-\tstd/net/curl.d std/net/isemail.d std/numeric.d std/outbuffer.d \\\n-\tstd/package.d std/parallelism.d std/path.d std/process.d std/random.d \\\n+\tstd/internal/windows/bcrypt.d std/json.d std/logger/core.d \\\n+\tstd/logger/filelogger.d std/logger/multilogger.d \\\n+\tstd/logger/nulllogger.d std/logger/package.d std/math/algebraic.d \\\n+\tstd/math/constants.d std/math/exponential.d std/math/hardware.d \\\n+\tstd/math/operations.d std/math/package.d std/math/remainder.d \\\n+\tstd/math/rounding.d std/math/traits.d std/math/trigonometry.d \\\n+\tstd/mathspecial.d std/meta.d std/mmfile.d std/net/curl.d \\\n+\tstd/net/isemail.d std/numeric.d std/outbuffer.d std/package.d \\\n+\tstd/parallelism.d std/path.d std/process.d std/random.d \\\n \tstd/range/interfaces.d std/range/package.d std/range/primitives.d \\\n \tstd/regex/internal/backtracking.d std/regex/internal/generator.d \\\n \tstd/regex/internal/ir.d std/regex/internal/kickstart.d \\\ndiff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in\nindex 960ca98cc1d..c7dd55aac7b 100644\n--- a/libphobos/src/Makefile.in\n+++ b/libphobos/src/Makefile.in\n@@ -255,6 +255,7 @@ am__dirstamp = $(am__leading_dot)dirstamp\n @ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/internal/unicode_norm.lo \\\n @ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/internal/unicode_tables.lo \\\n @ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/internal/windows/advapi32.lo \\\n+@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/internal/windows/bcrypt.lo \\\n @ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/json.lo std/logger/core.lo \\\n @ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/logger/filelogger.lo \\\n @ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/logger/multilogger.lo \\\n@@ -619,14 +620,15 @@ libgphobos_la_LINK = $(LIBTOOL) --tag=D $(libgphobos_la_LIBTOOLFLAGS) \\\n @ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/internal/unicode_comp.d std/internal/unicode_decomp.d \\\n @ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/internal/unicode_grapheme.d std/internal/unicode_norm.d \\\n @ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/internal/unicode_tables.d std/internal/windows/advapi32.d \\\n-@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/json.d std/logger/core.d std/logger/filelogger.d \\\n-@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/logger/multilogger.d std/logger/nulllogger.d std/logger/package.d \\\n-@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/math/algebraic.d std/math/constants.d std/math/exponential.d \\\n-@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/math/hardware.d std/math/operations.d std/math/package.d \\\n-@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/math/remainder.d std/math/rounding.d std/math/traits.d \\\n-@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/math/trigonometry.d std/mathspecial.d std/meta.d std/mmfile.d \\\n-@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/net/curl.d std/net/isemail.d std/numeric.d std/outbuffer.d \\\n-@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/package.d std/parallelism.d std/path.d std/process.d std/random.d \\\n+@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/internal/windows/bcrypt.d std/json.d std/logger/core.d \\\n+@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/logger/filelogger.d std/logger/multilogger.d \\\n+@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/logger/nulllogger.d std/logger/package.d std/math/algebraic.d \\\n+@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/math/constants.d std/math/exponential.d std/math/hardware.d \\\n+@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/math/operations.d std/math/package.d std/math/remainder.d \\\n+@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/math/rounding.d std/math/traits.d std/math/trigonometry.d \\\n+@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/mathspecial.d std/meta.d std/mmfile.d std/net/curl.d \\\n+@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/net/isemail.d std/numeric.d std/outbuffer.d std/package.d \\\n+@ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/parallelism.d std/path.d std/process.d std/random.d \\\n @ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/range/interfaces.d std/range/package.d std/range/primitives.d \\\n @ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/regex/internal/backtracking.d std/regex/internal/generator.d \\\n @ENABLE_LIBDRUNTIME_ONLY_FALSE@\tstd/regex/internal/ir.d std/regex/internal/kickstart.d \\\n@@ -909,6 +911,7 @@ std/internal/windows/$(am__dirstamp):\n \t@: > std/internal/windows/$(am__dirstamp)\n std/internal/windows/advapi32.lo:  \\\n \tstd/internal/windows/$(am__dirstamp)\n+std/internal/windows/bcrypt.lo: std/internal/windows/$(am__dirstamp)\n std/json.lo: std/$(am__dirstamp)\n std/logger/$(am__dirstamp):\n \t@$(MKDIR_P) std/logger\ndiff --git a/libphobos/src/index.dd b/libphobos/src/index.dd\nindex ed8e46ba8bb..2483bcbb8e1 100644\n--- a/libphobos/src/index.dd\n+++ b/libphobos/src/index.dd\n@@ -3,10 +3,13 @@ Ddoc\n $(P Phobos is the standard runtime library that comes with the D language\n compiler.)\n \n-$(P Generally, the `std` namespace is used for the main modules in the\n-Phobos standard library. The `etc` namespace is used for external C/C++\n-library bindings. The `core` namespace is used for low-level D runtime\n-functions.)\n+- The `std` namespace is used for the main modules in the\n+  Phobos standard library.\n+- The $(LREF etc) namespace is used for external C/C++ library bindings.\n+- The `core` namespace is mainly used for low-level D runtime functions.\n+- $(RELATIVE_LINK2 stdc, `core.stdc`) wraps the C standard library.\n+- $(RELATIVE_LINK2 stdcpp, `core.stdcpp`) wraps some of the C++ standard library.\n+- `core.sys` wraps OS headers.\n \n $(P The following table is a quick reference guide for which Phobos modules to\n use for a given category of functionality. Note that some modules may appear in\n@@ -130,7 +133,7 @@ $(BOOKTABLE ,\n         $(TD Defines built-in exception types and low-level\n             language hooks required by the compiler.)\n     )\n-    $(LEADINGROW External library bindings)\n+    $(LEADINGROW $(LNAME2 etc, External library bindings))\n     $(TR\n         $(TDNW $(MREF etc,c,curl))\n         $(TD Interface to libcurl C library.)\n@@ -156,6 +159,14 @@ $(BOOKTABLE ,\n         $(TDNW $(MREF etc,c,zlib))\n         $(TD Interface to zlib C library.)\n     )\n+    $(TR\n+        $(TDNW $(MREF etc,linux,memoryerror))\n+        $(TD Handle memory errors on Linux.)\n+    )\n+    $(TR\n+        $(TDNW $(MREF etc,valgrind,valgrind))\n+        $(TD Interface to $(LINK2 https://valgrind.org, Valgrind) for dynamic analysis.)\n+    )\n     $(LEADINGROW I/O &amp; File system)\n     $(TR\n         $(TDNW $(MREF std,file))\n@@ -194,12 +205,31 @@ $(BOOKTABLE ,\n             $(MREF core,stdc,wctype)$(BR)\n         )\n         $(TD\n-            D bindings for standard C headers.$(BR)$(BR)\n+            D bindings for $(LNAME2 stdc, standard C) headers.$(BR)$(BR)\n             These are mostly undocumented, as documentation\n             for the functions these declarations provide\n             bindings to can be found on external resources.\n         )\n     )\n+    $(TR\n+        $(TDNW\n+            $(MREF core,stdcpp,allocator)$(BR)\n+            $(MREF core,stdcpp,array)$(BR)\n+            $(MREF core,stdcpp,exception)$(BR)\n+            $(MREF core,stdcpp,memory)$(BR)\n+            $(MREF core,stdcpp,new_)$(BR)\n+            $(MREF core,stdcpp,string)$(BR)\n+            $(MREF core,stdcpp,string_view)$(BR)\n+            $(MREF core,stdcpp,type_traits)$(BR)\n+            $(MREF core,stdcpp,typeinfo)$(BR)\n+            $(MREF core,stdcpp,utility)$(BR)\n+            $(MREF core,stdcpp,vector)$(BR)\n+            $(MREF core,stdcpp,xutility)$(BR)\n+        )\n+        $(TD\n+            Partial D bindings for $(LNAME2 stdcpp, standard C++) headers.$(BR)$(BR)\n+        )\n+    )\n     $(LEADINGROW Memory management)\n     $(TR\n         $(TDNW $(MREF core,memory))\n@@ -307,8 +337,10 @@ $(BOOKTABLE ,\n         $(TD An arbitrary-precision integer type.)\n     )\n     $(TR\n-        $(TDNW $(MREF std,int128))\n-        $(TDNW $(MREF core,int128))\n+        $(TDNW\n+            $(MREF std,int128)$(BR)\n+            $(MREF core,int128)\n+        )\n         $(TD 128 bit-precision integer type.)\n     )\n     $(TR\ndiff --git a/libphobos/src/std/algorithm/setops.d b/libphobos/src/std/algorithm/setops.d\nindex 10873a7cabc..f373fe74e70 100644\n--- a/libphobos/src/std/algorithm/setops.d\n+++ b/libphobos/src/std/algorithm/setops.d\n@@ -365,6 +365,8 @@ if (ranges.length >= 2 &&\n     // For infinite ranges or non-forward ranges, we fall back to the old\n     // implementation which expands an exponential number of templates.\n     import std.typecons : tuple;\n+    import std.meta : allSatisfy;\n+    import std.range.primitives : hasLength;\n \n     static struct Result\n     {\n@@ -413,13 +415,37 @@ if (ranges.length >= 2 &&\n             }\n             return copy;\n         }\n+        static if (allSatisfy!(hasLength, RR))\n+        {\n+            @property size_t length()\n+            {\n+                size_t result = 1;\n+                foreach (r; ranges)\n+                {\n+                    result *= r.length;\n+                }\n+                return result;\n+            }\n+        }\n     }\n     static assert(isForwardRange!Result, Result.stringof ~ \" must be a forward\"\n             ~ \" range\");\n \n     return Result(ranges);\n }\n+@safe unittest\n+{\n+    import std.algorithm.setops : cartesianProduct;\n+\n+    // 2 ranges\n+    assert(cartesianProduct([1, 2], [3, 4]).length == 4);\n \n+    // different sizes\n+    assert(cartesianProduct([1, 2, 3], [4, 5]).length == 6);\n+\n+    // 3 ranges\n+    assert(cartesianProduct([1, 2], [3, 4], [5]).length == 4);\n+}\n // cartesian product of empty ranges should be empty\n // https://issues.dlang.org/show_bug.cgi?id=10693\n @safe unittest\ndiff --git a/libphobos/src/std/array.d b/libphobos/src/std/array.d\nindex e85eadb4090..dfcffdd8882 100644\n--- a/libphobos/src/std/array.d\n+++ b/libphobos/src/std/array.d\n@@ -1083,14 +1083,6 @@ if (isDynamicArray!T && allSatisfy!(isIntegral, I))\n     }\n }\n \n-// from rt/lifetime.d\n-private extern(C) void[] _d_newarrayU(const TypeInfo ti, size_t length) pure nothrow;\n-\n-// from rt/tracegc.d\n-version (D_ProfileGC)\n-private extern (C) void[] _d_newarrayUTrace(string file, size_t line,\n-    string funcname, const scope TypeInfo ti, size_t length) pure nothrow;\n-\n private auto arrayAllocImpl(bool minimallyInitialized, T, I...)(I sizes) nothrow\n {\n     static assert(I.length <= nDimensions!T,\n@@ -1141,18 +1133,19 @@ private auto arrayAllocImpl(bool minimallyInitialized, T, I...)(I sizes) nothrow\n               which will inform the GC how to destroy the items in the block\n               when it gets collected.\n \n-              _d_newarrayU returns a void[], but with the length set according\n-              to E.sizeof.\n+              _d_newarrayU returns a E[], with the length set according to\n+              to the size parameter.\n             +/\n+            enum isShared = is (E == shared);\n             version (D_ProfileGC)\n             {\n                 // FIXME: file, line, function should be propagated from the\n                 // caller, not here.\n-                *(cast(void[]*)&ret) = _d_newarrayUTrace(__FILE__, __LINE__,\n-                    __FUNCTION__, typeid(E[]), size);\n+                ret = _d_newarrayUTrace!E(size, isShared,\n+                    __FILE__, __LINE__, __FUNCTION__);\n             }\n             else\n-                *(cast(void[]*)&ret) = _d_newarrayU(typeid(E[]), size);\n+                ret = _d_newarrayU!E(size, isShared);\n             static if (minimallyInitialized && hasIndirections!E)\n                 // _d_newarrayU would have asserted if the multiplication below\n                 // had overflowed, so we don't have to check it again.\n@@ -3581,11 +3574,18 @@ See_Also: $(LREF appender)\n struct Appender(A)\n if (isDynamicArray!A)\n {\n-    import std.format.spec : FormatSpec;\n+    import core.memory : GC;\n \n     private alias T = ElementEncodingType!A;\n \n-    InPlaceAppender!A* impl;\n+    private struct Data\n+    {\n+        size_t capacity;\n+        Unqual!T[] arr;\n+        bool tryExtendBlock = false;\n+    }\n+\n+    private Data* _data;\n \n     /**\n      * Constructs an `Appender` with a given array.  Note that this does not copy the\n@@ -3593,17 +3593,27 @@ if (isDynamicArray!A)\n      * it will be used by the appender.  After initializing an appender on an array,\n      * appending to the original array will reallocate.\n      */\n-    this(A arr) @safe\n+    this(A arr) @trusted\n     {\n-        impl = new InPlaceAppender!A(arr);\n-    }\n+        // initialize to a given array.\n+        _data = new Data;\n+        _data.arr = cast(Unqual!T[]) arr; //trusted\n \n-    private void ensureInit() @safe\n-    {\n-        if (impl is null)\n+        if (__ctfe)\n+            return;\n+\n+        // We want to use up as much of the block the array is in as possible.\n+        // if we consume all the block that we can, then array appending is\n+        // safe WRT built-in append, and we can use the entire block.\n+        // We only do this for mutable types that can be extended.\n+        static if (isMutable!T && is(typeof(arr.length = size_t.max)))\n         {\n-            impl = new InPlaceAppender!A;\n+            immutable cap = arr.capacity; //trusted\n+            // Replace with \"GC.setAttr( Not Appendable )\" once pure (and fixed)\n+            if (cap > arr.length)\n+                arr.length = cap;\n         }\n+        _data.capacity = arr.length;\n     }\n \n     /**\n@@ -3616,10 +3626,14 @@ if (isDynamicArray!A)\n      */\n     void reserve(size_t newCapacity)\n     {\n-        if (newCapacity != 0)\n+        if (_data)\n+        {\n+            if (newCapacity > _data.capacity)\n+                ensureAddable(newCapacity - _data.arr.length);\n+        }\n+        else\n         {\n-            ensureInit();\n-            impl.reserve(newCapacity);\n+            ensureAddable(newCapacity);\n         }\n     }\n \n@@ -3630,11 +3644,11 @@ if (isDynamicArray!A)\n      */\n     @property size_t capacity() const\n     {\n-        return impl ? impl.capacity : 0;\n+        return _data ? _data.capacity : 0;\n     }\n \n     /// Returns: The number of elements appended.\n-    @property size_t length() const => (impl is null) ? 0 : impl.length;\n+    @property size_t length() const => _data ? _data.arr.length : 0;\n \n     /**\n      * Use opSlice() from now on.\n@@ -3642,219 +3656,29 @@ if (isDynamicArray!A)\n      */\n     @property inout(T)[] data() inout\n     {\n-        return opSlice();\n+        return this[];\n     }\n \n     /**\n      * Returns: The managed array.\n      */\n-    @property inout(T)[] opSlice() inout @safe\n-    {\n-        return impl ? impl.opSlice() : null;\n-    }\n-\n-    /**\n-     * Appends `item` to the managed array. Performs encoding for\n-     * `char` types if `A` is a differently typed `char` array.\n-     *\n-     * Params:\n-     *     item = the single item to append\n-     */\n-    void put(U)(U item)\n-    if (InPlaceAppender!A.canPutItem!U)\n-    {\n-        ensureInit();\n-        impl.put(item);\n-    }\n-\n-    // Const fixing hack.\n-    void put(Range)(Range items)\n-    if (InPlaceAppender!A.canPutConstRange!Range)\n-    {\n-        if (!items.empty)\n-        {\n-            ensureInit();\n-            impl.put(items);\n-        }\n-    }\n-\n-    /**\n-     * Appends an entire range to the managed array. Performs encoding for\n-     * `char` elements if `A` is a differently typed `char` array.\n-     *\n-     * Params:\n-     *     items = the range of items to append\n-     */\n-    void put(Range)(Range items)\n-    if (InPlaceAppender!A.canPutRange!Range)\n-    {\n-        if (!items.empty)\n-        {\n-            ensureInit();\n-            impl.put(items);\n-        }\n-    }\n-\n-    /**\n-     * Appends to the managed array.\n-     *\n-     * See_Also: $(LREF Appender.put)\n-     */\n-    alias opOpAssign(string op : \"~\") = put;\n-\n-\n-    // only allow overwriting data on non-immutable and non-const data\n-    static if (isMutable!T)\n-    {\n-        /**\n-         * Clears the managed array.  This allows the elements of the array to be reused\n-         * for appending.\n-         *\n-         * Note: clear is disabled for immutable or const element types, due to the\n-         * possibility that `Appender` might overwrite immutable data.\n-         */\n-        void clear() @safe pure nothrow\n-        {\n-            if (impl)\n-            {\n-                impl.clear();\n-            }\n-        }\n-\n-        /**\n-         * Shrinks the managed array to the given length.\n-         *\n-         * Throws: `Exception` if newlength is greater than the current array length.\n-         * Note: shrinkTo is disabled for immutable or const element types.\n-         */\n-        void shrinkTo(size_t newlength) @safe pure\n-        {\n-            import std.exception : enforce;\n-            if (impl)\n-            {\n-                impl.shrinkTo(newlength);\n-            }\n-            else\n-            {\n-                enforce(newlength == 0, \"Attempting to shrink empty Appender with non-zero newlength\");\n-            }\n-        }\n-    }\n-\n-    /**\n-     * Gives a string in the form of `Appender!(A)(data)`.\n-     *\n-     * Params:\n-     *     w = A `char` accepting\n-     *     $(REF_ALTTEXT output range, isOutputRange, std, range, primitives).\n-     *     fmt = A $(REF FormatSpec, std, format) which controls how the array\n-     *     is formatted.\n-     * Returns:\n-     *     A `string` if `writer` is not set; `void` otherwise.\n-     */\n-    string toString()() const\n-    {\n-        return InPlaceAppender!A.toStringImpl(Unqual!(typeof(this)).stringof, impl ? impl.data : null);\n-    }\n-\n-    /// ditto\n-    template toString(Writer)\n-    if (isOutputRange!(Writer, char))\n-    {\n-        void toString(scope ref Writer w, scope const ref FormatSpec!char fmt) const\n-        {\n-            InPlaceAppender!A.toStringImpl(Unqual!(typeof(this)).stringof, impl ? impl.data : null, w, fmt);\n-        }\n-    }\n-}\n-\n-///\n-@safe pure nothrow unittest\n-{\n-    auto app = appender!string();\n-    string b = \"abcdefg\";\n-    foreach (char c; b)\n-        app.put(c);\n-    assert(app[] == \"abcdefg\");\n-\n-    int[] a = [ 1, 2 ];\n-    auto app2 = appender(a);\n-    app2.put(3);\n-    app2.put([ 4, 5, 6 ]);\n-    assert(app2[] == [ 1, 2, 3, 4, 5, 6 ]);\n-}\n-\n-package(std) struct InPlaceAppender(A)\n-if (isDynamicArray!A)\n-{\n-    import core.memory : GC;\n-    import std.format.spec : FormatSpec;\n-\n-    private alias T = ElementEncodingType!A;\n-\n-    private\n-    {\n-        size_t _capacity;\n-        Unqual!T[] arr;\n-        bool tryExtendBlock = false;\n-    }\n-\n-    @disable this(ref InPlaceAppender);\n-\n-    this(A arrIn) @trusted\n-    {\n-        arr = cast(Unqual!T[]) arrIn; //trusted\n-\n-        if (__ctfe)\n-            return;\n-\n-        // We want to use up as much of the block the array is in as possible.\n-        // if we consume all the block that we can, then array appending is\n-        // safe WRT built-in append, and we can use the entire block.\n-        // We only do this for mutable types that can be extended.\n-        static if (isMutable!T && is(typeof(arrIn.length = size_t.max)))\n-        {\n-            immutable cap = arrIn.capacity; //trusted\n-            // Replace with \"GC.setAttr( Not Appendable )\" once pure (and fixed)\n-            if (cap > arrIn.length)\n-                arrIn.length = cap;\n-        }\n-        _capacity = arrIn.length;\n-    }\n-\n-    void reserve(size_t newCapacity)\n-    {\n-        if (newCapacity > _capacity)\n-            ensureAddable(newCapacity - arr.length);\n-    }\n-\n-    @property size_t capacity() const\n-    {\n-        return _capacity;\n-    }\n-\n-    @property size_t length() const => arr.length;\n-\n-    @property inout(T)[] data() inout\n-    {\n-        return this[];\n-    }\n-\n-    inout(T)[] opSlice() inout @trusted\n+    @property inout(T)[] opSlice() inout @trusted\n     {\n         /* @trusted operation:\n          * casting Unqual!T[] to inout(T)[]\n          */\n-        return cast(typeof(return)) arr;\n+        return cast(typeof(return))(_data ? _data.arr : null);\n     }\n \n     // ensure we can add nelems elements, resizing as necessary\n     private void ensureAddable(size_t nelems)\n     {\n-        immutable len = arr.length;\n+        if (!_data)\n+            _data = new Data;\n+        immutable len = _data.arr.length;\n         immutable reqlen = len + nelems;\n \n-        if (_capacity >= reqlen)\n+        if (_data.capacity >= reqlen)\n             return;\n \n         // need to increase capacity\n@@ -3862,17 +3686,17 @@ if (isDynamicArray!A)\n         {\n             static if (__traits(compiles, new Unqual!T[1]))\n             {\n-                arr.length = reqlen;\n+                _data.arr.length = reqlen;\n             }\n             else\n             {\n                 // avoid restriction of @disable this()\n-                arr = arr[0 .. _capacity];\n-                foreach (i; _capacity .. reqlen)\n-                    arr ~= Unqual!T.init;\n+                _data.arr = _data.arr[0 .. _data.capacity];\n+                foreach (i; _data.capacity .. reqlen)\n+                    _data.arr ~= Unqual!T.init;\n             }\n-            arr = arr[0 .. len];\n-            _capacity = reqlen;\n+            _data.arr = _data.arr[0 .. len];\n+            _data.capacity = reqlen;\n         }\n         else\n         {\n@@ -3880,11 +3704,11 @@ if (isDynamicArray!A)\n             // Time to reallocate.\n             // We need to almost duplicate what's in druntime, except we\n             // have better access to the capacity field.\n-            auto newlen = appenderNewCapacity!(T.sizeof)(_capacity, reqlen);\n+            auto newlen = appenderNewCapacity!(T.sizeof)(_data.capacity, reqlen);\n             // first, try extending the current block\n-            if (tryExtendBlock)\n+            if (_data.tryExtendBlock)\n             {\n-                immutable u = (() @trusted => GC.extend(arr.ptr, nelems * T.sizeof, (newlen - len) * T.sizeof))();\n+                immutable u = (() @trusted => GC.extend(_data.arr.ptr, nelems * T.sizeof, (newlen - len) * T.sizeof))();\n                 if (u)\n                 {\n                     // extend worked, update the capacity\n@@ -3893,10 +3717,11 @@ if (isDynamicArray!A)\n                     // at large unused blocks.\n                     static if (hasIndirections!T)\n                     {\n-                        immutable addedSize = u - (_capacity * T.sizeof);\n-                        () @trusted { memset(arr.ptr + _capacity, 0, addedSize); }();\n+                        immutable addedSize = u - (_data.capacity * T.sizeof);\n+                        () @trusted { memset(_data.arr.ptr + _data.capacity, 0, addedSize); }();\n                     }\n-                    _capacity = u / T.sizeof;\n+\n+                    _data.capacity = u / T.sizeof;\n                     return;\n                 }\n             }\n@@ -3910,11 +3735,11 @@ if (isDynamicArray!A)\n                     ~ \"available pointer range\");\n \n             auto bi = (() @trusted => GC.qalloc(nbytes, blockAttribute!T))();\n-            _capacity = bi.size / T.sizeof;\n-            import core.stdc.string : memcpy;\n+            _data.capacity = bi.size / T.sizeof;\n             if (len)\n-                () @trusted { memcpy(bi.base, arr.ptr, len * T.sizeof); }();\n-            arr = (() @trusted => (cast(Unqual!T*) bi.base)[0 .. len])();\n+                () @trusted { memcpy(bi.base, _data.arr.ptr, len * T.sizeof); }();\n+\n+            _data.arr = (() @trusted => (cast(Unqual!T*) bi.base)[0 .. len])();\n \n             // we requested new bytes that are not in the existing\n             // data. If T has pointers, then this new data could point at stale\n@@ -3925,7 +3750,7 @@ if (isDynamicArray!A)\n                     memset(bi.base + (len * T.sizeof), 0, (newlen - len) * T.sizeof);\n                 }();\n \n-            tryExtendBlock = true;\n+            _data.tryExtendBlock = true;\n             // leave the old data, for safety reasons\n         }\n     }\n@@ -3941,13 +3766,13 @@ if (isDynamicArray!A)\n         enum bool canPutConstRange =\n             isInputRange!(Unqual!Range) &&\n             !isInputRange!Range &&\n-            is(typeof(InPlaceAppender.init.put(Range.init.front)));\n+            is(typeof(Appender.init.put(Range.init.front)));\n     }\n     private template canPutRange(Range)\n     {\n         enum bool canPutRange =\n             isInputRange!Range &&\n-            is(typeof(InPlaceAppender.init.put(Range.init.front)));\n+            is(typeof(Appender.init.put(Range.init.front)));\n     }\n \n     /**\n@@ -3976,13 +3801,13 @@ if (isDynamicArray!A)\n             import core.lifetime : emplace;\n \n             ensureAddable(1);\n-            immutable len = arr.length;\n+            immutable len = _data.arr.length;\n \n-            auto bigData = (() @trusted => arr.ptr[0 .. len + 1])();\n+            auto bigData = (() @trusted => _data.arr.ptr[0 .. len + 1])();\n             auto itemUnqual = (() @trusted => & cast() item)();\n             emplace(&bigData[len], *itemUnqual);\n             //We do this at the end, in case of exceptions\n-            arr = bigData;\n+            _data.arr = bigData;\n         }\n     }\n \n@@ -4026,16 +3851,16 @@ if (isDynamicArray!A)\n             auto bigDataFun(size_t extra)\n             {\n                 ensureAddable(extra);\n-                return (() @trusted => arr.ptr[0 .. arr.length + extra])();\n+                return (() @trusted => _data.arr.ptr[0 .. _data.arr.length + extra])();\n             }\n             auto bigData = bigDataFun(items.length);\n \n-            immutable len = arr.length;\n+            immutable len = _data.arr.length;\n             immutable newlen = bigData.length;\n \n             alias UT = Unqual!T;\n \n-            static if (is(typeof(arr[] = items[])) &&\n+            static if (is(typeof(_data.arr[] = items[])) &&\n                 !hasElaborateAssign!UT && isAssignable!(UT, ElementEncodingType!Range))\n             {\n                 bigData[len .. newlen] = items[];\n@@ -4051,7 +3876,7 @@ if (isDynamicArray!A)\n             }\n \n             //We do this at the end, in case of exceptions\n-            arr = bigData;\n+            _data.arr = bigData;\n         }\n         else static if (isSomeChar!T && isSomeChar!(ElementType!Range) &&\n                         !is(immutable T == immutable ElementType!Range))\n@@ -4094,7 +3919,10 @@ if (isDynamicArray!A)\n          */\n         void clear() @trusted pure nothrow\n         {\n-            arr = arr.ptr[0 .. 0];\n+            if (_data)\n+            {\n+                _data.arr = _data.arr.ptr[0 .. 0];\n+            }\n         }\n \n         /**\n@@ -4106,8 +3934,13 @@ if (isDynamicArray!A)\n         void shrinkTo(size_t newlength) @trusted pure\n         {\n             import std.exception : enforce;\n-            enforce(newlength <= arr.length, \"Attempting to shrink Appender with newlength > length\");\n-            arr = arr.ptr[0 .. newlength];\n+            if (_data)\n+            {\n+                enforce(newlength <= _data.arr.length, \"Attempting to shrink Appender with newlength > length\");\n+                _data.arr = _data.arr.ptr[0 .. newlength];\n+            }\n+            else\n+                enforce(newlength == 0, \"Attempting to shrink empty Appender with non-zero newlength\");\n         }\n     }\n \n@@ -4122,18 +3955,13 @@ if (isDynamicArray!A)\n      * Returns:\n      *     A `string` if `writer` is not set; `void` otherwise.\n      */\n-    auto toString() const\n-    {\n-        return toStringImpl(Unqual!(typeof(this)).stringof, data);\n-    }\n-\n-    static auto toStringImpl(string typeName, const T[] arr)\n+    string toString()() const\n     {\n         import std.format.spec : singleSpec;\n \n-        InPlaceAppender!string app;\n+        auto app = appender!string();\n         auto spec = singleSpec(\"%s\");\n-        immutable len = arr.length;\n+        immutable len = _data ? _data.arr.length : 0;\n         // different reserve lengths because each element in a\n         // non-string-like array uses two extra characters for `, `.\n         static if (isSomeString!A)\n@@ -4146,25 +3974,25 @@ if (isDynamicArray!A)\n             // length, as it assumes each element is only one char\n             app.reserve((len * 3) + 25);\n         }\n-        toStringImpl(typeName, arr, app, spec);\n+        toString(app, spec);\n         return app.data;\n     }\n \n-    void toString(Writer)(scope ref Writer w, scope const ref FormatSpec!char fmt) const\n-    if (isOutputRange!(Writer, char))\n-    {\n-        toStringImpl(Unqual!(typeof(this)).stringof, data, w, fmt);\n-    }\n+    import std.format.spec : FormatSpec;\n \n-    static void toStringImpl(Writer)(string typeName, const T[] data, scope ref Writer w,\n-                                     scope const ref FormatSpec!char fmt)\n+    /// ditto\n+    template toString(Writer)\n+    if (isOutputRange!(Writer, char))\n     {\n-        import std.format.write : formatValue;\n-        import std.range.primitives : put;\n-        put(w, typeName);\n-        put(w, '(');\n-        formatValue(w, data, fmt);\n-        put(w, ')');\n+        void toString(ref Writer w, scope const ref FormatSpec!char fmt) const\n+        {\n+            import std.format.write : formatValue;\n+            import std.range.primitives : put;\n+            put(w, Unqual!(typeof(this)).stringof);\n+            put(w, '(');\n+            formatValue(w, data, fmt);\n+            put(w, ')');\n+        }\n     }\n }\n \n@@ -4207,16 +4035,6 @@ if (isDynamicArray!A)\n     assert(app3[] == \"Appender!(int[])(0001, 0002, 0003)\");\n }\n \n-@safe pure unittest\n-{\n-    auto app = appender!(char[])();\n-    app ~= \"hello\";\n-    app.clear;\n-    // not a promise, just nothing else exercises capacity\n-    // and this is the expected sort of behaviour\n-    assert(app.capacity >= 5);\n-}\n-\n // https://issues.dlang.org/show_bug.cgi?id=17251\n @safe pure nothrow unittest\n {\n@@ -4347,6 +4165,25 @@ if (isDynamicArray!A)\n         writeln(\"WARNING: test of Appender zeroing did not occur\");\n }\n \n+// https://github.com/dlang/phobos/issues/10747\n+@system unittest\n+{\n+    static struct A10747\n+    {\n+        this(ref A10747 rhs) { }\n+    }\n+\n+    static class R10747\n+    {\n+        A10747 front() { return A10747.init; }\n+        void popFront() { }\n+        bool empty = true;\n+    }\n+\n+    auto a = new R10747();\n+    a.array();\n+}\n+\n //Calculates an efficient growth scheme based on the old capacity\n //of data, and the minimum requested capacity.\n //arg curLen: The current length\n@@ -4479,24 +4316,6 @@ unittest\n     assert(app2.capacity >= 5);\n }\n \n-/++\n-    Convenience function that returns a $(LREF InPlaceAppender) instance,\n-    optionally initialized with `array`.\n- +/\n-package(std) InPlaceAppender!A inPlaceAppender(A)()\n-if (isDynamicArray!A)\n-{\n-    return InPlaceAppender!A(null);\n-}\n-/// ditto\n-package(std) InPlaceAppender!(E[]) inPlaceAppender(A : E[], E)(auto ref A array)\n-{\n-    static assert(!isStaticArray!A || __traits(isRef, array),\n-        \"Cannot create InPlaceAppender from an rvalue static array\");\n-\n-    return InPlaceAppender!(E[])(array);\n-}\n-\n /++\n     Convenience function that returns an $(LREF Appender) instance,\n     optionally initialized with `array`.\ndiff --git a/libphobos/src/std/container/rbtree.d b/libphobos/src/std/container/rbtree.d\nindex b5c8fa3352c..5b3964f659f 100644\n--- a/libphobos/src/std/container/rbtree.d\n+++ b/libphobos/src/std/container/rbtree.d\n@@ -88,6 +88,14 @@ struct RBNode(V)\n     private Node _right;\n     private Node _parent;\n \n+    private this(Node left, Node right, Node parent, V value)\n+    {\n+        this._left = left;\n+        this._right = right;\n+        this._parent = parent;\n+        this.value = value;\n+    }\n+\n     /**\n      * The value held by this node\n      */\n@@ -747,7 +755,7 @@ private struct RBRange(N)\n  * inserted after all existing duplicate elements.\n  */\n final class RedBlackTree(T, alias less = \"a < b\", bool allowDuplicates = false)\n-if (is(typeof((ref const T a) => binaryFun!less(a, a))))\n+if (isSuitablePredicate!(less, T))\n {\n     import std.meta : allSatisfy;\n     import std.range : Take;\n@@ -1995,7 +2003,9 @@ assert(equal(rbt[], [5]));\n }\n \n import std.range.primitives : isInputRange, ElementType;\n-import std.traits : isArray, isSomeString;\n+import std.traits : isArray, isSomeString, lvalueOf;\n+\n+private enum isSuitablePredicate(alias less, T) = is(typeof(binaryFun!less(lvalueOf!(const T), lvalueOf!(const T))));\n \n /++\n     Convenience function for creating a `RedBlackTree!E` from a list of\n@@ -2020,14 +2030,14 @@ auto redBlackTree(bool allowDuplicates, E)(E[] elems...)\n \n /++ Ditto +/\n auto redBlackTree(alias less, E)(E[] elems...)\n-if (is(typeof(binaryFun!less(E.init, E.init))))\n+if (isSuitablePredicate!(less, E))\n {\n     return new RedBlackTree!(E, less)(elems);\n }\n \n /++ Ditto +/\n auto redBlackTree(alias less, bool allowDuplicates, E)(E[] elems...)\n-if (is(typeof(binaryFun!less(E.init, E.init))))\n+if (isSuitablePredicate!(less, E))\n {\n     //We shouldn't need to instantiate less here, but for some reason,\n     //dmd can't handle it if we don't (even though the template which\n@@ -2051,7 +2061,7 @@ if (isInputRange!Stuff && !isArray!(Stuff))\n \n /++ Ditto +/\n auto redBlackTree(alias less, Stuff)(Stuff range)\n-if ( is(typeof(binaryFun!less((ElementType!Stuff).init, (ElementType!Stuff).init)))\n+if (isSuitablePredicate!(less, ElementType!Stuff)\n     && isInputRange!Stuff && !isArray!(Stuff))\n {\n     return new RedBlackTree!(ElementType!Stuff, less)(range);\n@@ -2059,7 +2069,7 @@ if ( is(typeof(binaryFun!less((ElementType!Stuff).init, (ElementType!Stuff).init\n \n /++ Ditto +/\n auto redBlackTree(alias less, bool allowDuplicates, Stuff)(Stuff range)\n-if ( is(typeof(binaryFun!less((ElementType!Stuff).init, (ElementType!Stuff).init)))\n+if (isSuitablePredicate!(less, ElementType!Stuff)\n     && isInputRange!Stuff && !isArray!(Stuff))\n {\n     //We shouldn't need to instantiate less here, but for some reason,\n@@ -2276,3 +2286,17 @@ if ( is(typeof(binaryFun!less((ElementType!Stuff).init, (ElementType!Stuff).init\n \n     cast(void) new RedBlackTree!(S, (ref const S a, ref const S b) => a.value > b.value);\n }\n+\n+// struct with move constructor\n+@safe unittest\n+{\n+    static struct S {\n+        int i;\n+        this(S s) { this.i = s.i; }\n+        this(int i) { this.i = i; }\n+        int opCmp(ref const S other) const @safe nothrow  { return i - other.i; }\n+    }\n+\n+    auto tree = new RedBlackTree!(S, \"a.i < b.i\", false);\n+    tree.insert(S(0));\n+}\ndiff --git a/libphobos/src/std/experimental/allocator/common.d b/libphobos/src/std/experimental/allocator/common.d\nindex 245157258c1..b06fb627d71 100644\n--- a/libphobos/src/std/experimental/allocator/common.d\n+++ b/libphobos/src/std/experimental/allocator/common.d\n@@ -63,8 +63,7 @@ unittest\n     class C2 { char c; }\n     static assert(stateSize!C2 == 4 * size_t.sizeof);\n     static class C3 { char c; }\n-    // Uncomment test after dmd issue closed https://github.com/dlang/dmd/issues/21065\n-    //static assert(stateSize!C3 == 3 * size_t.sizeof);\n+    static assert(stateSize!C3 == 2 * size_t.sizeof + char.sizeof);\n }\n \n /**\ndiff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d\nindex a5b53270f95..0d4959b226f 100644\n--- a/libphobos/src/std/file.d\n+++ b/libphobos/src/std/file.d\n@@ -969,6 +969,19 @@ if (isConvertibleToString!RF || isConvertibleToString!RT)\n     assert(t2.readText == \"2\");\n }\n \n+\n+@safe unittest\n+{\n+    import std.file;\n+    import std.exception : assertThrown;\n+\n+    string f = null;\n+\n+    // Check if FileException is thrown for invalid rename\n+    assertThrown!FileException(rename(\"\", f));\n+    assertThrown!FileException(rename(f, \"\"));\n+}\n+\n private void renameImpl(scope const(char)[] f, scope const(char)[] t,\n                         scope const(FSChar)* fromz, scope const(FSChar)* toz) @trusted\n {\n@@ -983,10 +996,10 @@ private void renameImpl(scope const(char)[] f, scope const(char)[] t,\n             import std.conv : to, text;\n \n             if (!f)\n-                f = to!(typeof(f))(fromz[0 .. wcslen(fromz)]);\n+                f = fromz ? to!(typeof(f))(fromz[0 .. wcslen(fromz)]) : \"(null)\";\n \n             if (!t)\n-                t = to!(typeof(t))(toz[0 .. wcslen(toz)]);\n+                t = toz ? to!(typeof(t))(toz[0 .. wcslen(toz)]) : \"(null)\";\n \n             enforce(false,\n                 new FileException(\ndiff --git a/libphobos/src/std/format/write.d b/libphobos/src/std/format/write.d\nindex d704c14f5fa..68a96d48625 100644\n--- a/libphobos/src/std/format/write.d\n+++ b/libphobos/src/std/format/write.d\n@@ -534,6 +534,8 @@ uint formattedWrite(Writer, Char, Args...)(auto ref Writer w, const scope Char[]\n \n     // Are we already done with formats? Then just dump each parameter in turn\n     uint currentArg = 0;\n+    bool lastWasConsumeAll;\n+\n     while (spec.writeUpToNextSpec(w))\n     {\n         if (currentArg == Args.length && !spec.indexStart)\n@@ -649,7 +651,10 @@ uint formattedWrite(Writer, Char, Args...)(auto ref Writer w, const scope Char[]\n             }\n         default:\n             if (spec.indexEnd == spec.indexEnd.max)\n+            {\n+                lastWasConsumeAll = true;\n                 break;\n+            }\n             else if (spec.indexEnd == spec.indexStart)\n                 throw new FormatException(\n                     text(\"Positional specifier %\", spec.indexStart, '$', spec.spec,\n@@ -660,7 +665,8 @@ uint formattedWrite(Writer, Char, Args...)(auto ref Writer w, const scope Char[]\n                     \" index exceeds \", Args.length));\n         }\n     }\n-    return currentArg;\n+\n+    return lastWasConsumeAll ? Args.length : currentArg;\n }\n \n ///\n@@ -1212,7 +1218,8 @@ if (isSomeString!(typeof(fmt)))\n     import std.array : appender;\n     auto w = appender!(char[])();\n \n-    formattedWrite(w, \"%1:$d\", 1, 2, 3);\n+    uint count = formattedWrite(w, \"%1:$d\", 1, 2, 3);\n+    assert(count == 3);\n     assert(w.data == \"123\");\n }\n \ndiff --git a/libphobos/src/std/internal/math/errorfunction.d b/libphobos/src/std/internal/math/errorfunction.d\nindex 8894ffb92ea..bb132ce8dea 100644\n--- a/libphobos/src/std/internal/math/errorfunction.d\n+++ b/libphobos/src/std/internal/math/errorfunction.d\n@@ -984,6 +984,9 @@ Journal of Statistical Software <b>11</b>, (July 2004).\n */\n real normalDistributionImpl(real a)\n {\n+    if (a is -real.infinity) return 0.0L;\n+    if (a is real.infinity) return 1.0L;\n+\n     real x = a * SQRT1_2;\n     real z = fabs(x);\n \n@@ -1005,6 +1008,8 @@ real normalDistributionImpl(real a)\n {\n assert(fabs(normalDistributionImpl(1L) - (0.841344746068543L)) < 0.0000000000000005L);\n assert(isIdentical(normalDistributionImpl(NaN(0x325)), NaN(0x325)));\n+assert(normalDistributionImpl(-real.infinity) == 0.0L);\n+assert(normalDistributionImpl(real.infinity) == 1.0L);\n }\n \n /*\ndiff --git a/libphobos/src/std/internal/math/gammafunction.d b/libphobos/src/std/internal/math/gammafunction.d\nindex d4e51f5653a..1b05ebd48a2 100644\n--- a/libphobos/src/std/internal/math/gammafunction.d\n+++ b/libphobos/src/std/internal/math/gammafunction.d\n@@ -168,12 +168,19 @@ real gammaStirling(real x)\n }\n \n /*\n- * Helper function: Incomplete gamma function computed by Temme's expansion.\n+ * Regularized incomplete gamma function computed by Temme's expansion. If\n+ * `compl` is true, it computes the complement of the regularized incomplete\n+ * gamma function instead.\n+ *\n+ * For a derivation of the algorithm, see A \"Set of Algorithms for the\n+ * Incomplete Gamma Functions\", N. M. Temme, Probability in the Engineering and\n+ * Informational Sciences, Volume 8, Issue 2, April 1994, pp. 291-307, DOI:\n+ * https://doi.org/10.1017/S0269964800003417.\n  *\n  * This is a port of igamma_temme_large from Boost.\n  *\n  */\n-real igammaTemmeLarge(real a, real x)\n+real igammaTemmeLarge(real a, real x, bool compl)\n {\n     static immutable real[][13] coef = [\n         [ -0.333333333333333333333L, 0.0833333333333333333333L,\n@@ -250,13 +257,12 @@ real igammaTemmeLarge(real a, real x)\n \n     // avoid nans when one of the arguments is inf:\n     if (x == real.infinity && a != real.infinity)\n-        return 0;\n-\n+        return compl ? 0.0L : 1.0L;\n     if (x != real.infinity && a == real.infinity)\n-        return 1;\n+        return compl ? 1.0L : 0.0L;\n \n     real sigma = (x - a) / a;\n-    real phi = sigma - log(sigma + 1);\n+    real phi = sigma - log1p(sigma);\n \n     real y = a * phi;\n     real z = sqrt(2 * phi);\n@@ -267,14 +273,40 @@ real igammaTemmeLarge(real a, real x)\n     foreach (i; 0 .. coef.length)\n         workspace[i] = poly(z, coef[i]);\n \n-    real result = poly(1 / a, workspace);\n-    result *= exp(-y) / sqrt(2 * PI * a);\n-    if (x < a)\n-        result = -result;\n+    // Rₐ(πœ‚) = [exp(-aπœ‚Β²/2)/√(2πœ‹a)]Sₐ(πœ‚)\n+    const r = exp(-y)/sqrt(2.0L*PI*a) * poly(1.0L/a, workspace);\n+\n+    if (compl)\n+    {\n+        // Q(a,x) = erfc(+πœ‚βˆš(a/2))/2 + Rₐ(πœ‚)\n+        return erfc(+sgn(sigma)*sqrt(y))/2.0L + r;\n+    }\n+    else\n+    {\n+        // P(a,x) = erfc(-πœ‚βˆš(a/2))/2 - Rₐ(πœ‚)\n+        return erfc(-sgn(sigma)*sqrt(y))/2.0L - r;\n+    }\n+}\n+\n+@safe unittest\n+{\n+    // Values were generated using scipy, which restricts values to double precision.\n+    assert(feqrel(igammaTemmeLarge(25.0, 25.0, true), 0.47339_84685_56349_37L) >= double.mant_dig);\n+    assert(feqrel(igammaTemmeLarge(25.0, 26.0, true), 0.39592_65699_99828_5L) >= double.mant_dig);\n+    assert(feqrel(igammaTemmeLarge(26.0, 25.0, true), 0.55292_14200_24414_8L) >= double.mant_dig);\n+\n+    assert(feqrel(igammaTemmeLarge(25.0, 25.0, false), 0.52660_15314_43650_6L) >= double.mant_dig);\n+    assert(feqrel(igammaTemmeLarge(26.0, 25.0, false), 0.44707_85799_75585_2L) >= double.mant_dig);\n+\n+    assert(\n+        feqrel(igammaTemmeLarge(30.0L,31.0L,true), 1.0L-igammaTemmeLarge(30.0L,31.0L,false))\n+        >= real.mant_dig - 1);\n \n-    result += erfc(sqrt(y)) / 2;\n+    assert(feqrel(igammaTemmeLarge(1e9, 1.1e9, false), 1.0) >= double.mant_dig);\n+    assert(feqrel(igammaTemmeLarge(1.1e9, 1e9, false), 0.0) >= double.mant_dig);\n \n-    return result;\n+    assert(\n+        feqrel(igammaTemmeLarge(1e6, 1e6 + 1.0, true), 0.49946_80772_57932_46L) >= double.mant_dig);\n }\n \n } // private\n@@ -692,35 +724,34 @@ private pragma(inline, true) real betaLarge(in real x, in real y)\n  */\n real beta(in real x, in real y)\n {\n+    // When one of the input parameters is NaN, return the NaN with the larger\n+    // payload. This mimics the behavior of the + operator.\n+    if (isNaN(x) || isNaN(y)) return cmp(abs(x), abs(y)) >= 0 ? x : y;\n+\n     real res;\n \n+    // Take advantage of the symmetry B(x,y) = B(y,x)\n+    // smaller ≀ larger\n+    const larger = cmp(x, y) >= 0 ? x : y;\n+    const smaller = cmp(x, y) >= 0 ? y : x;\n+    const sum = larger + smaller;\n+\n     // the main algorithm\n-    if (x > MAXGAMMA || y > MAXGAMMA || x + y > MAXGAMMA)\n+    if (larger > MAXGAMMA || sum > MAXGAMMA)\n     {\n-        res = betaLarge(x, y);\n+        res = betaLarge(smaller, larger);\n     }\n     else\n     {\n-        res = gamma(x) * gamma(y) / gamma(x+y);\n+        res = gamma(smaller) * gamma(larger) / gamma(sum);\n \n         // There are several regions near the asymptotes and inflection lines\n         // gamma cannot be computed but logGamma can.\n-        if (!isFinite(res)) res = betaLarge(x,y);\n+        if (!isFinite(res)) res = betaLarge(smaller, larger);\n     }\n \n     if (!isNaN(res)) return res;\n \n-    // For valid NaN results, always return the response from the main algorithm\n-    // in order to preserve signaling NaNs.\n-\n-    if (isNaN(x) || isNaN(y)) return res;\n-\n-    // Take advantage of the symmetry B(x,y) = B(y,x)\n-    // smaller ≀ larger\n-    const larger = cmp(x, y) >= 0 ? x : y;\n-    const smaller = cmp(x, y) >= 0 ? y : x;\n-    const sum = larger + smaller;\n-\n     // in a quadrant of the (smaller,larger) cartesian plane\n     const inQ1 = cmp(smaller, +0.0L) >= 0;\n     const inQ2 = !inQ1 && cmp(larger, +0.0L) >= 0;\n@@ -749,28 +780,35 @@ real beta(in real x, in real y)\n \n     if (inQ1)\n     {\n-        // 4) On the larger axis and larger is finite, B = +∞\n-        // 5) On the larger axis, and larger is +∞, B = nan\n+        // 4) At origin, B = +∞\n+        if (nextToOrigin) return +real.infinity;\n+\n+        // 5) On the larger axis and larger is finite, B = +∞\n+        // 6) On the larger axis, and larger is +∞, B = nan\n         if (nextToSmallAxis) return larger < +real.infinity ? +real.infinity : res;\n \n-        // 6) Not on the larger axis, and the larger is +∞, B = +0\n+        // 7) Not on the larger axis, and the larger is +∞, B = +0\n         if (!nextToSmallAxis && larger == +real.infinity) return +0.;\n+\n+        // not on larger axis, but near origin, case 4, or larger is very large,\n+        // case 7\n+        if (!nextToSmallAxis) return larger < 1 ? +real.infinity : +0.;\n     }\n \n     if (inQ2)\n     {\n-        // 7) Next to the origin, B = nan\n-        // 8) Next to the larger axis, but not the origin, B = -∞\n+        // 8) Next to the origin, B = nan\n+        // 9) Next to the larger axis, but not the origin, B = -∞\n         if (nextToSmallAxis) return nextToOrigin ? res : -real.infinity;\n \n-        // 9) Larger is +∞, B = ∞ * sgn(Ξ“(smaller))\n+        // 10) Larger is +∞, B = ∞ * sgn(Ξ“(smaller))\n         if (larger == +real.infinity) return copysign(real.infinity, sgnGamma(smaller));\n \n-        // 10) next to smaller axis, but not on an asymptote or at the origin,\n+        // 11) next to smaller axis, but not on an asymptote or at the origin,\n         //     B = +∞.\n         if (nextToLargeAxis && !onSmallAsymptote && !nextToOrigin) return +real.infinity;\n \n-        // larger very large, case 9\n+        // larger very large, case 10\n         // larger so large that ln|Ξ“(larger)| and ln|Ξ“(sum)| are too large to\n         // represent as reals. Thus they each are approximated as ∞, and the\n         // main algorithm resolves to NaN instead of ±∞.\n@@ -779,10 +817,10 @@ real beta(in real x, in real y)\n \n     if (inQ3)\n     {\n-        // 11) next to the smaller axis, but not on an asymptote, B = -∞.\n+        // 12) next to the smaller axis, but not on an asymptote, B = -∞.\n         if (nextToLargeAxis && !onSmallAsymptote) return -real.infinity;\n \n-        // near origin, case 11\n+        // near origin, case 12\n         // -larger and -sum are so small that ln|Ξ“(larger)| and ln|Ξ“(sum)| are\n         // too large to be represented as reals. Thus they each are approximated\n         // as ∞, and the main algorithm resolves to NaN instead of -∞.\n@@ -795,14 +833,20 @@ real beta(in real x, in real y)\n \n @safe unittest\n {\n+    // Test NaN payload propagation\n+    assert(isIdentical(beta(NaN(0x1), 7), NaN(0x1)));\n     assert(isIdentical(beta(2, NaN(0xABC)), NaN(0xABC)));\n+    assert(isIdentical(beta(NaN(0x1), NaN(0x2)), NaN(0x2)));\n \n     // Test symmetry\n+    assert(beta(1, 2) is beta(2, 1));\n \n     // Test first quadrant\n+    assert(beta(+0., +0.) == +real.infinity);\n     assert(beta(+0., 1) == +real.infinity);\n-    assert(beta(nextUp(+0.0L), nextUp(+0.0L) > 0), \"B(Ξ΅β‚“,Ρ𞁟) > 0\");\n+    assert(isClose(beta(nextUp(+0.0L), nextUp(+0.0L)), real.infinity), \"B(Ξ΅β‚“,Ρ𞁟) ≲ +∞\");\n     assert(!isNaN(beta(nextUp(+0.0L), 1)), \"B(Ξ΅,y), y > 0 should exist\");\n+    assert(isClose(beta(nextUp(+0.0L), nextDown(real.infinity)), +0.0L), \"B(Ξ΅,y) ≳ 0, y large\");\n     assert(beta(1, +real.infinity) is +0.0L, \"lim{yβ†’+∞} B(x,y) = 0⁺, x > 0\");\n     assert(beta(1, 1) > 0);\n     assert(beta(0.6*MAXGAMMA, 0.5*MAXGAMMA) > 0);\n@@ -1817,6 +1861,9 @@ do\n     if ( (x > 1.0L) && (x > a ) )\n         return 1.0L - gammaIncompleteCompl(a,x);\n \n+    if (a > 25.0L && abs(x-a) < 0.2L*a)\n+        return igammaTemmeLarge(a, x, false);\n+\n     real ax = a * log(x) - x - logGamma(a);\n /+\n     if ( ax < MINLOGL ) return 0; // underflow\n@@ -1872,7 +1919,7 @@ do\n     // log(x)-x = NaN when x = real.infinity\n     const real MAXLOGL =  1.1356523406294143949492E4L;\n     if (x > MAXLOGL)\n-        return igammaTemmeLarge(a, x);\n+        return igammaTemmeLarge(a, x, true);\n \n     real ax = a * log(x) - x - logGamma(a);\n //const real MINLOGL = -1.1355137111933024058873E4L;\n@@ -1945,12 +1992,29 @@ do\n real gammaIncompleteComplInv(real a, real p)\n in\n {\n-  assert(p >= 0 && p <= 1);\n-  assert(a>0);\n+    if (!any!isNaN(only(a, p)))\n+    {\n+        assert(signbit(a) == 0);\n+        assert(p >= 0.0L && p <= 1.0L);\n+    }\n }\n do\n {\n-    if (p == 0) return real.infinity;\n+    // pass p first, so that if p and a are NaNs with the same payload but with\n+    // opposite signs, return p.\n+    if (any!isNaN(only(a, p))) return largestNaNPayload(p, a);\n+\n+    // domain violations\n+    if (signbit(a) == 1) return real.nan;\n+    if (p < 0.0L || p > 1.0L) return real.nan;\n+\n+    // places where not invertible\n+    if (a is +0.0L && p < 1.0L) return real.nan;\n+    if (a is real.infinity && p > 0.0L) return real.nan;\n+\n+    // edge cases for p\n+    if (p == 0.0L) return real.infinity;\n+    if (p == 1.0L) return 0.0L;\n \n     real y0 = p;\n     const real MAXLOGL =  1.1356523406294143949492E4L;\n@@ -2093,6 +2157,9 @@ assert(gammaIncomplete(1, 0)==0);\n assert(gammaIncompleteCompl(1, 0)==1);\n assert(gammaIncomplete(4545, real.infinity)==1);\n \n+// Value was generated using scipy, which restricts values to double precision.\n+assert(feqrel(gammaIncomplete(1e20, 1e20), 0.50000_00000_13298) >= double.mant_dig);\n+\n // Values from Excel's (1-GammaDist(x, alpha, 1, TRUE))\n \n assert(fabs(1.0L-gammaIncompleteCompl(0.5L, 2) - 0.954499729507309L) < 0.00000005L);\n@@ -2107,6 +2174,13 @@ static if (real.mant_dig >= 64) // incl. 80-bit reals\n     assert(fabs(gammaIncompleteCompl(100000, 100001) - 0.49831792109L) < 0.000000000005L);\n else\n     assert(fabs(gammaIncompleteCompl(100000, 100001) - 0.49831792109L) < 0.00000005L);\n+\n+assert(gammaIncompleteComplInv(NaN(0x5UL), -NaN(0x5UL)) is -NaN(0x5UL));\n+assert(!isNaN(gammaIncompleteComplInv(+0.0L, 1.0L)));\n+assert(isNaN(gammaIncompleteComplInv(+0.0L, nextDown(1.0L))));\n+assert(!isNaN(gammaIncompleteComplInv(real.infinity, -0.0L)));\n+assert(isNaN(gammaIncompleteComplInv(real.infinity, nextUp(+0.0L))));\n+assert(gammaIncompleteComplInv(2.0L, 1.0L) == 0.0L);\n }\n \n \n@@ -2305,12 +2379,14 @@ real logmdigammaInverse(real y)\n     immutable maxY = logmdigamma(real.min_normal);\n     assert(maxY > 0 && maxY <= real.max);\n \n+    if (isNaN(y)) return y;\n+\n     if (y >= maxY)\n     {\n         //lim x->0 (log(x)-digamma(x))*x == 1\n         return 1 / y;\n     }\n-    if (y < 0)\n+    if (signbit(y) == 1)  // y is negative\n     {\n         return real.nan;\n     }\n@@ -2319,13 +2395,10 @@ real logmdigammaInverse(real y)\n         //6.3.18\n         return 0.5 / y;\n     }\n-    if (y > 0)\n-    {\n-        // x/2 <= logmdigamma(1 / x) <= x, x > 0\n-        // calls logmdigamma ~6 times\n-        return 1 / findRoot((real x) => logmdigamma(1 / x) - y, y,  2*y);\n-    }\n-    return y; //NaN\n+\n+    // x/2 <= logmdigamma(1 / x) <= x, x > 0\n+    // calls logmdigamma ~6 times\n+    return 1 / findRoot((real x) => logmdigamma(1 / x) - y, y,  2*y);\n }\n \n @safe unittest\n@@ -2348,4 +2421,6 @@ real logmdigammaInverse(real y)\n     assert(isClose(logmdigammaInverse(logmdigamma(1)), 1, 1e-15L));\n     assert(isClose(logmdigammaInverse(logmdigamma(real.min_normal)), real.min_normal, 1e-15L));\n     assert(isClose(logmdigammaInverse(logmdigamma(real.max/2)), real.max/2, 1e-15L));\n+    assert(logmdigammaInverse(NaN(0x1)) is NaN(0x1));\n+    assert(isNaN(logmdigammaInverse(-0.)));\n }\ndiff --git a/libphobos/src/std/internal/windows/bcrypt.d b/libphobos/src/std/internal/windows/bcrypt.d\nnew file mode 100644\nindex 00000000000..239dcd52e66\n--- /dev/null\n+++ b/libphobos/src/std/internal/windows/bcrypt.d\n@@ -0,0 +1,65 @@\n+module std.internal.windows.bcrypt;\n+\n+version (Windows):\n+\n+import core.sys.windows.bcrypt : BCryptGenRandom, BCRYPT_USE_SYSTEM_PREFERRED_RNG;\n+import core.sys.windows.windef : HMODULE, PUCHAR, ULONG;\n+import core.sys.windows.ntdef : NT_SUCCESS;\n+\n+pragma(lib, \"Bcrypt.lib\");\n+\n+package(std) bool bcryptGenRandom(T)(out T result) @trusted\n+{\n+    loadBcrypt();\n+\n+    const gotRandom = ptrBCryptGenRandom(\n+        null,\n+        cast(PUCHAR) &result,\n+        ULONG(T.sizeof),\n+        BCRYPT_USE_SYSTEM_PREFERRED_RNG,\n+    );\n+\n+    return NT_SUCCESS(gotRandom);\n+}\n+\n+private\n+{\n+    HMODULE hBcrypt = null;\n+    typeof(BCryptGenRandom)* ptrBCryptGenRandom;\n+}\n+\n+private void loadBcrypt() @nogc nothrow\n+{\n+    import core.sys.windows.winbase : GetProcAddress, LoadLibraryA;\n+\n+    if (!hBcrypt)\n+    {\n+        hBcrypt = LoadLibraryA(\"Bcrypt.dll\");\n+        if (!hBcrypt)\n+            assert(false, `LoadLibraryA(\"Bcrypt.dll\") failed.`); // `@nogc`\n+\n+        ptrBCryptGenRandom = cast(typeof(ptrBCryptGenRandom)) GetProcAddress(hBcrypt , \"BCryptGenRandom\");\n+        if (!ptrBCryptGenRandom)\n+            assert(false, `GetProcAddress(hBcrypt , \"BCryptGenRandom\") failed.`); // `@nogc`\n+    }\n+}\n+\n+// Will free `Bcrypt.dll`.\n+private void freeBcrypt() @nogc nothrow\n+{\n+    import core.sys.windows.winbase : FreeLibrary;\n+\n+    if (hBcrypt)\n+    {\n+        if (!FreeLibrary(hBcrypt))\n+            assert(false, `FreeLibrary(\"Bcrypt.dll\") failed.`); // `@nogc`\n+\n+        hBcrypt = null;\n+        ptrBCryptGenRandom = null;\n+    }\n+}\n+\n+static ~this()\n+{\n+    freeBcrypt();\n+}\ndiff --git a/libphobos/src/std/logger/core.d b/libphobos/src/std/logger/core.d\nindex 1e879fd6c56..58328eb6e9a 100644\n--- a/libphobos/src/std/logger/core.d\n+++ b/libphobos/src/std/logger/core.d\n@@ -13,6 +13,17 @@ import std.traits;\n \n import std.logger.filelogger;\n \n+/+\n+    Don’t forget to update the documentation of `std.logger` (`package.d`)\n+    when changing this test. This is a copy of example code found in its\n+    doc comment.\n+ +/\n+@system unittest\n+{\n+    assert(globalLogLevel == LogLevel.all);\n+    assert((cast() sharedLog).logLevel == LogLevel.info);\n+}\n+\n /** This functions is used at runtime to determine if a `LogLevel` is\n active. The same previously defined version statements are used to disable\n certain levels. Again the version statements are associated with a compile\ndiff --git a/libphobos/src/std/logger/package.d b/libphobos/src/std/logger/package.d\nindex 5a847491478..568510fec2d 100644\n--- a/libphobos/src/std/logger/package.d\n+++ b/libphobos/src/std/logger/package.d\n@@ -24,6 +24,76 @@ This will print a message to the `stderr` device. The message will contain\n the filename, the line number, the name of the surrounding function, the time\n and the message.\n \n+$(H4 Quickstart)\n+\n+$(B $(RED Pitfall:)) The $(B defaults) of this package are meant to be $(B reasonable for those who do $(I not) use logging).\n+Users who intend to use logging are expected to set it up accordingly.\n+\n+The logging machinery is basically a pipeline.\n+Convenience functions like `log()`, `info()` and `trace()` are on the very top end of it.\n+When one calls `trace()`, it sends a log message with `LogLevel.trace` down the pipes.\n+\n+One of the first checks is for `globalLogLevel`, where any message of a lesser log level is filtered out;\n+the default here is `LogLevel.all` which allows all log messages to be passed down further.\n+\n+Eventually, the logged message is passed into a logger which will perform an output operation.\n+Keep in mind, loggers themselves also have an assigned log level they filter for.\n+\n+On default settings, a log message will eventually reach `sharedLog`;\n+this one is a [FileLogger] writing to `stderr` with a threshold of `LogLevel.info`.\n+This default was chosen because of concerns regarding spamming trace messages to unsuspecting downstream library users.\n+\n+As consequence of this design decision, the `LogLevel` of `FileLogger` needs to be adjusted\n+in order to have `trace()` or `log()` actually print something.\n+\n+-------------\n+import std.logger;\n+\n+void main() @system\n+{\n+    // `globalLogLevel` defaults to `LogLevel.all`.\n+    // `sharedLog.logLevel` defaults to `LogLevel.info`.\n+    assert(globalLogLevel == LogLevel.all);\n+    assert((cast() sharedLog).logLevel == LogLevel.info);\n+\n+    // Log a few messages. These will be printed to `stderr` output.\n+    info(\"Works out of the box.\");\n+    warning(\"Works out of the box.\");\n+    error(\"Works out of the box.\");\n+    critical(\"Works out of the box.\");\n+\n+    // `log()` and `trace()` will not actually print anything as-is.\n+    log(\"Does *not* work out of the box.\");\n+    trace(\"Does *not* work out of the box.\");\n+\n+    // Enable trace logging output.\n+    (cast() sharedLog).logLevel = LogLevel.trace;\n+\n+    // Emit a log message with `LogLevel.trace`.\n+    trace(\"Tracing the World\");\n+\n+    // Set the log level to the most permissive option, i.e. `LogLevel.all`.\n+    (cast() sharedLog).logLevel = LogLevel.all;\n+\n+    // Emit a log message with `LogLevel.all`.\n+    log(\"All aboard!\");\n+\n+    // Logging a fatal message also throws an `Error`, i.e. crashes the program.\n+    fatal(\"C u l8r, alligator!\");\n+}\n+-------------\n+\n+$(H5 Rationale)\n+\n+$(UL\n+    $(LI $(LINK2 https://bugzilla-archive.dlang.org/bugs/22532/, Bugzilla Issue 22532 (archived)))\n+    $(LI $(LINK2 https://github.com/dlang/phobos/pull/8336, GitHub: dlang/phobos Pull request #8336))\n+    $(LI $(LINK2 https://github.com/dlang/phobos/pull/8406, GitHub: dlang/phobos Pull request #8406))\n+    $(LI $(LINK2 https://github.com/dlang/phobos/issues/10858, GitHub: dlang/phobos Issue #10858))\n+)\n+\n+$(H3 Advanced Usage)\n+\n More complex log call can go along the lines like:\n -------------\n log(\"Logging to the sharedLog with its default LogLevel\");\n@@ -35,14 +105,14 @@ errorf(\"Logging %s the sharedLog %s its error LogLevel\", \"to\", \"with\");\n critical(\"Logging to the\",\" sharedLog with its error LogLevel\");\n fatal(\"Logging to the sharedLog with its fatal LogLevel\");\n \n-auto fLogger = new FileLogger(\"NameOfTheLogFile\");\n-fLogger.log(\"Logging to the fileLogger with its default LogLevel\");\n-fLogger.info(\"Logging to the fileLogger with its default LogLevel\");\n-fLogger.warning(5 < 6, \"Logging to the fileLogger with its LogLevel.warning if 5 is less than 6\");\n-fLogger.warningf(5 < 6, \"Logging to the fileLogger with its LogLevel.warning if %s is %s than 6\", 5, \"less\");\n-fLogger.critical(\"Logging to the fileLogger with its info LogLevel\");\n-fLogger.log(LogLevel.trace, 5 < 6, \"Logging to the fileLogger\",\" with its default LogLevel if 5 is less than 6\");\n-fLogger.fatal(\"Logging to the fileLogger with its warning LogLevel\");\n+auto fileLogger = new FileLogger(\"NameOfTheLogFile\");\n+fileLogger.log(\"Logging to the fileLogger with its default LogLevel\");\n+fileLogger.info(\"Logging to the fileLogger with its default LogLevel\");\n+fileLogger.warning(5 < 6, \"Logging to the fileLogger with its LogLevel.warning if 5 is less than 6\");\n+fileLogger.warningf(5 < 6, \"Logging to the fileLogger with its LogLevel.warning if %s is %s than 6\", 5, \"less\");\n+fileLogger.critical(\"Logging to the fileLogger with its info LogLevel\");\n+fileLogger.log(LogLevel.trace, 5 < 6, \"Logging to the fileLogger\",\" with its default LogLevel if 5 is less than 6\");\n+fileLogger.fatal(\"Logging to the fileLogger with its warning LogLevel\");\n -------------\n Additionally, this example shows how a new `FileLogger` is created.\n Individual `Logger` and the global log functions share commonly named\ndiff --git a/libphobos/src/std/math/hardware.d b/libphobos/src/std/math/hardware.d\nindex 3e3d0da0e9d..302f041b1f6 100644\n--- a/libphobos/src/std/math/hardware.d\n+++ b/libphobos/src/std/math/hardware.d\n@@ -63,6 +63,7 @@ else version (RISCV_Any) version = IeeeFlagsSupport;\n else version (MIPS_Any)  version = IeeeFlagsSupport;\n else version (LoongArch_Any) version = IeeeFlagsSupport;\n else version (ARM_Any)   version = IeeeFlagsSupport;\n+else version (SPARC_Any) version = IeeeFlagsSupport;\n \n // Struct FloatingPointControl is only available if hardware FP units are available.\n version (D_HardFloat)\n@@ -90,7 +91,7 @@ private:\n     // The x87 FPU status register is 16 bits.\n     // The Pentium SSE2 status register is 32 bits.\n     // The ARM and PowerPC FPSCR is a 32-bit register.\n-    // The SPARC FSR is a 32bit register (64 bits for SPARC 7 & 8, but high bits are uninteresting).\n+    // The SPARC FSR is a 32-bit register (64 bits for SPARC V9, but high bits are uninteresting).\n     // The RISC-V (32 & 64 bit) fcsr is 32-bit register.\n     // THe LoongArch fcsr (fcsr0) is a 32-bit register.\n     uint flags;\n@@ -112,6 +113,36 @@ private:\n         // Don't bother about subnormals, they are not supported on most CPUs.\n         //  SUBNORMAL_MASK = 0x02;\n     }\n+    else version (Solaris)\n+    {\n+        // Solaris <fenv.h> uses hardware-incompatible floating-point status flags.\n+        // Use the <sys/fsr.h> AEXC (Accrued EXCeption) bit field of fsr instead.\n+        version (SPARC_Any)\n+        {\n+            enum : int\n+            {\n+                INEXACT_MASK    = 0x020,\n+                UNDERFLOW_MASK  = 0x080,\n+                OVERFLOW_MASK   = 0x100,\n+                DIVBYZERO_MASK  = 0x040,\n+                INVALID_MASK    = 0x200,\n+                EXCEPTIONS_MASK = 0x3E0,\n+            }\n+        }\n+        // Use the <sys/fp.h> masks for 80387 control word or SSE/SSE2 MXCSR instead.\n+        else version (X86_Any)\n+        {\n+            enum : int\n+            {\n+                INEXACT_MASK    = 0x20,\n+                UNDERFLOW_MASK  = 0x10,\n+                OVERFLOW_MASK   = 0x08,\n+                DIVBYZERO_MASK  = 0x04,\n+                INVALID_MASK    = 0x01,\n+                EXCEPTIONS_MASK = 0x3D,\n+            }\n+        }\n+    }\n     else\n     {\n         enum : int\n@@ -648,6 +679,36 @@ nothrow @nogc:\n                              | roundUp | roundToZero,\n         }\n     }\n+    else version (Solaris)\n+    {\n+        // Solaris <fenv.h> uses hardware-incompatible floating-point status flags.\n+        // Use the <sys/fsr.h> RD (Rounding Direction) field of fsr instead.\n+        version (SPARC_Any)\n+        {\n+            enum : RoundingMode\n+            {\n+                roundToNearest = 0x00000000,\n+                roundDown      = 0xC0000000,\n+                roundUp        = 0x80000000,\n+                roundToZero    = 0x40000000,\n+                roundingMask   = roundToNearest | roundDown\n+                                 | roundUp | roundToZero,\n+            }\n+        }\n+        // Use the <sys/fp.h> rounding options in control word instead.\n+        else version (X86_Any)\n+        {\n+            enum : RoundingMode\n+            {\n+                roundToNearest = 0x000,\n+                roundDown      = 0x400,\n+                roundUp        = 0x800,\n+                roundToZero    = 0xc00,\n+                roundingMask   = roundToNearest | roundDown\n+                                 | roundUp | roundToZero,\n+            }\n+        }\n+    }\n     else\n     {\n         enum : RoundingMode\n@@ -878,6 +939,8 @@ nothrow @nogc:\n             return true;\n         else version (SPARC_Any)\n             return true;\n+        else version (SPARC_Any)\n+            return true;\n         else version (ARM_Any)\n         {\n             // The hasExceptionTraps_impl function is basically pure,\n@@ -961,7 +1024,7 @@ private:\n     }\n     else version (SPARC_Any)\n     {\n-        alias ControlState = ulong;\n+        alias ControlState = uint;\n     }\n     else version (IBMZ_Any)\n     {\ndiff --git a/libphobos/src/std/mathspecial.d b/libphobos/src/std/mathspecial.d\nindex fc33c921191..0646f2c733c 100644\n--- a/libphobos/src/std/mathspecial.d\n+++ b/libphobos/src/std/mathspecial.d\n@@ -187,21 +187,6 @@ pragma(inline, true) real beta(real x, real y)\n @safe unittest\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 /** Digamma function, $(PSI)(x)\n@@ -505,23 +490,59 @@ do\n     assert(isClose(gammaIncompleteCompl(1, 2), 1-gammaIncomplete(1, 2)));\n }\n \n-/** Inverse of complemented incomplete gamma integral\n+/** Inverse regularized upper incomplete gamma function Q$(SUP -1)(a,p) with respect to p\n  *\n- * Given a and p, the function finds x such that\n+ * Given a and p, the function finds x such that p = Q(a,x).\n  *\n- *  gammaIncompleteCompl( a, x ) = p.\n+ * Params:\n+ *   a = the shape parameter, must be positive\n+ *   p = Q(a,x), must be in the interval [0,1]\n+ *\n+ * Returns:\n+ *   It returns x, a value $(GE) 0\n+ *\n+ * $(TABLE_SV\n+ *   $(TR $(TH a)               $(TH p)        $(TH gammaIncompleteComplInverse(a, p)) )\n+ *   $(TR $(TD negative)        $(TD)          $(TD $(NAN))                            )\n+ *   $(TR $(TD)                 $(TD $(LT) 0)  $(TD $(NAN))                            )\n+ *   $(TR $(TD)                 $(TD $(GT) 1)  $(TD $(NAN))                            )\n+ *   $(TR $(TD +0)              $(TD $(LT) 1)  $(TD $(NAN))                            )\n+ *   $(TR $(TD $(INFIN))        $(TD $(GT) 0)  $(TD $(NAN))                            )\n+ *   $(TR $(TD $(GT) 0)         $(TD 0)        $(TD $(INFIN))                          )\n+ *   $(TR $(TD $(LT) $(INFIN))  $(TD 1)        $(TD 0)                                 )\n+ * )\n+ *\n+ * See_Also: $(LREF gammaIncompleteCompl)\n  */\n real gammaIncompleteComplInverse(real a, real p)\n in\n {\n-  assert(p >= 0 && p <= 1);\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(p))\n+    {\n+        assert(signbit(a) == 0, \"a must be positive\");\n+        assert(p >= 0.0L && p <= 1.0L, \"p must be in the interval [0,1]\");\n+    }\n }\n+out(x; isNaN(x) || x >= 0.0L)\n do\n {\n     return std.internal.math.gammafunction.gammaIncompleteComplInv(a, p);\n }\n \n+///\n+@safe unittest\n+{\n+    const a = 2, p = 0.5L;\n+    assert(isClose(gammaIncompleteComplInverse(a, gammaIncompleteCompl(a, p)), p));\n+\n+    assert(isClose(gammaIncompleteComplInverse(1, 1/E), 1));\n+    assert(isNaN(gammaIncompleteComplInverse(+0.0L, 0.1)));\n+    assert(isNaN(gammaIncompleteComplInverse(real.infinity, 0.2)));\n+    assert(gammaIncompleteComplInverse(3, 0) is real.infinity);\n+    assert(gammaIncompleteComplInverse(4, 1) == 0);\n+}\n \n /* ***********************************************\n  *     ERROR FUNCTIONS & NORMAL DISTRIBUTION     *\ndiff --git a/libphobos/src/std/signals.d b/libphobos/src/std/signals.d\nindex 97004d52ddd..14b082fc20d 100644\n--- a/libphobos/src/std/signals.d\n+++ b/libphobos/src/std/signals.d\n@@ -66,11 +66,6 @@ import core.exception : onOutOfMemoryError;\n import core.stdc.stdlib : calloc, realloc, free;\n import std.stdio;\n \n-// Special function for internal use only.\n-// Use of this is where the slot had better be a delegate\n-// to an object or an interface that is part of an object.\n-extern (C) Object _d_toObject(void* p);\n-\n // Used in place of Object.notifyRegister and Object.notifyUnRegister.\n alias DisposeEvt = void delegate(Object);\n extern (C) void  rt_attachDisposeEvent( Object obj, DisposeEvt evt );\ndiff --git a/libphobos/src/std/socket.d b/libphobos/src/std/socket.d\nindex 8f29c78f59f..1c04e67dbd7 100644\n--- a/libphobos/src/std/socket.d\n+++ b/libphobos/src/std/socket.d\n@@ -3560,7 +3560,7 @@ public:\n             if (checkError) checkError.setMinCapacity(n);\n         }\n \n-        int result = .select(n, fr, fw, fe, &timeout.ctimeval);\n+        int result = .select(n, fr, fw, fe, timeout !is null ? &timeout.ctimeval : null);\n \n         version (Windows)\n         {\ndiff --git a/libphobos/src/std/traits.d b/libphobos/src/std/traits.d\nindex 759ccb94fcf..0f04afb55ff 100644\n--- a/libphobos/src/std/traits.d\n+++ b/libphobos/src/std/traits.d\n@@ -2246,8 +2246,8 @@ if (isCallable!func)\n     static assert(is( typeof(test) == FunctionTypeOf!test ));\n     static assert(is( typeof(test) == FunctionTypeOf!test_fp ));\n     static assert(is( typeof(test) == FunctionTypeOf!test_dg ));\n-    alias int GetterType() @property;\n-    alias int SetterType(int) @property;\n+    alias GetterType = int() @property;\n+    alias SetterType = int(int) @property;\n     static assert(is( FunctionTypeOf!propGet == GetterType ));\n     static assert(is( FunctionTypeOf!propSet == SetterType ));\n \ndiff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d\nindex a2039006c8b..b957394d523 100644\n--- a/libphobos/src/std/typecons.d\n+++ b/libphobos/src/std/typecons.d\n@@ -7586,12 +7586,12 @@ private template TypeMod(T)\n     }\n     alias methods = GetOverloadedMethods!A;\n \n-    alias int F1();\n-    alias @property int F2();\n-    alias string F3();\n-    alias nothrow @trusted uint F4();\n-    alias int F5(Object);\n-    alias bool F6(Object);\n+    alias F1 = int();\n+    alias F2 = @property int();\n+    alias F3 = string();\n+    alias F4 = nothrow @trusted uint();\n+    alias F5 = int(Object);\n+    alias F6 = bool(Object);\n     static assert(methods.length == 3 + 4);\n     static assert(__traits(identifier, methods[0]) == \"draw\"     && is(typeof(&methods[0]) == F1*));\n     static assert(__traits(identifier, methods[1]) == \"value\"    && is(typeof(&methods[1]) == F2*));\n@@ -7675,49 +7675,49 @@ package template DerivedFunctionType(T...)\n @safe unittest\n {\n     // attribute covariance\n-    alias int F1();\n+    alias F1 = int();\n     static assert(is(DerivedFunctionType!(F1, F1) == F1));\n-    alias int F2() pure nothrow;\n+    alias F2 = int() pure nothrow;\n     static assert(is(DerivedFunctionType!(F1, F2) == F2));\n-    alias int F3() @safe;\n-    alias int F23() @safe pure nothrow;\n+    alias F3 = int() @safe;\n+    alias F23 = int() @safe pure nothrow;\n     static assert(is(DerivedFunctionType!(F2, F3) == F23));\n \n     // return type covariance\n-    alias long F4();\n+    alias F4 = long();\n     static assert(is(DerivedFunctionType!(F1, F4) == void));\n     class C {}\n     class D : C {}\n-    alias C F5();\n-    alias D F6();\n+    alias F5 = C();\n+    alias F6 = D();\n     static assert(is(DerivedFunctionType!(F5, F6) == F6));\n-    alias typeof(null) F7();\n-    alias int[] F8();\n-    alias int* F9();\n+    alias F7 = typeof(null)();\n+    alias F8 = int[]();\n+    alias F9 = int*();\n     static assert(is(DerivedFunctionType!(F5, F7) == F7));\n     static assert(is(DerivedFunctionType!(F7, F8) == void));\n     static assert(is(DerivedFunctionType!(F7, F9) == F7));\n \n     // variadic type equality\n-    alias int F10(int);\n-    alias int F11(int...);\n-    alias int F12(int, ...);\n+    alias F10 = int(int);\n+    alias F11 = int(int...);\n+    alias F12 = int(int, ...);\n     static assert(is(DerivedFunctionType!(F10, F11) == void));\n     static assert(is(DerivedFunctionType!(F10, F12) == void));\n     static assert(is(DerivedFunctionType!(F11, F12) == void));\n \n     // linkage equality\n-    alias extern(C) int F13(int);\n-    alias extern(D) int F14(int);\n-    alias extern(Windows) int F15(int);\n+    alias F13 = extern(C) int(int);\n+    alias F14 = extern(D) int(int);\n+    alias F15 = extern(Windows) int(int);\n     static assert(is(DerivedFunctionType!(F13, F14) == void));\n     static assert(is(DerivedFunctionType!(F13, F15) == void));\n     static assert(is(DerivedFunctionType!(F14, F15) == void));\n \n     // ref & @property equality\n-    alias int F16(int);\n-    alias ref int F17(int);\n-    alias @property int F18(int);\n+    alias F16 = int(int);\n+    alias F17 = ref int(int);\n+    alias F18 = @property int(int);\n     static assert(is(DerivedFunctionType!(F16, F17) == void));\n     static assert(is(DerivedFunctionType!(F16, F18) == void));\n     static assert(is(DerivedFunctionType!(F17, F18) == void));\ndiff --git a/libphobos/src/std/uni/package.d b/libphobos/src/std/uni/package.d\nindex 34d15e034ba..d689f08e538 100644\n--- a/libphobos/src/std/uni/package.d\n+++ b/libphobos/src/std/uni/package.d\n@@ -1785,6 +1785,7 @@ alias sharSwitchLowerBound = sharMethod!switchUniformLowerBound;\n     {\n         debug\n         {\n+            assert(accessIsSafe);\n             arr[] = cast(typeof(T.init[0]))(0xdead_beef);\n         }\n         arr = null;\n@@ -1795,6 +1796,18 @@ alias sharSwitchLowerBound = sharMethod!switchUniformLowerBound;\n     {\n         arr = null;\n     }\n+\n+    // This is unfortunately necessary to \"fake pure\". It will only ever be called\n+    // in the destructor for a GC-allocated CowArray, which is the only place where\n+    // this might return false. Current code expects this to be pure, so we can't\n+    // break that. But before this change, the code would access the referenced\n+    // array inside a GC finalizer, which is invalid.\n+    pragma(mangle, \"gc_inFinalizer\") private static extern(C) bool pureInGCFinalizer() @safe pure nothrow;\n+\n+    static @property bool accessIsSafe() @safe nothrow pure\n+    {\n+        return __ctfe || !pureInGCFinalizer;\n+    }\n }\n \n // ditto\n@@ -1892,6 +1905,8 @@ alias sharSwitchLowerBound = sharMethod!switchUniformLowerBound;\n             pureFree(arr.ptr);\n         arr = null;\n     }\n+\n+    enum accessIsSafe = true;\n }\n \n //build hack\n@@ -3234,6 +3249,10 @@ struct CowArray(SP=GcPolicy)\n \n     ~this()\n     {\n+        if (!SP.accessIsSafe)\n+            // detach from the array, we can no longer access it.\n+            data = null;\n+\n         if (!empty)\n         {\n             immutable cnt = refCount;\ndiff --git a/libphobos/src/std/variant.d b/libphobos/src/std/variant.d\nindex 1760f5fd694..74b6065162d 100644\n--- a/libphobos/src/std/variant.d\n+++ b/libphobos/src/std/variant.d\n@@ -37,6 +37,7 @@ Source:    $(PHOBOSSRC std/variant.d)\n module std.variant;\n \n import std.meta, std.traits, std.typecons;\n+import core.memory : GC;\n \n ///\n @system unittest\n@@ -428,8 +429,8 @@ private:\n                     }\n                     else\n                     {\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+                        // object will be intialized later. Using malloc in case `this()` is disabled\n+                        A* p = cast(A*) GC.malloc(A.sizeof, 0, typeid(A));\n                     }\n                     *cast(A**)&target.store = p;\n                 }\n@@ -679,8 +680,8 @@ switchStmtTupAssign:\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+                            // object will be intialized later. Using malloc in case `this()` is disabled\n+                            A* p = cast(A*) GC.malloc(A.sizeof, 0, typeid(A));\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@@ -789,8 +790,8 @@ public:\n                 static if (is(T == U[n], U, size_t n))\n                     T* p = cast(T*) (new U[n]).ptr;\n                 else\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+                    // object will be intialized later. Using malloc in case `this()` is disabled\n+                    T* p = cast(T*) GC.malloc(T.sizeof, 0, typeid(T));\n                 copyEmplace(rhs, *p);\n                 *(cast(T**) &store) = p;\n             }\n@@ -1274,7 +1275,7 @@ public:\n             auto arr = get!(A[]);\n             foreach (ref e; arr)\n             {\n-                if (dg(e)) return 1;\n+                if (auto r = dg(e)) return r;\n             }\n         }\n         else static if (is(A == VariantN))\n@@ -1286,7 +1287,7 @@ public:\n                 // Variant when in fact they are only changing tmp.\n                 auto tmp = this[i];\n                 debug scope(exit) assert(tmp == this[i]);\n-                if (dg(tmp)) return 1;\n+                if (auto r = dg(tmp)) return r;\n             }\n         }\n         else\ndiff --git a/libphobos/testsuite/libphobos.aa/test_aa.d b/libphobos/testsuite/libphobos.aa/test_aa.d\nindex 214bc9a12b2..aef99e8ab5a 100644\n--- a/libphobos/testsuite/libphobos.aa/test_aa.d\n+++ b/libphobos/testsuite/libphobos.aa/test_aa.d\n@@ -1048,3 +1048,38 @@ void testAliasThis2()\n     assert(B(5) in aa);\n     assert(A(false, 5) in aa);\n }\n+\n+void test22510()\n+{\n+    static struct S(AA)\n+    {\n+        AA aa_;\n+        auto aa() inout => this.aa_.dup;\n+    }\n+    auto testDup(AA)()\n+    {\n+        S!AA s;\n+        return s.aa();\n+    }\n+    auto aa_ii = testDup!(int[int])();\n+    static assert(is(typeof(aa_ii) == int[int]));\n+\n+    auto aa_cii = testDup!(const(int[int]))();\n+    static assert(is(typeof(aa_cii) == int[int]));\n+\n+    static struct T\n+    {\n+        char[] s; // non const indirection disallows conversion of const(T) -> T when copying\n+    }\n+    auto aa_it = testDup!(int[T])();\n+    static assert(is(typeof(aa_it) == int[T]));\n+\n+    auto aa_cit = testDup!(const(int[T]))();\n+    static assert(is(typeof(aa_cit) == int[T]));\n+\n+    auto aa_ti = testDup!(T[int])();\n+    static assert(is(typeof(aa_ti) == T[int]));\n+\n+    auto aa_cti = testDup!(const(T[int]))();\n+    static assert(is(typeof(aa_cti) == const(T)[int]));\n+}\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_array.d b/libphobos/testsuite/libphobos.phobos/std_array.d\nindex b74b19a3e92..9d1c0216935 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_array.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_array.d\n@@ -442,23 +442,6 @@\n     assert(b == [1, 0, 0, 0, 5]);\n }\n \n-@safe pure nothrow unittest\n-{\n-    import std.array;\n-\n-    auto app = appender!string();\n-    string b = \"abcdefg\";\n-    foreach (char c; b)\n-        app.put(c);\n-    assert(app[] == \"abcdefg\");\n-\n-    int[] a = [ 1, 2 ];\n-    auto app2 = appender(a);\n-    app2.put(3);\n-    app2.put([ 4, 5, 6 ]);\n-    assert(app2[] == [ 1, 2, 3, 4, 5, 6 ]);\n-}\n-\n @safe pure nothrow unittest\n {\n     import std.array;\ndiff --git a/libphobos/testsuite/libphobos.phobos/std_mathspecial.d b/libphobos/testsuite/libphobos.phobos/std_mathspecial.d\nindex 84a90c81345..10521eece3f 100644\n--- a/libphobos/testsuite/libphobos.phobos/std_mathspecial.d\n+++ b/libphobos/testsuite/libphobos.phobos/std_mathspecial.d\n@@ -10,21 +10,6 @@\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@@ -84,3 +69,17 @@\n     assert(isClose(gammaIncompleteCompl(1, 2), 1-gammaIncomplete(1, 2)));\n }\n \n+@safe unittest\n+{\n+    import std.mathspecial;\n+\n+    const a = 2, p = 0.5L;\n+    assert(isClose(gammaIncompleteComplInverse(a, gammaIncompleteCompl(a, p)), p));\n+\n+    assert(isClose(gammaIncompleteComplInverse(1, 1/E), 1));\n+    assert(isNaN(gammaIncompleteComplInverse(+0.0L, 0.1)));\n+    assert(isNaN(gammaIncompleteComplInverse(real.infinity, 0.2)));\n+    assert(gammaIncompleteComplInverse(3, 0) is real.infinity);\n+    assert(gammaIncompleteComplInverse(4, 1) == 0);\n+}\n+\n",
    "prefixes": [
        "committed"
    ]
}