Skip to content

Commit 2168bec

Browse files
s-ludwigdlang-bot
authored andcommitted
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.
1 parent b3a9736 commit 2168bec

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

std/algorithm/sorting.d

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2385,7 +2385,11 @@ private template TimSortImpl(alias pred, R)
23852385
size_t stackLen = 0;
23862386

23872387
// Allocate temporary memory if not provided by user
2388-
if (temp.length < minTemp) temp = () @trusted { return uninitializedArray!(T[])(minTemp); }();
2388+
if (temp.length < minTemp)
2389+
{
2390+
static if (hasElaborateAssign!T) temp = new T[](minTemp);
2391+
else temp = () @trusted { return uninitializedArray!(T[])(minTemp); }();
2392+
}
23892393

23902394
for (size_t i = 0; i < range.length; )
23912395
{
@@ -3076,6 +3080,20 @@ private template TimSortImpl(alias pred, R)
30763080
array.sort!("a < b", SwapStrategy.stable);
30773081
}
30783082

3083+
// https://issues.dlang.org/show_bug.cgi?id=24773
3084+
@safe unittest
3085+
{
3086+
static struct S
3087+
{
3088+
int i = 42;
3089+
~this() { assert(i == 42); }
3090+
}
3091+
3092+
auto array = new S[](400);
3093+
array.sort!((a, b) => false, SwapStrategy.stable);
3094+
}
3095+
3096+
30793097
// schwartzSort
30803098
/**
30813099
Alternative sorting method that should be used when comparing keys involves an

0 commit comments

Comments
 (0)