October 04, 2020 [Issue 21291] New: Array literal that escapes scope is allocated on stack | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=21291 Issue ID: 21291 Summary: Array literal that escapes scope is allocated on stack Product: D Version: D2 Hardware: All OS: All Status: NEW Keywords: accepts-invalid, safe Severity: regression Priority: P1 Component: dmd Assignee: nobody@puremagic.com Reporter: dkorpel@live.nl I got memory corruption in @safe code because an array literal that was expected to be allocated by the Garbage Collector turned out to be put on the stack, as shown by the following @nogc code (must be compiled with -dip1000): ``` @safe: @nogc: struct S { int[] arr; static S create(int[] arr) pure @nogc { return S(arr); } } S createS() { // This should be GC allocated, but the compiler allows this // in this @nogc function and puts it on the stack! return S.create([0xABCD, 0xBCDE]); } void stompStack() { // set stack memory to reveal dangling stack pointers ubyte[128] stackMemory = 0x77; } extern(C) void main() { auto s = createS(); assert(s.arr[0] == 0xABCD); // likely still passes stompStack(); assert(s.arr[0] == 0xABCD); // likely does not pass } ``` It seems to be important that the array literal is in a pure static member function, though it might be possible to reduce the example further. This is introduced in DMD version 2.092 most likely because of https://github.com/dlang/dmd/pull/11039 though I don't think the wrong code is in that PR's code. I suspect that somewhere else in the compiler the 'return scope' flag is wrongfully inferred. -- |
Copyright © 1999-2021 by the D Language Foundation