Bug 7516 – Postblit not called for structs returned from a ternary operator

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-02-16T03:28:00Z
Last change time
2017-08-02T08:07:13Z
Keywords
pull, wrong-code
Assigned to
nobody
Creator
sludwig

Attachments

IDFilenameSummaryContent-TypeSize
1075bug_refcount.dReproduction caseapplication/octet-stream919

Comments

Comment #0 by sludwig — 2012-02-16T03:28:54Z
Created attachment 1075 Reproduction case Attached is a small example with a pseudo RefCount struct. Running with the ternary operator enabled "dmd -version=BUG -run" yields: --- 1st pass POS1: 613D80 -100 CREATE 18FDFC 1 DESTROY 18FDE0 -100 IN DESTROY 18FDE0 -100 OUT POS2: 613D80 1 DESTROY 18FE0C 1 IN <- destroys the object although the static variable DESTROY 18FE0C -100 OUT in func() should still hold a reference 2nd pass POS1: 613D80 0 <- the static variable now references a destroyed POS2: 613D80 0 object DESTROY 18FE0C 0 IN DESTROY 18FE0C -1 OUT --- The line "return cnt.cnt ? cnt : cnt;" fails to call the struct's postblit and causes the returned object to get destroyed. running with "dmd -run" yields the expected output: --- 1st pass POS1: 533D80 -100 CREATE 18FDFC 1 DESTROY 18FDE0 -100 IN DESTROY 18FDE0 -100 OUT POS2: 533D80 1 COPY 18FE0C 2 <- correctly copied on return DESTROY 18FE0C 2 IN DESTROY 18FE0C 1 OUT 2nd pass POS1: 533D80 1 POS2: 533D80 1 COPY 18FE0C 2 DESTROY 18FE0C 2 IN DESTROY 18FE0C 1 OUT <- the static reference is still there --- "return cnt;" will correctly call the postblit constructor. Occurs for DMD 2.058 (2.57 fails for both cases)
Comment #1 by lovelydear — 2012-04-20T00:43:05Z
See also issue 7506
Comment #2 by lovelydear — 2012-04-20T01:01:16Z
See also issue 7530
Comment #3 by k.hara.pg — 2012-05-10T22:56:59Z
Test cases: void main() { static struct S { int val; this(int n) { val = n; } this(this) { val *= 3; } } // cond ? lvalue : lvalue S foo(bool f) { auto s1 = S(1), s2 = S(2); return f ? s1 : s2; } auto s1 = foo(true); assert(s1.val == 3); auto s2 = foo(false); assert(s2.val == 6); // cond ? rvalue : rvalue S bar(bool f) { return f ? S(1) : S(2); } auto s3 = bar(true); assert(s3.val == 1); auto s4 = bar(false); assert(s4.val == 2); // cond ? lvalue : rvalue S baz(bool f) { auto s1 = S(1); return f ? s1 : S(2); } auto s5 = baz(true); assert(s5.val == 3); auto s6 = baz(false); assert(s6.val == 2); }
Comment #4 by k.hara.pg — 2012-05-10T23:05:16Z
*** Issue 7130 has been marked as a duplicate of this issue. ***
Comment #5 by briancschott — 2014-05-05T00:28:50Z
Still fails with dmd 2.065
Comment #6 by k.hara.pg — 2015-07-07T16:46:09Z
Comment #7 by github-bugzilla — 2016-02-05T06:59:00Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/094b358ba1c5ecd6708ccd82660f44462cd06314 fix Issue 7516 - Postblit not called for structs returned from a ternary operator https://github.com/D-Programming-Language/dmd/commit/1ea699106e924387269681d4b54f2802a25e24d3 Merge pull request #4805 from 9rnsr/fix7516 Issue 7516 - Postblit not called for structs returned from a ternary operator
Comment #8 by github-bugzilla — 2017-08-02T08:07:13Z
Commit pushed to dmd-cxx at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/3f497efad06f609476b4852482f8ecb24a4d33fd Issue 7516 - Postblit not called for structs returned from a ternary operator