Skip to content

Commit

Permalink
Fix Bugzilla 24773: Don't invoke destructors on uninitialized element…
Browse files Browse the repository at this point in the history
…s 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.
  • Loading branch information
s-ludwig authored and dlang-bot committed Sep 20, 2024
1 parent b3a9736 commit 2168bec
Showing 1 changed file with 19 additions and 1 deletion.
20 changes: 19 additions & 1 deletion std/algorithm/sorting.d
Original file line number Diff line number Diff line change
Expand Up @@ -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; )
{
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 2168bec

Please sign in to comment.