Bug 19774 – wrong code caused by opIndex

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2019-03-30T01:57:53Z
Last change time
2019-04-29T09:20:58Z
Keywords
pull, wrong-code
Assigned to
No Owner
Creator
Илья Ярошенко

Comments

Comment #0 by ilyayaroshenko — 2019-03-30T01:57:53Z
alias AliasSeq(T...) = T; struct C(T) { T* ptr; ~this() { ptr = null; } auto bar() const { return C!(const T)(ptr); } auto opIndex(A...)(A a) { return this; } auto foo() const { alias A = AliasSeq!(); A a; return this.bar()[a]; /+ If we replace the line above with the following line then the code would work well +/ //return this.bar.opIndex(a); } } void main() { const d = C!double(new double); auto c = d.foo; // Fails if `this.bar[a];` is used // and pass if `this.bar.opIndex(a)` is used. // Expected behaviour: pass for both cases. assert(c.ptr !is null); }
Comment #1 by ag0aep6g — 2019-04-05T13:09:04Z
Slighlty more reduced: ---- C bar() { return C(42); } C foo() { return bar()[1]; } struct C { int x; ~this() { x = 0; } C opIndex(int a) { return this; } } void main() { auto c = foo(); assert(c.x == 42); /* fails; should pass */ } ----
Comment #2 by ilyayaroshenko — 2019-04-07T05:52:45Z
Thank you, the reduced variant is much more generalised, looks more dangerous.
Comment #3 by ilyayaroshenko — 2019-04-08T11:29:21Z
Comment #4 by john.loughran.colvin — 2019-04-08T11:58:15Z
Changed to regression because it worked up to and including 2.066.0
Comment #5 by mihails.strasuns — 2019-04-08T14:05:55Z
Quick check with -vcg-ast shows that for opIndex different intermediate AST gets generated compared to regular function call: C foo() { C __dop3 = bar(); return __dop3.opIndex(1); } vs C foo() { return ((C __tmpfordtor3 = bar();) , __tmpfordtor3).zzz(); }
Comment #6 by mihails.strasuns — 2019-04-08T14:08:02Z
Interesting that expanded code works fine when supplied manually.
Comment #7 by johanengelen — 2019-04-08T21:57:09Z
fyi with LDC: the bug is that `return bar()[1];` first calls the destructor on the temporary returned by `bar()`, and _after_ that calls opIndex. Clearly the order of those calls should be reversed.
Comment #8 by dlang-bot — 2019-04-25T13:34:25Z
@RazvanN7 created dlang/dmd pull request #9696 "Fix Issue 19774 - wrong code caused by opIndex" fixing this issue: - Fix Issue 19774 - wrong code caused by opIndex https://github.com/dlang/dmd/pull/9696
Comment #9 by dlang-bot — 2019-04-26T10:46:46Z
dlang/dmd pull request #9696 "Fix Issue 19774 - wrong code caused by opIndex" was merged into stable: - 92b0a9967f59c0de24c2a2a3f9ae9e9103a514af by RazvanN7: Fix Issue 19774 - wrong code caused by opIndex https://github.com/dlang/dmd/pull/9696
Comment #10 by dlang-bot — 2019-04-29T09:20:58Z
dlang/dmd pull request #9725 "Followup 19774" was merged into stable: - b8d4101ae586d993aaf40e4eaf5f2708b31c3f8e by RazvanN7: Follow up for Issue 19774 - fix opDollar https://github.com/dlang/dmd/pull/9725