Fix Bugzilla 24773: Don't invoke destructors on uninitialized elements in stable sort

Uses a regular initialized temporary array when sorting elements with an elaborate assignment to avoid undefined behavior when destructors, postblits or copy constructors are invoked during the array assignment.
This commit is contained in:
Sönke Ludwig 2024-09-20 11:07:22 +02:00 committed by The Dlang Bot
parent b3a9736480
commit 2168becf74

View file

@ -2385,7 +2385,11 @@ private template TimSortImpl(alias pred, R)
size_t stackLen = 0;
// Allocate temporary memory if not provided by user
if (temp.length < minTemp) temp = () @trusted { return uninitializedArray!(T[])(minTemp); }();
if (temp.length < minTemp)
{
static if (hasElaborateAssign!T) temp = new T[](minTemp);
else temp = () @trusted { return uninitializedArray!(T[])(minTemp); }();
}
for (size_t i = 0; i < range.length; )
{
@ -3076,6 +3080,20 @@ private template TimSortImpl(alias pred, R)
array.sort!("a < b", SwapStrategy.stable);
}
// https://issues.dlang.org/show_bug.cgi?id=24773
@safe unittest
{
static struct S
{
int i = 42;
~this() { assert(i == 42); }
}
auto array = new S[](400);
array.sort!((a, b) => false, SwapStrategy.stable);
}
// schwartzSort
/**
Alternative sorting method that should be used when comparing keys involves an