[Issue 20135] New: Tuple assignment incorrectly calls destructor on freshly postblitted structs
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Sat Aug 17 15:54:41 UTC 2019
https://issues.dlang.org/show_bug.cgi?id=20135
Issue ID: 20135
Summary: Tuple assignment incorrectly calls destructor on
freshly postblitted structs
Product: D
Version: D2
Hardware: x86_64
OS: Linux
Status: NEW
Severity: normal
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: destructionator at gmail.com
Tested on dmd.2.088.0-beta.1, but also present on older versions I tried, so I
don't think it is new.
Consider the following code:
--------------
import std.stdio;
struct Test {
string s;
this(string s) { this.s = s; }
this(this) { this.s ~= " postblitted"; }
~this() { this.s = "destroyed"; }
}
struct Wrapper {
Test s;
}
void bug(Ranges...)(Ranges _ranges) {
auto ranges = _ranges;
// notice how in the original, we can still see the "1" in there
writeln(_ranges[0]);
// but in the copy made from the tuple assignment above, the destructor
// has apparently been run on the new object, starts with "destroyed"
writeln(ranges[0]);
assert(ranges[0].s.s[0 .. "destroyed".length] != "destroyed"); // fails
// same thing happens to ranges[1] btw
}
void main()
{
Wrapper a = Wrapper(Test("1"));
Wrapper b = Wrapper(Test("2"));
bug(a, b);
}
------------------
The `ranges = _ranges` does everything right - copies the bits, calls the
postblit.... then immediately calls the destructor on the freshly postblitted
object, leaving s == "destroyed". (then the writeln adds a bunch of other
postblits to it, but once it is destroyed, the relevant data is lost and we are
in bug city.)
This is reduced from a case an IRC user brought up trying to lockstep over some
phobos Files.
--
More information about the Digitalmars-d-bugs
mailing list