From 36243567e610808834147218fa791cbaab535941 Mon Sep 17 00:00:00 2001 From: mlugg Date: Mon, 7 Oct 2024 07:27:50 +0100 Subject: [PATCH 1/2] Sema: add missing runtime value validation to @memcpy and @memset --- src/Sema.zig | 5 +++++ .../comptime_var_referenced_at_runtime.zig | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/Sema.zig b/src/Sema.zig index abd66f22fe19..e397a6659a09 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -26193,6 +26193,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void } try sema.requireRuntimeBlock(block, src, runtime_src); + try sema.validateRuntimeValue(block, dest_src, dest_ptr); + try sema.validateRuntimeValue(block, src_src, src_ptr); // Aliasing safety check. if (block.wantSafety()) { @@ -26321,6 +26323,9 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void }; try sema.requireRuntimeBlock(block, src, runtime_src); + try sema.validateRuntimeValue(block, dest_src, dest_ptr); + try sema.validateRuntimeValue(block, value_src, elem); + _ = try block.addInst(.{ .tag = if (block.wantSafety()) .memset_safe else .memset, .data = .{ .bin_op = .{ diff --git a/test/cases/compile_errors/comptime_var_referenced_at_runtime.zig b/test/cases/compile_errors/comptime_var_referenced_at_runtime.zig index 30c3b2b850d0..2a5868f6b1ee 100644 --- a/test/cases/compile_errors/comptime_var_referenced_at_runtime.zig +++ b/test/cases/compile_errors/comptime_var_referenced_at_runtime.zig @@ -47,6 +47,22 @@ export fn qar() void { _ = y; } +export fn bux() void { + comptime var x: [2]u32 = undefined; + x = .{ 1, 2 }; + + var rt: [2]u32 = undefined; + @memcpy(&rt, &x); +} + +export fn far() void { + comptime var x: u32 = 123; + + var rt: [2]*u32 = undefined; + const elem: *u32 = &x; + @memset(&rt, elem); +} + // error // // :5:19: error: runtime value contains reference to comptime var @@ -63,3 +79,7 @@ export fn qar() void { // :41:12: note: comptime var pointers are not available at runtime // :46:39: error: runtime value contains reference to comptime var // :46:39: note: comptime var pointers are not available at runtime +// :55:18: error: runtime value contains reference to comptime var +// :55:18: note: comptime var pointers are not available at runtime +// :63:18: error: runtime value contains reference to comptime var +// :63:18: note: comptime var pointers are not available at runtime From 95857d6b2180c1bc1009a0ebb173ba66d44c34f7 Mon Sep 17 00:00:00 2001 From: mlugg Date: Mon, 7 Oct 2024 07:33:46 +0100 Subject: [PATCH 2/2] Sema: add missing runtime value validation to global mutable variables Resolves: #20365 --- src/Sema.zig | 7 ++++++- .../compile_errors/comptime_var_referenced_by_decl.zig | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Sema.zig b/src/Sema.zig index e397a6659a09..7060128e6db2 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2274,15 +2274,20 @@ pub fn resolveFinalDeclValue( src: LazySrcLoc, air_ref: Air.Inst.Ref, ) CompileError!Value { + const zcu = sema.pt.zcu; + const val = try sema.resolveValueAllowVariables(air_ref) orelse { return sema.failWithNeededComptime(block, src, .{ .needed_comptime_reason = "global variable initializer must be comptime-known", }); }; if (val.isGenericPoison()) return error.GenericPoison; - if (val.canMutateComptimeVarState(sema.pt.zcu)) { + + const init_val: Value = if (val.getVariable(zcu)) |v| .fromInterned(v.init) else val; + if (init_val.canMutateComptimeVarState(zcu)) { return sema.fail(block, src, "global variable contains reference to comptime var", .{}); } + return val; } diff --git a/test/cases/compile_errors/comptime_var_referenced_by_decl.zig b/test/cases/compile_errors/comptime_var_referenced_by_decl.zig index a5dce623edbd..e11af45df315 100644 --- a/test/cases/compile_errors/comptime_var_referenced_by_decl.zig +++ b/test/cases/compile_errors/comptime_var_referenced_by_decl.zig @@ -38,6 +38,12 @@ export const g: *const *const u32 = g: { break :g &aggregate[0]; }; +// Mutable globals should have the same restrictions as const globals. +export var h: *[1]u32 = h: { + var x: [1]u32 = .{123}; + break :h &x; +}; + // error // // :1:27: error: global variable contains reference to comptime var @@ -47,3 +53,4 @@ export const g: *const *const u32 = g: { // :22:24: error: global variable contains reference to comptime var // :28:33: error: global variable contains reference to comptime var // :34:40: error: global variable contains reference to comptime var +// :42:28: error: global variable contains reference to comptime var