[Issue 19122] New: Multiple destruction of union members
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Fri Jul 27 14:27:22 UTC 2018
https://issues.dlang.org/show_bug.cgi?id=19122
Issue ID: 19122
Summary: Multiple destruction of union members
Product: D
Version: D2
Hardware: x86
OS: Windows
Status: NEW
Keywords: safe
Severity: critical
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: simen.kjaras at gmail.com
@safe unittest {
import std.stdio : writeln;
struct S1 {
int* p;
~this() {
writeln("Writing garbage to random memory: ", p);
//*p = 80085;
}
}
struct S2 {
union {
S1 a;
int b;
}
int index;
this(S1 s) {
a = s;
index = 0;
}
this(int n) {
b = n;
index = 1;
}
}
S2 s = 123456;
}
The above code shows that destructors of union members will be called when the
surrounding struct is destructed. In this case, this leads to reinterpretation
of an int as a pointer, but worse could happen.
If multiple union members have destructors, all of them are called, regardless
of what's currently in the union.
According to 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."
This is clearly not what's happening here. Worse, there's no way to tell the
compiler not to call the destructors, short of hiding the actual types behind
ubyte[]/void[] and casting.
As a crowning achievement, this happens in @safe.
--
More information about the Digitalmars-d-bugs
mailing list