https://issues.dlang.org/show_bug.cgi?id=20752
Issue ID: 20752
Summary: __traits(isReturnOnStack, func) is incomplete and
can't be trusted
Product: D
Version: D2
Hardware: All
OS: All
Status: NEW
Severity: major
Priority: P1
Component: dmd
Assignee: [email protected]
Reporter: [email protected]
Since half of the logic for NRVO is in the backend, this traits simply cannot
be relied on and is mostly useless.
For example, the following compiles and triggers the assert with DMD:
```
import std.meta;
import std.traits;
import std.stdio;
T deserializeFull (T) (scope ubyte[] delegate(size_t) dg)
{
static if (is(T == ulong))
{
ulong ret = *cast(ulong*)(dg(ulong.sizeof).ptr);
return ret;
}
else static if (is(T == ulong*))
{
return null;
}
else static if (is(T == struct))
{
Target convert (Target) ()
{
auto x = deserializeFull!Target(dg);
return x;
}
auto enableNRVO = T(staticMap!(convert, Fields!T));
return enableNRVO;
}
else
static assert(0);
}
struct FooBar
{
this(Repeat!(6, ulong) vals, ulong* ignored)
{
this.tupleof[0 .. vals.length] = vals;
this.ptr = &this.a;
}
ulong a;
ulong b;
ulong c;
ulong d;
ulong e;
ulong f;
ulong* ptr;
}
struct WrapMe { FooBar fb; FooBar xc; }
void main ()
{
//FooBar f;
ubyte[WrapMe.sizeof] binary = 42;
ubyte[] tmp = binary;
scope ubyte[] delegate(size_t v) getter = (v) {
scope(success) tmp = tmp[v .. $];
return tmp[0 .. v];
};
auto final_ = deserializeFull!WrapMe(getter);
writeln("ptr: ", final_.fb.ptr, " == ", &final_.fb.a);
assert(final_.fb.ptr is &final_.fb.a);
static assert(__traits(isReturnOnStack, deserializeFull!WrapMe));
}
```
LDC v1.20.1 compiles and run this just fine, but not DMD:
```
% dmd -run repro.d
ptr: 7FFEE998E3D8 == 7FFEE998E520
[email protected](61): Assertion failure
----------------
??:? _d_assertp [0x10628dcbd]
??:? _Dmain [0x10627192a]
```
I would expect a compilation error, or the assert to pass.
--