Jump to page: 1 2
Thread overview
[Issue 22539] [dip1000] slicing of returned ref scope static array should not be allowed
Nov 26, 2021
Dlang Bot
Nov 27, 2021
Walter Bright
Nov 27, 2021
Dennis
Nov 27, 2021
Walter Bright
Nov 27, 2021
Walter Bright
Nov 27, 2021
Dennis
Nov 27, 2021
Dennis
Nov 27, 2021
Walter Bright
Nov 27, 2021
Dennis
Nov 27, 2021
Walter Bright
Nov 27, 2021
Dennis
Nov 28, 2021
Walter Bright
Nov 29, 2021
Walter Bright
Feb 13, 2022
Florian Weimer
Mar 10, 2022
Dlang Bot
November 26, 2021
https://issues.dlang.org/show_bug.cgi?id=22539

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #1 from Dlang Bot <dlang-bot@dlang.rocks> ---
@dkorpel created dlang/dmd pull request #13362 "Fix issue 22539 - slicing of returned ref scope static array should not be allowed" fixing this issue:

- Fix issue 22539 - slicing of returned ref scope static array should not be allowed

https://github.com/dlang/dmd/pull/13362

--
November 27, 2021
https://issues.dlang.org/show_bug.cgi?id=22539

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com

--- Comment #2 from Walter Bright <bugzilla@digitalmars.com> ---
I suspect the problem is actually this line:

    scope int*[1] x = [&stackVar];

Since scope is not transitive, allowing this causes the compiler to lose track of stack addresses, and will allow escapes.

--
November 27, 2021
https://issues.dlang.org/show_bug.cgi?id=22539

--- Comment #3 from Dennis <dkorpel@live.nl> ---
(In reply to Walter Bright from comment #2)
> I suspect the problem is actually this line:
> 
>     scope int*[1] x = [&stackVar];
> 
> Since scope is not transitive, allowing this causes the compiler to lose track of stack addresses, and will allow escapes.

Only if x were a slice, but since it's a static array with dimension 1 it is identical to:

scope int* x = &stackVar;

So it is correctly permitted.

--
November 27, 2021
https://issues.dlang.org/show_bug.cgi?id=22539

--- Comment #4 from Walter Bright <bugzilla@digitalmars.com> ---
Add @safe to escape() and it will fail to compile.

--
November 27, 2021
https://issues.dlang.org/show_bug.cgi?id=22539

--- Comment #5 from Walter Bright <bugzilla@digitalmars.com> ---
P.S. many times I've chased rabbits only to discover I forgot to add @safe. @safe really should be the default.

--
November 27, 2021
https://issues.dlang.org/show_bug.cgi?id=22539

--- Comment #6 from Dennis <dkorpel@live.nl> ---
(In reply to Walter Bright from comment #4)
> Add @safe to escape() and it will fail to compile.

`escape` is already under `@safe:`. I added `@safe` to escape explicitly to double check, it still compiles on my end. What error do you get?

--
November 27, 2021
https://issues.dlang.org/show_bug.cgi?id=22539

--- Comment #7 from Dennis <dkorpel@live.nl> ---
(In reply to Walter Bright from comment #5)
> P.S. many times I've chased rabbits only to discover I forgot to add @safe. @safe really should be the default.

I didn't forget @safe, I added @safe: on top (as I usually do).

--
November 27, 2021
https://issues.dlang.org/show_bug.cgi?id=22539

--- Comment #8 from Walter Bright <bugzilla@digitalmars.com> ---
My bad, adding -dip1000 removes the error message. I had neglected to do that.

--
November 27, 2021
https://issues.dlang.org/show_bug.cgi?id=22539

--- Comment #9 from Dennis <dkorpel@live.nl> ---
(In reply to Walter Bright from comment #8)
> My bad, adding -dip1000 removes the error message. I had neglected to do that.

I guess -dip1000 really should be the default :)

--
November 27, 2021
https://issues.dlang.org/show_bug.cgi?id=22539

--- Comment #10 from Walter Bright <bugzilla@digitalmars.com> ---
Moving on from my previous mistakes:

    @safe:
    ref int* identity(ref return scope int* x) { return x; }

    int* escape() {
        int stackVar;
        scope int* x = &stackVar;
        int* y = identity(x);
        return y; // error: scope variable `y` may not be returned
    }

Good. Next,

    @safe:
    ref int*[1] identity(ref return scope int*[1] x) { return x; }

    int*[1] escape() {
        int stackVar;
        scope int*[1] x = [&stackVar];
        int*[1] y = identity(x);
        return y; // error: scope variable `y` may not be returned
    }

Good.

    int* escape() {
        int stackVar;
        scope int*[1] x = [&stackVar];
        int*[1] y = identity(x);
        return y[0]; // error: scope variable `y` may not be returned
    }

Good.

    int* escape() {
        int stackVar;
        scope int*[1] x = [&stackVar];
        int*[1] y = identity(x);
        int*[] z = y[]; // error: cannot take address of `scope` local `y`
        return z[0];
    }

Good. Here, the slicing of `y` is properly detected. But if we put the [] after the identity call:

    int* escape() {
        int stackVar;
        scope int*[1] x = [&stackVar];
        int*[] y = identity(x)[];
        return y[0];
    }

No error; bad. The slicing of the return value of identity() is not properly propagating the scope-ness of its argument x. This would be a problem in escape.d.

--
« First   ‹ Prev
1 2