Bug 20135 – Tuple assignment incorrectly calls destructor on freshly postblitted structs

Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2019-08-17T15:54:41Z
Last change time
2023-06-27T02:55:30Z
Assigned to
No Owner
Creator
Adam D. Ruppe

Comments

Comment #0 by destructionator — 2019-08-17T15:54:41Z
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.
Comment #1 by destructionator — 2019-08-17T16:53:33Z
Specifically I'd like to thank Nick Rozinsky on IRC for being the one who provided the initial report to me.
Comment #2 by boris2.9 — 2023-06-27T02:55:30Z
*** This issue has been marked as a duplicate of issue 24010 ***