aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthew Lugg <mlugg@mlugg.co.uk>2024-12-15 16:04:12 +0000
committerGitHub <noreply@github.com>2024-12-15 16:04:12 +0000
commit12f0c383475df1d0bd0e1a7aee58090e2cb23eb7 (patch)
tree7ad2a593be813469b9ac72f8542acb00625d6273 /src
parentaf89bb05d392b34a9ac257d166df1c794542f2e8 (diff)
parent72ba7f7e98b8cd00787e2903641e752e15264522 (diff)
downloadzig-12f0c383475df1d0bd0e1a7aee58090e2cb23eb7.tar.gz
zig-12f0c383475df1d0bd0e1a7aee58090e2cb23eb7.zip
Merge pull request #22239 from mlugg/runtime-store-comptime-only
Sema: disallow runtime stores to pointers with comptime-only element types Resolves: #22175
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig38
1 files changed, 32 insertions, 6 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index f31e71047f..aea749ddbd 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -3628,6 +3628,10 @@ fn zirAllocExtended(
}
}
+ if (small.has_type and try var_ty.comptimeOnlySema(pt)) {
+ return sema.analyzeComptimeAlloc(block, var_ty, alignment);
+ }
+
if (small.has_type) {
if (!small.is_const) {
try sema.validateVarType(block, ty_src, var_ty, false);
@@ -4075,7 +4079,7 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
- if (block.is_comptime) {
+ if (block.is_comptime or try var_ty.comptimeOnlySema(pt)) {
return sema.analyzeComptimeAlloc(block, var_ty, .none);
}
if (sema.func_is_naked and try var_ty.hasRuntimeBitsSema(pt)) {
@@ -30675,6 +30679,18 @@ fn coerceExtra(
else => {},
}
+ const can_coerce_to = switch (dest_ty.zigTypeTag(zcu)) {
+ .noreturn, .@"opaque" => false,
+ else => true,
+ };
+
+ if (can_coerce_to) {
+ // undefined to anything. We do this after the big switch above so that
+ // special logic has a chance to run first, such as `*[N]T` to `[]T` which
+ // should initialize the length field of the slice.
+ if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty);
+ }
+
if (!opts.report_err) return error.NotCoercible;
if (opts.is_ret and dest_ty.zigTypeTag(zcu) == .noreturn) {
@@ -30692,15 +30708,14 @@ fn coerceExtra(
return sema.failWithOwnedErrorMsg(block, msg);
}
- // undefined to anything. We do this after the big switch above so that
- // special logic has a chance to run first, such as `*[N]T` to `[]T` which
- // should initialize the length field of the slice.
- if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty);
-
const msg = msg: {
const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) });
errdefer msg.destroy(sema.gpa);
+ if (!can_coerce_to) {
+ try sema.errNote(inst_src, msg, "cannot coerce to '{}'", .{dest_ty.fmt(pt)});
+ }
+
// E!T to T
if (inst_ty.zigTypeTag(zcu) == .error_union and
(try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(zcu), dest_ty, false, target, dest_ty_src, inst_src, maybe_inst_val)) == .ok)
@@ -31927,6 +31942,17 @@ fn storePtr2(
} else break :rs ptr_src;
} else ptr_src;
+ // We're performing the store at runtime; as such, we need to make sure the pointee type
+ // is not comptime-only. We can hit this case with a `@ptrFromInt` pointer.
+ if (try elem_ty.comptimeOnlySema(pt)) {
+ return sema.failWithOwnedErrorMsg(block, msg: {
+ const msg = try sema.errMsg(src, "cannot store comptime-only type '{}' at runtime", .{elem_ty.fmt(pt)});
+ errdefer msg.destroy(sema.gpa);
+ try sema.errNote(ptr_src, msg, "operation is runtime due to this pointer", .{});
+ break :msg msg;
+ });
+ }
+
// We do this after the possible comptime store above, for the case of field_ptr stores
// to unions because we want the comptime tag to be set, even if the field type is void.
if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) {