Thread overview
[Issue 14618] can break immutable with inout and a delegate
Jul 25, 2017
ag0aep6g@gmail.com
Mar 04, 2018
Walter Bright
Mar 04, 2018
Walter Bright
Mar 04, 2018
ag0aep6g@gmail.com
Dec 17, 2022
Iain Buclaw
July 25, 2017
https://issues.dlang.org/show_bug.cgi?id=14618

ag0aep6g@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |safe

--- Comment #1 from ag0aep6g@gmail.com ---
Also possible in @safe code:

----
struct S
{
    immutable(int)* p;
}

inout(int)* f(inout S s) @safe
{
    inout(int)* result;
    auto dg = (inout(int)* p) {result = p;};
    dg(s.p);
    return result;
}

void main() @safe
{
    immutable int* p = new int(42);
    assert(*p == 42); /* passes */
    scope(exit) assert(*p == 42); /* fails */
    int* m = f(S(p)); /* uh-oh */
    *m = 13; /* writing over immutable *p */
}
----

--
March 04, 2018
https://issues.dlang.org/show_bug.cgi?id=14618

Walter Bright <bugzilla@digitalmars.com> changed:

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

--- Comment #2 from Walter Bright <bugzilla@digitalmars.com> ---
If I prepend:

  @safe:

to the code:

(In reply to ag0aep6g from comment #0)
> struct S
> {
>     immutable(int)* p;
> }
> 
> inout(int)* f(inout S s)
> {
>     inout(int)* result;
>     auto dg = (inout(int)* p) {result = p;};
>     dg(s.p);
>     return result;
> }
> 
> void main()
> {
>     immutable int x = 42;
>     immutable int* p = &x;

   Error: cannot take address of local x in @safe function main

>     assert(*p == 42); /* passes */
>     scope(exit) assert(*p == 42); /* fails */
>     int* m = f(S(p)); /* uh-oh */
>     *m = 13; /* writing over immutable *p */
> }

--
March 04, 2018
https://issues.dlang.org/show_bug.cgi?id=14618

--- Comment #3 from Walter Bright <bugzilla@digitalmars.com> ---
The second example is still a bug.

--
March 04, 2018
https://issues.dlang.org/show_bug.cgi?id=14618

--- Comment #4 from ag0aep6g@gmail.com ---
(In reply to Walter Bright from comment #2)
> If I prepend:
> 
>   @safe:
> 
> to the code:
[...]
>    Error: cannot take address of local x in @safe function main

Compile with `-dip1000` and add `scope` to `f`'s parameter and it compiles again:

----
@safe:

struct S
{
    immutable(int)* p;
}

inout(int)* f(scope inout S s)
{
    inout(int)* result;
    auto dg = (inout(int)* p) {result = p;};
    dg(s.p);
    return result;
}

void main()
{
    immutable int x = 42;
    immutable int* p = &x;
    assert(*p == 42); /* passes */
    scope(exit) assert(*p == 42); /* fails */
    int* m = f(S(p)); /* uh-oh */
    *m = 13; /* writing over immutable *p */
}
----

The `scope` on the parameter is wrong here, of course, but the compiler doesn't catch it.

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

Iain Buclaw <ibuclaw@gdcproject.org> changed:

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

--
December 13
https://issues.dlang.org/show_bug.cgi?id=14618

--- Comment #5 from dlangBugzillaToGithub <robert.schadek@posteo.de> ---
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/dmd/issues/18992

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB

--