Bug 15660 – break immutable with pure function and mutable reference params

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2016-02-08T20:58:19Z
Last change time
2018-03-21T07:24:52Z
Keywords
accepts-invalid, safe
Assigned to
No Owner
Creator
Iakh

Comments

Comment #0 by iaktakh — 2016-02-08T20:58:19Z
Compiler can't determine result of pure function is not unique import std.stdio; struct S { void[] arr; // with int instead of void program doesn't compiles auto f() pure @safe { int[] a = new int[4]; arr = a; return a; } } void main() @safe { S s; immutable a = s.f(); int[] b = (cast(int[])s.arr); writeln(a); // [0, 0, 0, 0] b[0] = 1; writeln(a); // [1, 0, 0, 0] }
Comment #1 by iaktakh — 2016-02-08T22:07:22Z
Also this works import std.stdio; class A { int i; } class B : A {} struct S { A a; auto f() pure @safe { B b = new B; a = b; return b; } } void main() @safe { S s; immutable a = s.f(); A b = s.a; writeln(a.i); b.i = 1; writeln(a.i); }
Comment #2 by schveiguy — 2016-02-09T16:35:43Z
This doesn't require member functions. int[] f(ref void[] m) pure { auto result = new int[5]; m = result; return result; } void main() { void[] v; immutable x = f(v); } One significant problem here is that the compiler may not consider the parameter to f in these cases to be a *return* avenue, only a parameter. The compiler should take into account references to ensure that they cannot escape the same data that is being returned. Fixing this may break a lot of code, but probably for the better. May need a deprecation cycle for this.
Comment #3 by iaktakh — 2016-02-09T17:48:25Z
(In reply to Steven Schveighoffer from comment #2) Even this works: import std.stdio; int[] f(void[] a) @safe pure { return cast(int[])a; } void main() @safe { int[] a = new int[4]; immutable b = a.f(); writeln(b); a[0] = 1; writeln(b); } > One significant problem here is that the compiler may not consider the > parameter to f in these cases to be a *return* avenue, only a parameter. The > compiler should take into account references to ensure that they cannot > escape the same data that is being returned. So not only escape. Compiler just traverses params's AST and search for exactly match with ReturnType. > Fixing this may break a lot of code, but probably for the better. May need a > deprecation cycle for this.
Comment #4 by schveiguy — 2016-02-09T18:51:45Z
(In reply to Iakh from comment #3) > (In reply to Steven Schveighoffer from comment #2) > Even this works: > import std.stdio; > > int[] f(void[] a) @safe pure > { > return cast(int[])a; > } In this case, you are using a cast. The compiler pretty much gives up trying to ensure anything when you cast, so I think it's OK to allow that. Although, I thought such a cast wouldn't work in @safe code.
Comment #5 by iaktakh — 2016-02-09T21:05:08Z
(In reply to Steven Schveighoffer from comment #4) > In this case, you are using a cast. The compiler pretty much gives up trying > to ensure anything when you cast, so I think it's OK to allow that. > > Although, I thought such a cast wouldn't work in @safe code. Me too. Casting of array types does in reinterpret_cast manner. So it's a bug in @safe definition.
Comment #6 by bugzilla — 2016-08-26T01:22:19Z
(In reply to Steven Schveighoffer from comment #4) > (In reply to Iakh from comment #3) > > (In reply to Steven Schveighoffer from comment #2) > > Even this works: > > import std.stdio; > > > > int[] f(void[] a) @safe pure > > { > > return cast(int[])a; > > } > > In this case, you are using a cast. The compiler pretty much gives up trying > to ensure anything when you cast, so I think it's OK to allow that. > > Although, I thought such a cast wouldn't work in @safe code. And indeed, it no longer is compilable: test.d(3): Error: cast from void[] to int[] not allowed in safe code
Comment #7 by bugzilla — 2018-03-18T00:35:24Z
Comment #8 by github-bugzilla — 2018-03-21T07:24:49Z
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/ab5a18635adaa3e2271e0f4b569500a89ac74235 fix Issue 15660 - break immutable with pure function and mutable reference params https://github.com/dlang/dmd/commit/54ab04e0ab6d27d96c78eccf10bc162fd08535cf Merge pull request #8048 from WalterBright/fix15660 fix Issue 15660 - break immutable with pure function and mutable refe… merged-on-behalf-of: Walter Bright <[email protected]>