aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustus Klausecker <justus@klausecker.de>2025-11-14 14:13:09 +0100
committerMatthew Lugg <mlugg@mlugg.co.uk>2025-11-14 23:25:54 +0000
commit06d08dababda8fde2fef8267698a712d1966045d (patch)
tree2517a590fd472799ebea1eee4f39cf92de023230 /src
parentc6b5945356568f6ec70ca00f9a844bd180f8ca62 (diff)
downloadzig-06d08dababda8fde2fef8267698a712d1966045d.tar.gz
zig-06d08dababda8fde2fef8267698a712d1966045d.zip
Sema: fix illegal multi level pointer coercions
Moves a premature check that allowed pointers to mutable pointers to coerce to any other pointer to a mutable pointer.
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig20
1 files changed, 14 insertions, 6 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 191ab34070..390ec0b926 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -29385,14 +29385,18 @@ const InMemoryCoercionResult = union(enum) {
break;
},
.array_sentinel => |sentinel| {
- if (sentinel.actual.toIntern() != .unreachable_value) {
- try sema.errNote(src, msg, "array sentinel '{f}' cannot cast into array sentinel '{f}'", .{
- sentinel.actual.fmtValueSema(pt, sema), sentinel.wanted.fmtValueSema(pt, sema),
+ if (sentinel.wanted.toIntern() == .unreachable_value) {
+ try sema.errNote(src, msg, "source array cannot be guaranteed to maintain '{f}' sentinel", .{
+ sentinel.actual.fmtValueSema(pt, sema),
});
- } else {
+ } else if (sentinel.actual.toIntern() == .unreachable_value) {
try sema.errNote(src, msg, "destination array requires '{f}' sentinel", .{
sentinel.wanted.fmtValueSema(pt, sema),
});
+ } else {
+ try sema.errNote(src, msg, "array sentinel '{f}' cannot cast into array sentinel '{f}'", .{
+ sentinel.actual.fmtValueSema(pt, sema), sentinel.wanted.fmtValueSema(pt, sema),
+ });
}
break;
},
@@ -30179,10 +30183,14 @@ fn coerceInMemoryAllowedPtrs(
src_src,
null,
);
- if (child != .ok and !dest_is_mut) allow: {
+ if (child != .ok) allow: {
// As a special case, we also allow coercing `*[n:s]T` to `*[n]T`, akin to dropping the sentinel from a slice.
// `*[n:s]T` cannot coerce in memory to `*[n]T` since they have different sizes.
- if (src_child.zigTypeTag(zcu) == .array and dest_child.zigTypeTag(zcu) == .array and
+ //
+ // We must once again include `dest_is_mut` because `**[n:s]T -> **[n]T`
+ // is not allowed, as it would make it possible to assign an illegal value
+ // to the sentinel-terminated side.
+ if (!dest_is_mut and src_child.zigTypeTag(zcu) == .array and dest_child.zigTypeTag(zcu) == .array and
src_child.arrayLen(zcu) == dest_child.arrayLen(zcu) and
src_child.sentinel(zcu) != null and dest_child.sentinel(zcu) == null and
.ok == try sema.coerceInMemoryAllowed(block, dest_child.childType(zcu), src_child.childType(zcu), !dest_info.flags.is_const, target, dest_src, src_src, null))