authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-10-07 13:46:21+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-10-07 13:46:21+01:00
logea527f7a850f0200681630d8f36131eca31ef48b
tree70cf160373d67ad8ed5d46af78d91f5bc6bb5aaf
parent7a2fde973d27c7c47dc6eba174c71ae93af29d5f
parent95857d6b2180c1bc1009a0ebb173ba66d44c34f7
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21618 from mlugg/validate-runtime-value

Sema: add a few missing runtime value validations

3 files changed, 38 insertions(+), 1 deletions(-)

src/Sema.zig+11-1
...@@ -2274,15 +2274,20 @@ pub fn resolveFinalDeclValue(...@@ -2274,15 +2274,20 @@ pub fn resolveFinalDeclValue(
2274 src: LazySrcLoc,2274 src: LazySrcLoc,
2275 air_ref: Air.Inst.Ref,2275 air_ref: Air.Inst.Ref,
2276) CompileError!Value {2276) CompileError!Value {
2277 const zcu = sema.pt.zcu;
2278
2277 const val = try sema.resolveValueAllowVariables(air_ref) orelse {2279 const val = try sema.resolveValueAllowVariables(air_ref) orelse {
2278 return sema.failWithNeededComptime(block, src, .{2280 return sema.failWithNeededComptime(block, src, .{
2279 .needed_comptime_reason = "global variable initializer must be comptime-known",2281 .needed_comptime_reason = "global variable initializer must be comptime-known",
2280 });2282 });
2281 };2283 };
2282 if (val.isGenericPoison()) return error.GenericPoison;2284 if (val.isGenericPoison()) return error.GenericPoison;
2283 if (val.canMutateComptimeVarState(sema.pt.zcu)) {2285
2286 const init_val: Value = if (val.getVariable(zcu)) |v| .fromInterned(v.init) else val;
2287 if (init_val.canMutateComptimeVarState(zcu)) {
2284 return sema.fail(block, src, "global variable contains reference to comptime var", .{});2288 return sema.fail(block, src, "global variable contains reference to comptime var", .{});
2285 }2289 }
2290
2286 return val;2291 return val;
2287}2292}
22882293
...@@ -26193,6 +26198,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -26193,6 +26198,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
26193 }26198 }
2619426199
26195 try sema.requireRuntimeBlock(block, src, runtime_src);26200 try sema.requireRuntimeBlock(block, src, runtime_src);
26201 try sema.validateRuntimeValue(block, dest_src, dest_ptr);
26202 try sema.validateRuntimeValue(block, src_src, src_ptr);
2619626203
26197 // Aliasing safety check.26204 // Aliasing safety check.
26198 if (block.wantSafety()) {26205 if (block.wantSafety()) {
...@@ -26321,6 +26328,9 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -26321,6 +26328,9 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
26321 };26328 };
2632226329
26323 try sema.requireRuntimeBlock(block, src, runtime_src);26330 try sema.requireRuntimeBlock(block, src, runtime_src);
26331 try sema.validateRuntimeValue(block, dest_src, dest_ptr);
26332 try sema.validateRuntimeValue(block, value_src, elem);
26333
26324 _ = try block.addInst(.{26334 _ = try block.addInst(.{
26325 .tag = if (block.wantSafety()) .memset_safe else .memset,26335 .tag = if (block.wantSafety()) .memset_safe else .memset,
26326 .data = .{ .bin_op = .{26336 .data = .{ .bin_op = .{
test/cases/compile_errors/comptime_var_referenced_at_runtime.zig+20
...@@ -47,6 +47,22 @@ export fn qar() void {...@@ -47,6 +47,22 @@ export fn qar() void {
47 _ = y;47 _ = y;
48}48}
4949
50export fn bux() void {
51 comptime var x: [2]u32 = undefined;
52 x = .{ 1, 2 };
53
54 var rt: [2]u32 = undefined;
55 @memcpy(&rt, &x);
56}
57
58export fn far() void {
59 comptime var x: u32 = 123;
60
61 var rt: [2]*u32 = undefined;
62 const elem: *u32 = &x;
63 @memset(&rt, elem);
64}
65
50// error66// error
51//67//
52// :5:19: error: runtime value contains reference to comptime var68// :5:19: error: runtime value contains reference to comptime var
...@@ -63,3 +79,7 @@ export fn qar() void {...@@ -63,3 +79,7 @@ export fn qar() void {
63// :41:12: note: comptime var pointers are not available at runtime79// :41:12: note: comptime var pointers are not available at runtime
64// :46:39: error: runtime value contains reference to comptime var80// :46:39: error: runtime value contains reference to comptime var
65// :46:39: note: comptime var pointers are not available at runtime81// :46:39: note: comptime var pointers are not available at runtime
82// :55:18: error: runtime value contains reference to comptime var
83// :55:18: note: comptime var pointers are not available at runtime
84// :63:18: error: runtime value contains reference to comptime var
85// :63:18: note: comptime var pointers are not available at runtime
test/cases/compile_errors/comptime_var_referenced_by_decl.zig+7
...@@ -38,6 +38,12 @@ export const g: *const *const u32 = g: {...@@ -38,6 +38,12 @@ export const g: *const *const u32 = g: {
38 break :g &aggregate[0];38 break :g &aggregate[0];
39};39};
4040
41// Mutable globals should have the same restrictions as const globals.
42export var h: *[1]u32 = h: {
43 var x: [1]u32 = .{123};
44 break :h &x;
45};
46
41// error47// error
42//48//
43// :1:27: error: global variable contains reference to comptime var49// :1:27: error: global variable contains reference to comptime var
...@@ -47,3 +53,4 @@ export const g: *const *const u32 = g: {...@@ -47,3 +53,4 @@ export const g: *const *const u32 = g: {
47// :22:24: error: global variable contains reference to comptime var53// :22:24: error: global variable contains reference to comptime var
48// :28:33: error: global variable contains reference to comptime var54// :28:33: error: global variable contains reference to comptime var
49// :34:40: error: global variable contains reference to comptime var55// :34:40: error: global variable contains reference to comptime var
56// :42:28: error: global variable contains reference to comptime var