Created attachment 1076 [details] 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.
See also issue 7516
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); }
*** Issue 7541 has been marked as a duplicate of this issue. ***
https://github.com/D-Programming-Language/dmd/pull/939
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/e72fa541029d2c09daa992e78f2adf33d1bd8045 fix Issue 7530 - Postblit not called structs returned from an array index expr. https://github.com/D-Programming-Language/dmd/commit/481f5585639de6dbf94e6b80510f767dc5e81b64 Merge pull request #939 from 9rnsr/fix_postblit Issue 7506 & 7530 more postblit fixes