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