digitalmars.D.bugs - [Issue 19812] New: Lambda over struct member causes dangling
- d-bugmail puremagic.com (64/64) Apr 19 2019 https://issues.dlang.org/show_bug.cgi?id=19812
https://issues.dlang.org/show_bug.cgi?id=19812 Issue ID: 19812 Summary: Lambda over struct member causes dangling reference to out-of-scope struct Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: hsteoh quickfur.ath.cx Code: ------ import std.algorithm : filter, map; import std.stdio; struct S { bool flag; auto method() { return [ 1 ].filter!(e => flag); } } void main() safe { auto s = S(true); writeln(s.method); auto arr = [ s ]; writeln(arr[0].method); auto mappedArray = arr.map!(e => e.method); writeln(mappedArray.front); writeln(mappedArray); } ------ Expected output: [1] [1] [1] [[1]] Actual output: [1] [1] [1] [[]] Changing method() to the following makes the problem go away: ------ auto method() { auto _flag = flag; return [ 1 ].filter!(e => _flag); } ------ Changing flag to an integer value and printing the value reveals that in the last writeln, the value has been corrupted into a garbage value. It appears that the lambda incorrectly closes over a temporary copy of the struct (the argument of map as a local variable) that has gone out of scope by the time the lambda is executed. Explicitly copying .flag into a local variable in method() appears to cause it to be allocated on the heap, as it ought to be. Compiling with -dip25 -dip1000 fails to catch this problem even though main() is marked safe. Expected behaviour: the compiler should either reject this code (at the very least under -dip25 -dip1000, because the lambda carries a reference to a variable past its scope), or it should do the correct thing by copying the closed-over variable into a heap allocation. --
Apr 19 2019