From 2e69efed7eae065f8b76fac2f1465fbf8fd7e977 Mon Sep 17 00:00:00 2001 From: k-hara Date: Wed, 31 Dec 2014 22:41:41 +0900 Subject: [PATCH] fix Issue 13871 - Segmentation fault from std/variant.d:609 A variant to variant assignment is specially handled by OpID.copyOut. Therefore, destroying original value before the copyOut call is problematic. --- std/variant.d | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/std/variant.d b/std/variant.d index c625147dd..6d8cb236c 100644 --- a/std/variant.d +++ b/std/variant.d @@ -605,8 +605,6 @@ public: static assert(allowed!(T), "Cannot store a " ~ T.stringof ~ " in a " ~ VariantN.stringof ~ ". Valid types are " ~ AllowedTypes.stringof); - // Assignment should destruct previous value - fptr(OpID.destruct, &store, null); static if (is(T : VariantN)) { @@ -620,6 +618,9 @@ public: } else { + // Assignment should destruct previous value + fptr(OpID.destruct, &store, null); + static if (T.sizeof <= size) { // If T is a class we're only copying the reference, so it @@ -2514,6 +2515,17 @@ unittest auto a = appender!(T[]); } +unittest +{ + // Bugzilla 13871 + alias A = Algebraic!(int, typeof(null)); + static struct B { A value; } + alias C = std.variant.Algebraic!B; + + C var; + var = C(B()); +} + unittest { // Make sure Variant can handle types with opDispatch but no length field.