Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
21 changes: 21 additions & 0 deletions dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down
48 changes: 24 additions & 24 deletions runtime/druntime/src/core/sys/posix/netinet/in_.d
Original file line number Diff line number Diff line change
Expand Up @@ -547,77 +547,77 @@ 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 &&
(cast(uint32_t*) addr)[2] == 0 &&
(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 &&
(cast(uint32_t*) addr)[2] == 0 &&
(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 &&
(cast(uint32_t*) addr)[2] == 0 &&
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;
Expand Down Expand Up @@ -670,45 +670,45 @@ 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 &&
(cast(uint32_t*) addr)[2] == 0 &&
(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 &&
(cast(uint32_t*) addr)[2] == 0 &&
(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 &&
Expand All @@ -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;
Expand Down
14 changes: 14 additions & 0 deletions runtime/druntime/src/object.d
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
2 changes: 1 addition & 1 deletion runtime/phobos
35 changes: 35 additions & 0 deletions tests/dmd/runnable/testaa3.d
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -456,4 +489,6 @@ void main()
test21066();
test22354();
testShared();
test22567();
test22556();
}