Bug 20084 – return by auto ref unsafe - and different code for inout ref and ref.

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2019-07-25T17:49:24Z
Last change time
2020-03-14T11:30:57Z
Keywords
accepts-invalid, pull, safe
Assigned to
No Owner
Creator
Ali Ak

Comments

Comment #0 by ali.akhtarzada — 2019-07-25T17:49:24Z
Original issue opened here: https://github.com/ldc-developers/ldc/issues/3115 but it seems maybe a frontend thing? A function returning by auto ref seems to return by value if it in turn calls an ref T function, where as it seems to return by ref if it calls an inout ref T. I assume this may have something to do with inout ref being inferred as a return? And so inout doesn't generate a value? But why does ref T return by ref? And how can one make this generic code safe: auto ref get(Range)(Range range) { return range.front; } If you take the following code and look at the output you'll see what's happening: struct W(T) { T value; ref inout(T) inoutFront() inout { return value; } ref T front() { return value; } } auto ref inoutGet(T)(W!T value) { return value.inoutFront; } auto ref get(T)(W!T value) { return value.front; } extern(C) void main() { int inoutS = W!int(4).inoutGet; int s = W!int(6).get; }
Comment #1 by kinke — 2019-07-25T19:03:42Z
With `-dip1000`, get() returns a reference, just like inoutGet(). Even this compiles with `-dip1000 -dip25` but clearly reads beyond the stack: ----- @safe: struct W(T) { T value; ref T front() return { return value; } } ref get(T)(W!T value) { return value.front; } void foo() { int i = get(W!int(4)); } -----
Comment #2 by ali.akhtarzada — 2019-07-25T22:08:27Z
(In reply to Ali Ak from comment #0) > But why does ref T return by ref? *by value > auto ref get(Range)(Range range) { > return range.front; > } I meant: auto ref get(Range)(auto ref Range range) { return range.front; }
Comment #3 by bugzilla — 2020-03-14T09:34:36Z
Reduced test case: struct W() { int value; @safe ref int front() return { return value; } } @safe ref int get(W!() v) { return v.front; // should produce error message with -dip1000 }
Comment #4 by dlang-bot — 2020-03-14T09:36:19Z
@WalterBright created dlang/dmd pull request #10915 "fix Issue 20084 - return by auto ref unsafe - and different code for …" fixing this issue: - fix Issue 20084 - return by auto ref unsafe - and different code for inout ref and ref https://github.com/dlang/dmd/pull/10915
Comment #5 by dlang-bot — 2020-03-14T11:30:57Z
dlang/dmd pull request #10915 "fix Issue 20084 - return by auto ref unsafe - and different code for …" was merged into master: - a299e32a89e6dabfcc35fb4be063c9902832f508 by Walter Bright: fix Issue 20084 - return by auto ref unsafe - and different code for inout ref and ref https://github.com/dlang/dmd/pull/10915