Created attachment 1076
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
CREATE 18FE34 1
COPY 443FD0 2
DESTROY 18FE34 2 IN
DESTROY 18FE34 1 OUT
POS2: 443FD0 1
DESTROY 18FE5C 1 IN <- destroys the object although the static
DESTROY 18FE5C -100 OUT array should still hold a reference
2nd pass
POS1: 443FD0 0 <- the static variable now references an
POS2: 443FD0 0 already destroyed object
DESTROY 18FE5C 0 IN
DESTROY 18FE5C -1 OUT
---
The line "return cnt[0];" fails to call the struct's postblit and
causes the returned object to get destroyed as the ref count goes to
zero.
running with "dmd -run" yields the expected output:
---
1st pass
CREATE 18FE34 1
COPY 4B3FD0 2
DESTROY 18FE34 2 IN
DESTROY 18FE34 1 OUT
POS2: 4B3FD0 1
COPY 18FE5C 2 <- correctly copied on return
DESTROY 18FE5C 2 IN
DESTROY 18FE5C 1 OUT
2nd pass
POS1: 4B3FD0 1
POS2: 4B3FD0 1
COPY 18FE5C 2 <- correctly copied on return
DESTROY 18FE5C 2 IN
DESTROY 18FE5C 1 OUT <- the static reference is still there
---
"auto ret = cnt[0]; return ret;" will correctly call the postblit constructor.
Occurs at least in DMD 2.058 and 2.057.
Comment #1 by lovelydear — 2012-04-20T01:00:49Z
See also issue 7516
Comment #2 by k.hara.pg — 2012-05-10T19:38:07Z
Reduced test case:
void main()
{
static struct S
{
int val;
this(int n) { val = n; }
this(this) { val *= 3; }
}
S[] sa = new S[](1);
sa[0].val = 1;
S foo()
{
return sa[0]; // postblit should run
}
auto s = foo();
assert(s.val == 3);
}
Comment #3 by k.hara.pg — 2012-05-10T19:38:30Z
*** Issue 7541 has been marked as a duplicate of this issue. ***