From 5984fd9da4b7dda16d5f5fe1534babe1495ff83f Mon Sep 17 00:00:00 2001 From: Dennis Date: Tue, 24 Feb 2026 14:17:21 +0100 Subject: [PATCH 1/5] Fix dlang/dmd!22625 - undefined identifier 'addr' in core.sys.posix.netinet.in_.IN6* (dlang/dmd!22627) Co-authored-by: Dennis Korpel --- .../druntime/src/core/sys/posix/netinet/in_.d | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/runtime/druntime/src/core/sys/posix/netinet/in_.d b/runtime/druntime/src/core/sys/posix/netinet/in_.d index 09a4a5e07d..75359ea213 100644 --- a/runtime/druntime/src/core/sys/posix/netinet/in_.d +++ b/runtime/druntime/src/core/sys/posix/netinet/in_.d @@ -547,7 +547,7 @@ version (CRuntime_Glibc) } // macros - extern (D) int IN6_IS_ADDR_UNSPECIFIED()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_UNSPECIFIED()(const scope in6_addr* addr) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && @@ -555,7 +555,7 @@ version (CRuntime_Glibc) (cast(uint32_t*) addr)[3] == 0; } - extern (D) int IN6_IS_ADDR_LOOPBACK()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_LOOPBACK()(const scope in6_addr* addr) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && @@ -563,29 +563,29 @@ version (CRuntime_Glibc) (cast(uint32_t*) addr)[3] == htonl( 1 ); } - extern (D) int IN6_IS_ADDR_MULTICAST()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_MULTICAST()(const scope in6_addr* addr) pure { return (cast(uint8_t*) addr)[0] == 0xff; } - extern (D) int IN6_IS_ADDR_LINKLOCAL()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_LINKLOCAL()(const scope in6_addr* addr) pure { return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfe800000 ); } - extern (D) int IN6_IS_ADDR_SITELOCAL()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_SITELOCAL()(const scope in6_addr* addr) pure { return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfec00000 ); } - extern (D) int IN6_IS_ADDR_V4MAPPED()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_V4MAPPED()(const scope in6_addr* addr) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && (cast(uint32_t*) addr)[2] == htonl( 0xffff ); } - extern (D) int IN6_IS_ADDR_V4COMPAT()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_V4COMPAT()(const scope in6_addr* addr) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && @@ -593,31 +593,31 @@ version (CRuntime_Glibc) ntohl( (cast(uint32_t*) addr)[3] ) > 1; } - extern (D) int IN6_IS_ADDR_MC_NODELOCAL()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_MC_NODELOCAL()(const scope in6_addr* addr) pure { return IN6_IS_ADDR_MULTICAST( addr ) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x1; } - extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()(const scope in6_addr* addr) pure { return IN6_IS_ADDR_MULTICAST( addr ) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x2; } - extern (D) int IN6_IS_ADDR_MC_SITELOCAL()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_MC_SITELOCAL()(const scope in6_addr* addr) pure { return IN6_IS_ADDR_MULTICAST(addr) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x5; } - extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()(const scope in6_addr* addr) pure { return IN6_IS_ADDR_MULTICAST( addr) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x8; } - extern (D) int IN6_IS_ADDR_MC_GLOBAL()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_MC_GLOBAL()(const scope in6_addr* addr) pure { return IN6_IS_ADDR_MULTICAST( addr ) && ((cast(uint8_t*) addr)[1] & 0xf) == 0xe; @@ -670,7 +670,7 @@ else version (Darwin) } // macros - extern (D) int IN6_IS_ADDR_UNSPECIFIED()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_UNSPECIFIED()(const scope in6_addr* addr) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && @@ -678,7 +678,7 @@ else version (Darwin) (cast(uint32_t*) addr)[3] == 0; } - extern (D) int IN6_IS_ADDR_LOOPBACK()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_LOOPBACK()(const scope in6_addr* addr) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && @@ -686,29 +686,29 @@ else version (Darwin) (cast(uint32_t*) addr)[3] == ntohl( 1 ); } - extern (D) int IN6_IS_ADDR_MULTICAST()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_MULTICAST()(const scope in6_addr* addr) pure { return addr.s6_addr[0] == 0xff; } - extern (D) int IN6_IS_ADDR_LINKLOCAL()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_LINKLOCAL()(const scope in6_addr* addr) pure { return addr.s6_addr[0] == 0xfe && (addr.s6_addr[1] & 0xc0) == 0x80; } - extern (D) int IN6_IS_ADDR_SITELOCAL()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_SITELOCAL()(const scope in6_addr* addr) pure { return addr.s6_addr[0] == 0xfe && (addr.s6_addr[1] & 0xc0) == 0xc0; } - extern (D) int IN6_IS_ADDR_V4MAPPED()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_V4MAPPED()(const scope in6_addr* addr) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && (cast(uint32_t*) addr)[2] == ntohl( 0x0000ffff ); } - extern (D) int IN6_IS_ADDR_V4COMPAT()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_V4COMPAT()(const scope in6_addr* addr) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && @@ -717,31 +717,31 @@ else version (Darwin) (cast(uint32_t*) addr)[3] != ntohl( 1 ); } - extern (D) int IN6_IS_ADDR_MC_NODELOCAL()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_MC_NODELOCAL()(const scope in6_addr* addr) pure { return IN6_IS_ADDR_MULTICAST( addr ) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x1; } - extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_MC_LINKLOCAL()(const scope in6_addr* addr) pure { return IN6_IS_ADDR_MULTICAST( addr ) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x2; } - extern (D) int IN6_IS_ADDR_MC_SITELOCAL()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_MC_SITELOCAL()(const scope in6_addr* addr) pure { return IN6_IS_ADDR_MULTICAST(addr) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x5; } - extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_MC_ORGLOCAL()(const scope in6_addr* addr) pure { return IN6_IS_ADDR_MULTICAST( addr) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x8; } - extern (D) int IN6_IS_ADDR_MC_GLOBAL()(const scope in6_addr* add) pure + extern (D) int IN6_IS_ADDR_MC_GLOBAL()(const scope in6_addr* addr) pure { return IN6_IS_ADDR_MULTICAST( addr ) && ((cast(uint8_t*) addr)[1] & 0xf) == 0xe; From d83c7d570649eb25b605cb3a10c1c62973038f77 Mon Sep 17 00:00:00 2001 From: Divyansh Sharma <140371139+divyansharma001@users.noreply.github.com> Date: Wed, 25 Feb 2026 08:38:54 +0530 Subject: [PATCH 2/5] Fix Issue dlang/dmd!22567 - alias this and nested AAs cause compiler SIGILL (dlang/dmd!22622) When an alias this redirects a nested AA write through a struct field, the inner AA IndexExp was left with modifiable=true and never lowered to an rvalue read, causing a SIGILL in the IR generator. Add revertModifiableAAIndexReads() to handle this case: it recurses through DotVarExp wrappers produced by alias this and lowers any modifiable AA IndexExp to a proper rvalue read before the side-effect extraction in rewriteAAIndexAssign(). --- dmd/expressionsem.d | 21 +++++++++++++++++++++ tests/dmd/runnable/testaa3.d | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/dmd/expressionsem.d b/dmd/expressionsem.d index 5fea4e408b..15c88e98eb 100644 --- a/dmd/expressionsem.d +++ b/dmd/expressionsem.d @@ -18884,6 +18884,26 @@ Expression revertIndexAssignToRvalues(IndexExp ie, Scope* sc) return lowerAAIndexRead(ie, sc); } +// Ditto, but traverses DotVarExp from `alias this` rewrites. +private Expression revertModifiableAAIndexReads(Expression e, Scope* sc) +{ + // Recurse through dot-accesses (alias this produces DotVarExp on an inner IndexExp) + if (auto dve = e.isDotVarExp()) + { + dve.e1 = revertModifiableAAIndexReads(dve.e1, sc); + return e; + } + if (auto ie = e.isIndexExp()) + { + // Recurse first to handle deeper nesting + ie.e1 = revertModifiableAAIndexReads(ie.e1, sc); + // Lower a modifiable AA IndexExp to an rvalue read + if (ie.modifiable && ie.e1.type.isTypeAArray()) + return lowerAAIndexRead(ie, sc); + } + return e; +} + // helper for rewriteAAIndexAssign private Expression implicitConvertToStruct(Expression ev, StructDeclaration sd, Scope* sc) { @@ -18934,6 +18954,7 @@ private Expression rewriteAAIndexAssign(BinExp exp, Scope* sc, ref Type[2] alias // find the AA of multi dimensional access for (auto ieaa = ie.e1.isIndexExp(); ieaa && ieaa.e1.type.isTypeAArray(); ieaa = ieaa.e1.isIndexExp()) eaa = ieaa.e1; + eaa = revertModifiableAAIndexReads(eaa, sc); eaa = extractSideEffect(sc, "__aatmp", e0, eaa); // collect all keys of multi dimensional access Expressions ekeys; diff --git a/tests/dmd/runnable/testaa3.d b/tests/dmd/runnable/testaa3.d index 53a0e8bb86..e94273b7da 100644 --- a/tests/dmd/runnable/testaa3.d +++ b/tests/dmd/runnable/testaa3.d @@ -429,6 +429,23 @@ void testShared() /***************************************************/ +// https://github.com/dlang/dmd/issues/22567 +void test22567() +{ + struct S + { + string[string] data; + alias this = data; + } + + S[string] foo; + foo["bar"] = S(); + foo["bar"]["baz"] = "boom"; + assert(foo["bar"]["baz"] == "boom"); +} + +/***************************************************/ + void main() { assert(testLiteral()); @@ -456,4 +473,5 @@ void main() test21066(); test22354(); testShared(); + test22567(); } From 2750eb23c4181d07e7afa504731234e2f5621f77 Mon Sep 17 00:00:00 2001 From: Rainer Date: Thu, 26 Feb 2026 11:34:10 +0100 Subject: [PATCH 3/5] fix issue dlang/dmd!22556 - shared AAs with RefCounted values don't work even after removing shared allow AA.clear with shared values for backward compatibility --- runtime/druntime/src/object.d | 14 ++++++++++++++ tests/dmd/runnable/testaa3.d | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/runtime/druntime/src/object.d b/runtime/druntime/src/object.d index 3097e6b658..bf450fc706 100644 --- a/runtime/druntime/src/object.d +++ b/runtime/druntime/src/object.d @@ -2985,16 +2985,30 @@ alias AssociativeArray(Key, Value) = Value[Key]; * aa = The associative array. */ void clear(Value, Key)(Value[Key] aa) @trusted +if (!is(Value == shared)) { _aaClear(aa); } /** ditto */ void clear(Value, Key)(Value[Key]* aa) @trusted +if (!is(Value == shared)) { (*aa).clear(); } +/** ditto */ +void clear(Value, Key)(shared(Value)[Key] aa) +{ + return (cast(Value[Key])aa).clear(); +} + +/** ditto */ +void clear(Value, Key)(shared(Value)[Key]* aa) +{ + (cast(Value[Key])*aa).clear(); +} + /// @safe unittest { diff --git a/tests/dmd/runnable/testaa3.d b/tests/dmd/runnable/testaa3.d index e94273b7da..1ba165b55e 100644 --- a/tests/dmd/runnable/testaa3.d +++ b/tests/dmd/runnable/testaa3.d @@ -427,6 +427,22 @@ void testShared() assert(2 in iprocesses); } +// https://github.com/dlang/dmd/issues/22556 +void test22556() +{ + static struct RefCounted(T) + { + this(this) {} + } + struct S {} + alias R = RefCounted!S; + shared R[string] foo; + + (cast (R[string]) foo).clear; // WORKS + (cast() foo).clear; // FAILS with 2.112.0, WORKS with 2.111.0 + static assert(!__traits(compiles, foo.clear)); +} + /***************************************************/ // https://github.com/dlang/dmd/issues/22567 @@ -474,4 +490,5 @@ void main() test22354(); testShared(); test22567(); + test22556(); } From 231f5cb01dde181ed5d869a49bde935b3495ca89 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Sun, 1 Mar 2026 15:46:50 +0100 Subject: [PATCH 4/5] Bump Phobos --- runtime/phobos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/phobos b/runtime/phobos index 77ead9f3fe..083e38a009 160000 --- a/runtime/phobos +++ b/runtime/phobos @@ -1 +1 @@ -Subproject commit 77ead9f3fe8cc29cc8b1a7c29f57367a29e0d3b0 +Subproject commit 083e38a00963bc3bac6aa3e16ddc2aeae79af622 From 7c534d7c655052556e10494652a063c858881e6e Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Sun, 1 Mar 2026 15:47:40 +0100 Subject: [PATCH 5/5] [extend changelog entry] --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e345d756c..97ffa97b47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # LDC master #### Big news -- Frontend, druntime and Phobos are at version [2.112.1+](https://dlang.org/changelog/2.112.0.html), incl. new command-line options `-extI`, `-dllimport=externalOnly` and `-edition`. (#4949, #4962, #4988, #5029, #5042, #5046, #5051, #5061, #5067, #5069) +- Frontend, druntime and Phobos are at version [2.112.1+](https://dlang.org/changelog/2.112.0.html), incl. new command-line options `-extI`, `-dllimport=externalOnly` and `-edition`. (#4949, #4962, #4988, #5029, #5042, #5046, #5051, #5061, #5067, #5069, #5076) - Support for [LLVM 21](https://releases.llvm.org/21.1.0/docs/ReleaseNotes.html). The prebuilt packages use v21.1.8. (#4950, #5033) - New prebuilt package for Alpine Linux aarch64 with musl libc, analogous to the existing x86_64 package. (#4943) - **Breaking change for dcompute**: The special `@kernel` UDA is now a function and _**requires**_ parentheses as in `@kernel() void foo(){}`. Optionally you can provide launch dimensions, `@kernel([2,4,8])`, to specify to the compute runtime how the kernel is intended to be launched.