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;
assert(*p == 42); /* passes */
scope(exit) assert(*p == 42); /* fails */
int* m = f(S(p)); /* uh-oh */
*m = 13; /* writing over immutable *p */
}
Comment #1 by ag0aep6g — 2017-07-25T10:04:05Z
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 */
}
----
Comment #2 by bugzilla — 2018-03-04T01:54:26Z
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 */
> }
Comment #3 by bugzilla — 2018-03-04T01:57:46Z
The second example is still a bug.
Comment #4 by ag0aep6g — 2018-03-04T11:50:12Z
(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.
Comment #5 by robert.schadek — 2024-12-13T18:42:59Z