Bug 5657 – Temporary object destruction

Status
RESOLVED
Resolution
FIXED
Severity
critical
Priority
P5
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2011-02-26T23:47:00Z
Last change time
2011-06-04T12:39:25Z
Keywords
patch
Assigned to
nobody
Creator
zan77137
See also
http://d.puremagic.com/issues/show_bug.cgi?id=3516, http://d.puremagic.com/issues/show_bug.cgi?id=4437, http://d.puremagic.com/issues/show_bug.cgi?id=4499

Attachments

IDFilenameSummaryContent-TypeSize
942test.dTest code.application/octet-stream2995
943out.txtTest results by patched dmd.text/plain1622

Comments

Comment #0 by zan77137 — 2011-02-26T23:47:22Z
Following code doesn't call destructor: -------------------------- import std.stdio; struct A { this(int a) {writeln("A.ctor");} ~this() {writeln("A.dtor");} } void main() { A(1); } -------------------------- $ dmd -run main A.ctor -------------------------- I suppose that this bug is related to a series of problems about the temporary object. The outbreak of construction, destruction, postblit are as following table: postblit | destructor constructor -> parameter ... x | o constructor -> return value ... x | x constructor -> variable ... x | o constructor -> no operate ... x | x return value -> parameter ... x | o return value -> return value ... x | x return value -> variable ... x | o return value -> no operate ... x | x variable -> parameter ... o | o variable -> return value ... o | o variable -> variable ... o | o variable -> no operate ... (error) | (error) * When a variable leaves from the scope, destructor is called. * When a variable returns from the function or a variable copies to other variable, postblit is called. Test code is here: http://ideone.com/7ujuN Are these behaviors correct? I feel suspicious... I think these behavior should be determined more strictly.
Comment #1 by zan77137 — 2011-04-01T04:44:14Z
I tested following commit: https://github.com/D-Programming-Language/dmd/commit/e764b3949ae0f95f8fc4d7d2e9114e29fee12493 with following code: http://ideone.com/Yqomf and result is here: http://ideone.com/qfBnx CONCLUTION: Almost! Its behavior is right except a case to ignore without storing away a temporary object produced in a return value to a variable. +--------------+--------------+----------+------------+-------------+ | source | distination | postblit | destructor | correctness | +--------------+--------------+----------+------------+-------------+ | constructor | parameter | x | o | OK | | constructor | return value | x | x | OK | | constructor | variable | x | o | OK | | constructor | no operate | x | o | OK | | return value | parameter | x | o | OK | | return value | return value | x | x | OK | | return value | variable | x | o | OK | | return value | no operate | x | _x_ | _NG_ | | variable | parameter | o | o | OK | | variable | return value | o | o | OK | | variable | variable | o | o | OK | | variable | no operate | (error) | (error) | OK | +--------------+--------------+----------+------------+-------------+ (*) x ... not called / o ... called Minimized case is here: ----- import std.stdio; struct A{ this(int x) {writeln("ctor");} ~this(){writeln("dtor");} } A foo() { return A(1); } void main() { foo(); } ----- $ dmd -run main ctor -----
Comment #2 by k.hara.pg — 2011-04-13T14:52:41Z
Comment #3 by bearophile_hugs — 2011-04-13T16:12:05Z
Code in online paste sites like ideone often gets deleted. So I suggest to avoid their usage in Bugzilla, and to just inline the text or add attaches.
Comment #4 by k.hara.pg — 2011-04-14T01:18:34Z
Created attachment 942 Test code.
Comment #5 by k.hara.pg — 2011-04-14T01:21:22Z
Created attachment 943 Test results by patched dmd. (In reply to comment #3) > Code in online paste sites like ideone often gets deleted. So I suggest to > avoid their usage in Bugzilla, and to just inline the text or add attaches. Thank you for your advice.
Comment #6 by k.hara.pg — 2011-04-16T19:31:55Z
Comment #7 by bugzilla — 2011-04-19T19:28:48Z
The patch fails to call the destructor with the following code: import std.c.stdio; struct S { int x = 1; int bar() { return x; } this(int i) { printf("ctor %p(%d)\n", &this, i); t ~= "a"; } this(this) { printf("postblit %p\n", &this); t ~= "b"; } ~this() { printf("dtor %p\n", &this); t ~= "c"; } static string t; } S bar() { return S(1); } void main() { bar().x += 1; } I'll see if I can come up with a solution.
Comment #8 by bugzilla — 2011-04-21T16:01:40Z
https://github.com/D-Programming-Language/dmd/commit/aef37eb0c8986a508ccf185286465b4cbef8a066 This is a rewrite of Kenji's patch, which was in the right direction but needed to handle a few more cases.
Comment #9 by bugzilla — 2011-06-04T12:39:25Z