digitalmars.D.bugs - [Issue 23440] New: closure over typesafe variadic or scope array
- d-bugmail puremagic.com (54/54) Oct 27 2022 https://issues.dlang.org/show_bug.cgi?id=23440
https://issues.dlang.org/show_bug.cgi?id=23440 Issue ID: 23440 Summary: closure over typesafe variadic or scope array passes safe though leads to stack corruption Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: destructionator gmail.com Consider the following: ``` void delegate() safe foo(int[] stuff...) safe { // adding `scope` to `stuff` makes no difference return () { assert(stuff == [1,2,3]); foreach(item; stuff) {} }; } void delegate() safe helper() safe { return foo(1, 2, 3); } void bar() safe { int[2048] pwned; // just to smash the stack } void main() safe { auto dg = helper(); bar(); dg(); } ``` Note how everything is ` safe`, though a dmd master build (from mid October), including the -dip1000 switch, fails to catch the problem here. The call to `foo` does a stack allocation, which makes enough sense, it normally does for a typesafe variadic and that's fine. The receiving function doesn't know the pedigree of the array. So it should assume `scope`. This PR merged recently does this: https://github.com/dlang/dmd/pull/14324 which is probably why adding the keyword here doesn't change anything; it is already implicitly scope. However, the delegate is able to capture it anyway, without any error being reported. The `stuff` variable itself is captured on the heap closure, but the `stuff.ptr` is not, which is why the assert is liable to fail. In some cases, you do pass an infinite lifetime array to a typesafe variadic, but the function just doesn't know, so it has to be more conservative. It should prohibit capturing it and extending the lifetime - somehow - without the programmer's intervention to pass the safe checks. bugzilla suggested this: https://issues.dlang.org/show_bug.cgi?id=5212 as a duplicate and they have a similar root cause but not quite the same, as my case launders it through a closure instead of a direct assignment. --
Oct 27 2022