Bug 21035 – wrong code when uses struct's methods of .init value

Status
NEW
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2020-07-11T03:01:56Z
Last change time
2024-12-13T19:10:03Z
Keywords
backend, wrong-code
Assigned to
No Owner
Creator
Илья Ярошенко
Moved to GitHub: dmd#17971 →

Comments

Comment #0 by ilyayaroshenko — 2020-07-11T03:01:56Z
struct CNB { string _separator = "-"; char[64] data = '\0'; /// @disable this(this); @safe pure @nogc: /// ref CNB append(scope const(char)[] str) scope return { data[0 .. str.length] = str; return this; } } extern(C) void main() { auto id = CNB .init .append("USD.LIBOR.1D") .data; } $ dmd -inline -betterC -run test.d -betterC is optional
Comment #1 by uplink.coder — 2020-07-14T14:31:36Z
How does the wrong-ness of this code manifest?
Comment #2 by ilyayaroshenko — 2020-07-14T14:32:53Z
(In reply to Stefan Koch from comment #1) > How does the wrong-ness of this code manifest? It fails to execute with exit code -11
Comment #3 by uplink.coder — 2020-07-21T16:00:11Z
What happens is that a `memcpy` fails which seems to be done executing `data[0 .. str.length] = str` why that happens is still under investigation
Comment #4 by kytodragon — 2020-07-26T21:06:11Z
Aren't the ".init" values read only? The append tries to change the "data" member of the initializer, which results in an memory write error.
Comment #5 by ilyayaroshenko — 2020-07-31T07:21:30Z
(In reply to KytoDragon from comment #4) > Aren't the ".init" values read only? The append tries to change the "data" > member of the initializer, which results in an memory write error. D doesn't prohibit to call methods of right hand side values.
Comment #6 by pro.mathias.lang — 2020-07-31T08:38:20Z
Definitely an accepts-invalid. Trying to bind `.init` to a mutable lvalue should not be allowed.
Comment #7 by kinke — 2021-07-13T14:44:52Z
I don't see where this would be invalid - `CNB.init` is a new rvalue (analogous to `CNB()`), `append` returns it as lvalue (allowed IIRC for DotIdExpressions), and then its `data` buffer is copied to the `id` local. Works fine with LDC.
Comment #8 by razvan.nitu1305 — 2023-04-05T11:22:25Z
It seems that the inliner somehow screws up the code. Without -inline code runs successfully.
Comment #9 by robert.schadek — 2024-12-13T19:10:03Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17971 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB