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. diff --git a/dmd/expressionsem.d b/dmd/expressionsem.d index 137e6e572b..262d332351 100644 --- a/dmd/expressionsem.d +++ b/dmd/expressionsem.d @@ -18912,6 +18912,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) { @@ -18962,6 +18982,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/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; diff --git a/runtime/druntime/src/object.d b/runtime/druntime/src/object.d index 23e59ce017..49d380108b 100644 --- a/runtime/druntime/src/object.d +++ b/runtime/druntime/src/object.d @@ -3034,16 +3034,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/runtime/phobos b/runtime/phobos index 77ead9f3fe..083e38a009 160000 --- a/runtime/phobos +++ b/runtime/phobos @@ -1 +1 @@ -Subproject commit 77ead9f3fe8cc29cc8b1a7c29f57367a29e0d3b0 +Subproject commit 083e38a00963bc3bac6aa3e16ddc2aeae79af622 diff --git a/tests/dmd/runnable/testaa3.d b/tests/dmd/runnable/testaa3.d index 53a0e8bb86..1ba165b55e 100644 --- a/tests/dmd/runnable/testaa3.d +++ b/tests/dmd/runnable/testaa3.d @@ -427,6 +427,39 @@ 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 +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() @@ -456,4 +489,6 @@ void main() test21066(); test22354(); testShared(); + test22567(); + test22556(); }