Open Fri3dNstuff opened 3 months ago
It's already noted in the issue text, but important to note that coercion of pointers-to-const *const *align(2) T
-> *const *align(1) T
can be allowed.
We only need to prevent it when the target pointer-to-mutable broadens the set of valid pointee values.
I just stumbled upon another manifestation of the issue, now with sentinel-terminated types:
test {
var x: [*:0]const u8 = "abc";
const good_ref: *[*:0]const u8 = &x;
const evil_ref: *[*]const u8 = good_ref; // this coercion is bad!
evil_ref.* = @as([*]const u8, &.{ 'a', 'b', 'c' });
// oops! `x` is now storing a
// non-sentinel-terminated pointer!
}
this is the classic unsoundness of covariance of mutable references. to lay out the sound conversions:
in Zig we also care that the coercion is possible in-memory (i.e. we just reinterpret bits), and that mutable references to T
can be cast into mutable references to U
and back if T
and U
are in-memory coercible into each other
Zig Version
0.14.0-dev.367+a57479afc
Steps to Reproduce and Observed Behavior
Attempt to compile the following code:
The code compiles without errors.
Expected Behavior
The code should have triggered a compilation error.
A mutable pointer to (one / many / slice / C) a type
T
can coerce into a mutable pointer of typeU
without soundness problems if-and-only-if:T
andU
are in-memory coercible, andThese are, I believe, the most liberal coercion rules that do not result in soundness problems - I will leave the discussion about whether Zig should be this liberal with its coercion rules to another issue.