Bug 23657 – [REG2.101] Incorrect error escape reference to stack allocated value
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-01-26T23:14:12Z
Last change time
2024-04-26T05:09:06Z
Keywords
industry, rejects-valid
Assigned to
No Owner
Creator
johanengelen
Comments
Comment #0 by johanengelen — 2023-01-26T23:14:12Z
Testcase succeeds with dmd <= 2.100, but fails since dmd 2.101
> ~/dcompilers/dmd-2.101.2/osx/bin/dmd -c -o- testcase.d
testcase.d(46): Error: escaping reference to stack allocated value returned by `theLA().agent.members()`
I believe this diagnostic is incorrect, there is no escaping of a stack allocated value. (but I am not 100.000% sure)
Testcase:
```
import std.algorithm: map;
import std.array: array;
struct SmallTable(K, V, ushort capacity) {
ushort _length = 5;
K[capacity] keys;
V[capacity] values;
auto byKey() {
return keys[0 .. _length];
}
}
struct SmallSet(K, ushort capacity) {
private alias V = ubyte[1];
private SmallTable!(K, V, capacity) table;
auto items() {
return table.byKey;
}
}
struct NodeId {
ushort value;
}
struct RaftId {
NodeId nodeId;
}
public struct RA {
SmallSet!(RaftId, 13) members() { return SmallSet!(RaftId, 13)(); }
}
class LA {
RA agent;
}
private __gshared LA leadAI = new LA();
ref auto theLA() {
return leadAI;
}
auto foo() {
return theLA.agent.members.items.map!(rid => rid.nodeId).array;
}
void main() {
int i = 0;
auto a = foo();
import std.stdio;
writeln("&i = ", &i);
writeln("&leadAI = ", &leadAI);
writeln("leadAI = ", cast(void*)leadAI);
writeln("a.ptr = ", a.ptr);
writeln("a.length = ", a.length);
writeln("a = ", a);
import core.memory : GC;
writeln("is_gc_allocated = ", GC.addrOf(a.ptr) != null);
}
```
Comment #1 by dkorpel — 2023-01-27T13:36:14Z
Reduced:
```
import std.algorithm: map;
import std.array: array;
struct SmallSet
{
ushort[13] keys;
auto items() return { return keys[]; }
}
public struct RA {
SmallSet members() { return SmallSet(); }
}
RA agent;
auto foo() {
return agent.members.items.map!(x => x).array;
}
```
The problem is that members.items returns a slice to a local variable, which should be okay because you call `array` in the end, but there you hit Issue 23300.
*** This issue has been marked as a duplicate of issue 23300 ***
Comment #2 by dkorpel — 2024-04-23T14:50:13Z
Reopened because this issue is not limited to std.array, and is more about general return scope inference triggering errors in @system non-dip1000 code, like Johan mentions in issue 23300:
> Note that this bug does not require DIP1000, and breaks
> compilation since 2.101.