Thread overview
[Issue 23440] closure over typesafe variadic or scope array passes safe though leads to stack corruption
Nov 01, 2022
Walter Bright
Dec 17, 2022
Iain Buclaw
Mar 28, 2023
kinke
Mar 28, 2023
Ate Eskola
Mar 29, 2023
RazvanN
Jun 27, 2023
Adam D. Ruppe
October 27, 2022
https://issues.dlang.org/show_bug.cgi?id=23440

Steven Schveighoffer <schveiguy@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |safe
                 CC|                            |schveiguy@gmail.com

--
November 01, 2022
https://issues.dlang.org/show_bug.cgi?id=23440

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://issues.dlang.org/sh
                   |                            |ow_bug.cgi?id=23445

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=23440

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P3

--
March 28, 2023
https://issues.dlang.org/show_bug.cgi?id=23440

kinke <kinke@gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kinke@gmx.net
           Severity|normal                      |critical

--- Comment #1 from kinke <kinke@gmx.net> ---
Just hit this too. Bumping priority to critical.

--
March 28, 2023
https://issues.dlang.org/show_bug.cgi?id=23440

Steven Schveighoffer <schveiguy@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |accepts-invalid

--- Comment #2 from Steven Schveighoffer <schveiguy@gmail.com> ---
The closure should fail to allocate, since it has to point at scope data from the heap.

It can be reduced to this case:

```d
@safe:
auto foo(scope int *x)
{
    return { return x; };
}

auto bar() {
    int x = 5;
    return foo(&x);
}

void smash() {
    ubyte[1024] data;
}
void main()
{
    import std.stdio;
    auto dg = bar();
    smash();
    writeln(*dg());
}
```

--
March 28, 2023
https://issues.dlang.org/show_bug.cgi?id=23440

Ate Eskola <Ajieskola@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |Ajieskola@gmail.com

--- Comment #3 from Ate Eskola <Ajieskola@gmail.com> ---
This isn't due to any bug in variadic arrays. They are (as far as I tested) properly treated as `scope` arrays with the `-preview=dip1000` flag.

The real failure is in creation of the closure. This compiles and behaves exactly like the original example:

---
void delegate() @safe foo(scope int[] stuff) @safe {
        return () {
                assert(stuff == [1,2,3]);
                foreach(item; stuff) {}
        };
}

void delegate() @safe helper() @safe {
        int[3] stArray = [1, 2, 3];
        return foo(stArray);
}

void bar() @safe {
        int[2048] pwned; // just to smash the stack
}

void main() @safe {
        auto dg = helper();
        bar();
        dg();
}
---

--
March 29, 2023
https://issues.dlang.org/show_bug.cgi?id=23440

--- Comment #4 from RazvanN <razvan.nitu1305@gmail.com> ---
*** Issue 23813 has been marked as a duplicate of this issue. ***

--
June 27, 2023
https://issues.dlang.org/show_bug.cgi?id=23440

--- Comment #5 from Adam D. Ruppe <destructionator@gmail.com> ---
user on the discord posted this which also seems kinda similar


import std;


auto makeClosure(ref int n) @safe
{
    return ref () => n;
}

auto escapeClosure() @safe
{
    int n = 123;
    return makeClosure(n);
}

void clobberStack() @safe
{
    ubyte[4096] a;
}

void main() @safe
{
    auto dg = escapeClosure();
    pragma(msg,typeof(dg));
    clobberStack();
    assert(dg() == 123); // kaboom
}

--