Bug 20956 – [DIP1000] @safe defeated by closure capturing ref parameter

Status
NEW
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2020-06-19T06:13:49Z
Last change time
2024-12-13T19:09:26Z
Keywords
industry, pull, safe
Assigned to
No Owner
Creator
Mathias LANG
See also
https://issues.dlang.org/show_bug.cgi?id=8538
Moved to GitHub: dmd#17964 →

Comments

Comment #0 by pro.mathias.lang — 2020-06-19T06:13:49Z
``` import std.stdio; struct Container { int[10] arr; } void main () @safe { auto dg = getDg(42); stompStack(); dg(); } auto getDg (int val) @safe { Container c; c.arr[] = val; return forwardDg(c); } auto forwardDg (scope ref Container c) @safe { return () => writeln(c); } void stompStack () @safe { int[256] oops = int.max; } ``` This should print: ``` Container([42, 42, 42, 42, 42, 42, 42, 42, 42, 42]) ``` Instead it prints: ``` Container([2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647]) ``` Compiled with `-preview=dip1000`. I would have tried `-preview=dip1021` if it didn't SEGV the compiler. ``` % dmd | head -n 1 DMD64 D Compiler v2.092.1 ```
Comment #1 by dkorpel — 2022-01-04T11:52:46Z
Reduced a bit more: ``` @safe: alias DG = void delegate() @safe; void main() { DG dg = getDg(42); stompStack(); dg(); } DG getDg(int val) { return forwardDg(val); } DG forwardDg(ref int c) { return () {assert(c == 42);}; } void stompStack() { int[256] oops = int.max; } ``` Also, it fails both with or without -dip1000. I think closing over a ref parameter should be an error (at least in `@safe` code), because it's really hard for `forwardDg` to create a closure including the stack frame of `getDg`: it has to be done at runtime, since you can't statically know where the `ref` parameter came from.
Comment #2 by dlang-bot — 2022-08-12T21:01:18Z
@WalterBright updated dlang/dmd pull request #14364 "fix Issue 20956 - [DIP1000] @safe defeated by closure capturing ref p…" fixing this issue: - fix Issue 20956 - [DIP1000] @safe defeated by closure capturing ref parameter https://github.com/dlang/dmd/pull/14364
Comment #3 by robert.schadek — 2024-12-13T19:09:26Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17964 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB