February 27, 2023
https://issues.dlang.org/show_bug.cgi?id=23751

          Issue ID: 23751
           Summary: Returning by ref from opApply fools DIP1000
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: major
          Priority: P2
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: timon.gehr@gmx.ch

DMD 2.102.1:

Test case 1:

---
struct S{
    int x;
    int opApply(scope int delegate(ref int x)@safe @nogc dg)@safe @nogc{
        return dg(x);
    }
}

ref int foo(ref S s)@safe @nogc{
    foreach(ref x;s)
        return x;
    assert(0);
}

int *escapeStack()@safe{
    S s;
    return &foo(s);
}

void main()@safe{
    import std.stdio;
    auto p=escapeStack();
    writeln(*p); // 0
    writeln("overwrite stack");
    writeln(*p); // garbage
}
---

Test case 2:

---
struct S{
    int x;
    int opApply(scope int delegate(ref int x)@safe @nogc dg)@safe @nogc{
        return dg(x);
    }
}

ref int foo(ref S s)@safe @nogc{
    foreach(x;s)
        return x;
    assert(0);
}

int *escapeStack()@safe{
    S s;
    return &foo(s);
}

void overwriteStack(int depth)@safe{
    auto s=S(2);
    import std.stdio;
    if(depth==0) writeln("overwrite stack: ",s);
    else overwriteStack(depth-1);
}

void main()@safe{
    import std.stdio;
    auto p=escapeStack();
    writeln(*p); // 0
    overwriteStack(10);
    writeln(*p); // garbage
}
---

(Partial reboot of Issue 23739 with proper test cases.)

--