Bug 24242 – forward inside templates with -dip1000 causes memory corruption

Status
NEW
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2023-11-13T12:35:05Z
Last change time
2024-12-13T19:31:45Z
Assigned to
No Owner
Creator
Jan Jurzitza
Moved to GitHub: dmd#18198 →

Comments

Comment #0 by d.bugs — 2023-11-13T12:35:05Z
minimal reproduction code: ```d // bug.d struct S() { ulong[] payload; this(ulong[] value) { import core.lifetime; payload = forward!value; } } S!() test() { return S!()([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); } void main() { import std.stdio; auto val = test().payload; writeln("[0]=", val[0], " (should be 0)"); writeln("[1]=", val[1], " (should be 1)"); writeln("[2]=", val[2], " (should be 2)"); writeln("[3]=", val[3], " (should be 3)"); writeln("[4]=", val[4], " (should be 4)"); writeln("[5]=", val[5], " (should be 5)"); writeln("[6]=", val[6], " (should be 6)"); writeln("[7]=", val[7], " (should be 7)"); writeln("[8]=", val[8], " (should be 8)"); writeln("[9]=", val[9], " (should be 9)"); } ``` `dmd -dip1000 -run source/app.d` (also happening with LDC) causes: ``` [0]=0 (should be 0) [1]=1 (should be 1) [2]=140720508484016 (should be 2) [3]=140720508484400 (should be 3) [4]=14 (should be 4) [5]=94655388051378 (should be 5) [6]=94655388051378 (should be 6) [7]=7 (should be 7) [8]=4 (should be 8) [9]=94655388051453 (should be 9) ``` real-world code: assign a `string[]` to mir-core's `Algebraic!(string[])`, the strings will be messed up note that everything works as expected without -dip1000
Comment #1 by d.bugs — 2023-11-13T12:38:47Z
discovered bug conditions: - the variable holding data MUST be created in a separate function, creating it inline, e.g. in the `main` here, doesn't trigger the memory corruption - the struct MUST be templated for this bug to occur (otherwise it works as expected)
Comment #2 by alphaglosined — 2023-11-13T13:03:11Z
Swapping forward for move, stops the bug. Removing forward altogether also stops it. Going through the alias sequence inside of forward appears to prevent the compiler from being able to see that the function parameter value is used, and therefore can go on the stack.
Comment #3 by kinke — 2023-11-13T18:20:59Z
The problem appears to be that the compiler wrongly infers the `ulong[] value` ctor param as being `scope` (if the struct/ctor is templated). That then enables a (frontend) optimization, passing the array literal on the stack.
Comment #4 by kinke — 2023-11-13T18:22:36Z
(In reply to kinke from comment #3) > passing the array literal on the stack Well, allocating the array literal on the caller's stack and passing a slice to it.
Comment #5 by mail — 2024-08-21T20:02:12Z
Still present with dmd-2.109.1
Comment #6 by robert.schadek — 2024-12-13T19:31:45Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18198 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB