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