Skip to content

Commit 0edef23

Browse files
Variant segfault (#10697)
* Reference correct issue for test * Variant: Fix Segfault on adding in wrapped AA
1 parent b57f75d commit 0edef23

File tree

1 file changed

+38
-3
lines changed

1 file changed

+38
-3
lines changed

std/variant.d

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,14 @@ public:
850850
*/
851851
@property inout(T) get(T)() inout
852852
{
853-
inout(T) result = void;
853+
static union SupressDestructor {
854+
T val;
855+
}
856+
857+
/* If this function fails and it throws, copy elision will not run and the destructor might be called.
858+
* But since this value is void initialized, this is undesireable.
859+
*/
860+
inout(SupressDestructor) result = void;
854861
static if (is(T == shared))
855862
alias R = shared Unqual!T;
856863
else
@@ -861,7 +868,7 @@ public:
861868
{
862869
throw new VariantException(type, typeid(T));
863870
}
864-
return result;
871+
return result.val;
865872
}
866873

867874
/// Ditto
@@ -3256,7 +3263,7 @@ if (isAlgebraic!VariantType && Handler.length > 0)
32563263
auto v = Variant(aa); // compile error
32573264
}
32583265

3259-
// https://issues.dlang.org/show_bug.cgi?id=8195
3266+
// https://github.com/dlang/phobos/issues/9585
32603267
// Verify that alignment is respected
32613268
@safe unittest
32623269
{
@@ -3268,3 +3275,31 @@ if (isAlgebraic!VariantType && Handler.length > 0)
32683275
enum FP_SIZE = (int function()).sizeof;
32693276
static assert(AFoo1.sizeof >= double.sizeof + FP_SIZE);
32703277
}
3278+
3279+
// https://github.com/dlang/phobos/issues/10518
3280+
@system unittest
3281+
{
3282+
import std.exception : assertThrown;
3283+
3284+
struct Huge {
3285+
real a, b, c, d, e, f, g;
3286+
}
3287+
Huge h = {1,1,1,1,1,1,1};
3288+
Variant variant = Variant([
3289+
"one": Variant(1),
3290+
]);
3291+
// Testing that this doesn't segfault. Future work might make enable this
3292+
assertThrown!VariantException(variant["three"] = 3);
3293+
assertThrown!VariantException(variant["four"] = Variant(4));
3294+
/* Storing huge works too, value will moved to the heap
3295+
* Testing this as a regression test here as the AA handling code is still somewhat brittle and might add changes
3296+
* that depend payload size in the future
3297+
*/
3298+
assertThrown!VariantException(variant["huge"] = Variant(h));
3299+
/+
3300+
assert(variant["one"] == Variant(1));
3301+
assert(variant["three"] == Variant(3));
3302+
assert(variant["three"] == 3);
3303+
assert(variant["huge"] == Variant(h));
3304+
+/
3305+
}

0 commit comments

Comments
 (0)