April 10, 2017
https://issues.dlang.org/show_bug.cgi?id=17318

          Issue ID: 17318
           Summary: Delegates allow escaping reference to stack variable
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: hsteoh@quickfur.ath.cx

Code:
------
import std.stdio;

struct S {
        int x;
        void delegate() dg;
        this(int dummy) {
                dg = () {
                        writefln("&x = %#x", &x);
                        x++;
                };
        }
}

S makeS() { return S(1); }

void main() {
        auto s = makeS();
        writefln("&s.x = %#x", &s.x);
        s.dg();
}
------

Output:
------
&s.x = 0x7ffdcc81bfe8
&x = 0x7ffdcc81bfb0
------

The problem here is that dg closes over the member variable x, but the struct resides in stack space.  When makeS() returns, the struct is copied somewhere else but the delegate still points to the old address of x. The increment therefore can potentially corrupt the stack.

Compiling with -dip1000 does not catch this error.  (Note that for some strange reason, I had to comment out the writefln's when compiling with -dip1000; it seems to break some template instantiation code in the compiler and causes the program to fail to link.)

--