Comment #0 by snarwin+bugzilla — 2021-01-20T18:02:38Z
Example program:
---
union U
{
int x;
immutable int y;
}
void example() @safe
{
U a = { x: 0 };
int n = a.y;
}
---
Access to `a.y` should be forbidden in @safe code according the the language spec's definition of safe aliasing [1], which permits aliasing between types with different mutability qualifiers only when
> * both types are const or immutable; or
> * one of the types is mutable while the other is a const-qualified basic data
> type
[1] https://dlang.org/spec/function.html#safe-aliasing
Comment #1 by zopsicle — 2021-01-20T18:15:10Z
Note that assigning to the a.x is still prohibited:
---
Error: field `U.x` cannot modify fields in `@safe` code that overlap fields with other storage classes
---
With that in place, is it necessary to also prohibit accessing the field?
Comment #2 by snarwin+bugzilla — 2021-01-20T18:28:29Z
Yes, because the data can still be modified by assigning a new value to the whole union.
---
void oops()
{
U a = { y: 0 };
U b = { x: 1 };
assert(a.y == 0);
a = b;
assert(a.y == 1);
}
---
Strictly speaking, the problem is that we are allowed to access a.y after its lifetime has ended. However, this only leads to undefined behavior when unsafe aliasing is involved, so the unsafe aliasing is what needs to be fixed.
Comment #3 by robert.schadek — 2024-12-13T19:14:06Z