Commit 95857d6b21

mlugg <mlugg@mlugg.co.uk>
2024-10-07 08:33:46
Sema: add missing runtime value validation to global mutable variables
Resolves: #20365
1 parent 3624356
Changed files (2)
src
test
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;
 }
 
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