Bug 19079 – Destructors not called in named unions
Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2018-07-12T08:53:59Z
Last change time
2018-07-30T06:15:22Z
Keywords
spec
Assigned to
No Owner
Creator
Simen Kjaeraas
Comments
Comment #0 by simen.kjaras — 2018-07-12T08:53:59Z
When a type T with a destructor is placed in a named union, T's destructor is not called when the union goes out of scope or is destroyed with destroy().
https://dlang.org/spec/struct.html states that 'Unions may not have fields that have destructors', so this may be undefined behavior.
struct S { ~this() { throw new Exception(""); } }
struct S1 { union { S s; } }
union U { S s; }
struct S2 { U u; }
unittest {
import std.exception;
// Correct behavior:
assertThrown((){ S s; }());
assertThrown((){ S s; destroy(s); }());
assertThrown((){ S1 s1; }());
assertThrown((){ S1 s1; destroy(s1); }());
// Incorrect behavior:
assertNotThrown((){ U u; }());
assertNotThrown((){ U u; destroy(u); }());
assertNotThrown((){ S2 s2; }());
assertNotThrown((){ S2 s2; destroy(s2); }());
}
Comment #1 by simen.kjaras — 2018-07-30T06:14:58Z
As mentioned in issue 19122, and quoting from https://github.com/dlang/dmd/pull/5830:
"Unrestricted unions can have fields that have destructors, postblits, or invariants. It's up to the user to call them correctly, the compiler does not automatically generate calls to them."
So this is actually expected behavior in unions, and the spec is wrong.