Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 5a6b41f

Browse files
Geod24dlang-bot
authored andcommitted
Fix 21442: Do not call shrink for AA in finalizers
This can easily lead to InvalidMemoryOperation (e.g. in Vibe.d).
1 parent 8180486 commit 5a6b41f

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

src/rt/aaA.d

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,9 @@ extern (C) bool _aaDelX(AA aa, scope const TypeInfo keyti, scope const void* pke
628628
p.entry = null;
629629

630630
++aa.deleted;
631-
if (aa.length * SHRINK_DEN < aa.dim * SHRINK_NUM)
631+
// `shrink` reallocates, and allocating from a finalizer leads to
632+
// InvalidMemoryError: https://issues.dlang.org/show_bug.cgi?id=21442
633+
if (aa.length * SHRINK_DEN < aa.dim * SHRINK_NUM && !GC.inFinalizer())
632634
aa.shrink(keyti);
633635

634636
return true;

test/aa/src/test_aa.d

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ void main()
3131
issue16974();
3232
issue18071();
3333
issue20440();
34+
issue21442();
3435
testIterationWithConst();
3536
testStructArrayKey();
3637
miscTests1();
@@ -709,6 +710,40 @@ void issue20440() @safe
709710
assert(aa[S(1)] == S(2));
710711
}
711712

713+
///
714+
void issue21442()
715+
{
716+
import core.memory;
717+
718+
size_t[size_t] glob;
719+
720+
class Foo
721+
{
722+
size_t count;
723+
724+
this (size_t entries) @safe
725+
{
726+
this.count = entries;
727+
foreach (idx; 0 .. entries)
728+
glob[idx] = idx;
729+
}
730+
731+
~this () @safe
732+
{
733+
foreach (idx; 0 .. this.count)
734+
glob.remove(idx);
735+
}
736+
}
737+
738+
void bar () @safe
739+
{
740+
Foo f = new Foo(16);
741+
}
742+
743+
bar();
744+
GC.collect(); // Needs to happen from a GC collection
745+
}
746+
712747
/// Verify iteration with const.
713748
void testIterationWithConst()
714749
{

0 commit comments

Comments
 (0)