From c4a97964727a7393ad929e41dc7929fcae9bb94e Mon Sep 17 00:00:00 2001 From: Rainer Date: Tue, 18 Feb 2025 13:51:06 +0100 Subject: [PATCH] add test case from #20853 --- druntime/test/aa/src/test_aa.d | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/druntime/test/aa/src/test_aa.d b/druntime/test/aa/src/test_aa.d index 5ccb14be17..5c3ba05d83 100644 --- a/druntime/test/aa/src/test_aa.d +++ b/druntime/test/aa/src/test_aa.d @@ -40,6 +40,7 @@ void main() testZeroSizedValue(); testTombstonePurging(); testClear(); + testTypeInfoCollect(); } void testKeysValues1() @@ -905,3 +906,44 @@ void testClear() assert(aa.length == 1); assert(aa[5] == 6); } + +// https://github.com/dlang/dmd/issues/17503 +void testTypeInfoCollect() +{ + import core.memory; + + static struct S + { + int x; + ~this() {} + } + + static struct AAHolder + { + S[int] aa; + } + + static S* getBadS() + { + auto aaholder = new AAHolder; + aaholder.aa[0] = S(); + auto s = 0 in aaholder.aa; // keep a pointer to the entry + GC.free(aaholder); // but not a pointer to the AA. + return s; + } + + static void stackStomp() + { + import core.stdc.string : memset; + ubyte[4 * 4096] x; + memset(x.ptr, 0, x.sizeof); + } + + auto s = getBadS(); + stackStomp(); // destroy any stale references to the AA or s except in the current frame; + GC.collect(); // BUG: this used to invalidate the fake type info, should no longer do this. + foreach(i; 0 .. 1000) // try to reallocate the freed type info + auto p = new void*[1]; + s = null; // clear any reference to the entry + GC.collect(); // used to segfault. +}