D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 7530 - Postblit not called structs returned from an array index expr.
Summary: Postblit not called structs returned from an array index expr.
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 major
Assignee: No Owner
URL:
Keywords: pull, wrong-code
: 7541 (view as issue list)
Depends on:
Blocks:
 
Reported: 2012-02-17 04:15 UTC by Sönke Ludwig
Modified: 2012-05-12 17:25 UTC (History)
3 users (show)

See Also:


Attachments
Reproduction case (981 bytes, application/octet-stream)
2012-02-17 04:15 UTC, Sönke Ludwig
Details

Note You need to log in before you can comment on or make changes to this issue.
Description Sönke Ludwig 2012-02-17 04:15:29 UTC
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.
Comment 1 SomeDude 2012-04-20 01:00:49 UTC
See also issue 7516
Comment 2 Kenji Hara 2012-05-10 19:38:07 UTC
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 Kenji Hara 2012-05-10 19:38:30 UTC
*** Issue 7541 has been marked as a duplicate of this issue. ***
Comment 5 github-bugzilla 2012-05-12 15:07:20 UTC
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