Bug 19175 – @safe code can escape local array references

Status
RESOLVED
Resolution
WORKSFORME
Severity
critical
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-08-17T07:12:40Z
Last change time
2019-08-22T10:12:42Z
Keywords
accepts-invalid, safe
Assigned to
No Owner
Creator
Peter Alexander

Comments

Comment #0 by peter.alexander.au — 2018-08-17T07:12:40Z
-------- import std.algorithm, std.stdio; @safe: auto foo() { int[6] xs = [0, 1, 2, 3, 4, 5]; return xs[].map!(x => x); } void main() { writeln(foo()); } -------- Observed: this compiles and (for me) prints [0, 0, -2132056872, 22008, 0, 0]. Expected: fail to compile with error about the escaped local reference.
Comment #1 by issues.dlang — 2018-08-17T07:43:54Z
This is a duplicate of https://issues.dlang.org/show_bug.cgi?id=8838, which was closed as fixed based on the fact that -dip1000 fixes the problem. It's still quite broken without -dip1000 though.
Comment #2 by peter.alexander.au — 2018-08-17T10:50:25Z
It is still broken with -dip1000 https://run.dlang.io/is/gJi2Fa
Comment #3 by dfj1esp02 — 2018-08-21T13:07:34Z
Reduced: @safe: struct A(alias fun) { int[] r; this(int[] q){r=q;} } template m(alias fun) { auto m(int[] r) { return A!fun(r); } } auto foo() { int[6] xs = [0, 1, 2, 3, 4, 5]; return xs[].m!(x => x); } void main() { auto a=foo(); }
Comment #4 by dfj1esp02 — 2018-08-21T13:20:52Z
@safe: struct A(T) { int[] r; this(int[] q){r=q;} } int[] escape(T)(int[] r) { return A!int(r).r; } int[] f() { int[6] xs = [0, 1, 2, 3, 4, 5]; return xs.escape!int; }
Comment #5 by radu.racariu — 2018-08-26T21:45:24Z
Under dip1000, what I think is that slicing a static array should always be considered scope. Also, calling a functions with a scope slice with the parameter for the slice not annotated as scope should result in an error if the compiler can't prove that the parameter can't escape.
Comment #6 by dfj1esp02 — 2018-08-27T08:00:24Z
Same for pointers: @safe: struct A(T) { int* r; this(int* q){r=q;} } int* escape(T)(int* r) { return A!int(r).r; } int* f() { int x; return escape!int(&x); }
Comment #7 by ag0aep6g — 2018-08-27T09:24:56Z
(In reply to anonymous4 from comment #6) > Same for pointers: [...] Resolving the templates shows that this is related to `pure`: ---- @safe: struct A { int* r; this(int* q) pure { r = q; } } int* escape(int* r) pure { return A(r).r; } int* f() { int x; return escape(&x); } ----
Comment #8 by slavo5150 — 2019-08-22T04:59:41Z
Works for me as in v2.087.1
Comment #9 by ag0aep6g — 2019-08-22T10:12:42Z
(In reply to Mike Franklin from comment #8) > Works for me as in v2.087.1 Most of the test cases are correctly rejected now with -dip1000. But the one from comment #7 is still accepted. Moved to issue 20150.