[Issue 19812] New: Lambda over struct member causes dangling reference to out-of-scope struct
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Fri Apr 19 12:21:33 UTC 2019
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 at puremagic.com
Reporter: hsteoh at 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.
--
More information about the Digitalmars-d-bugs
mailing list