DMD 2.079.0
void main(){
int i = 0;
struct S{
const(int)* fun()const pure{
return &i;
}
}
immutable S s;
static const(int)* foo(immutable(S) s)pure{
return s.fun();
}
immutable(int) *pi=foo(s);
import std.stdio;
writeln(*pi); // 0
i+=1;
writeln(*pi); // 1
}
I.e. the data *pi is typed as immutable(int), yet changes.
Comment #1 by razvan.nitu1305 — 2022-07-29T09:21:23Z
The code now compiles and prints:
```
0
0
```
So `i` does not change anymore, however, the code is still broken in my opinion, as it should not compile. Since `s` is immutable, maybe the context pointer for fun should also be type as immutable?
Comment #2 by timon.gehr — 2022-07-29T10:00:30Z
Well, the compiler is just compiling the code differently now (which it can do, as it exhibits UB), the CSE is pretty easy to defeat though:
void main(){
int i = 0;
struct S{
const(int)* fun()const pure{
return &i;
}
}
immutable S s;
static const(int)* foo(immutable(S) s)pure{
return s.fun();
}
immutable(int) *pi=foo(s);
import std.stdio;
writeln(*pi); // 0
i+=1;
int x=*pi;
writeln(x); // 1
}
The problem is that this line compiles:
immutable S s;
This requires an immutable context pointer, but a mutable one is provided.
In general, context pointers should be type checked essentially as if we were passing around explicit pointers.
Comment #3 by robert.schadek — 2024-12-13T18:57:41Z