authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-08-05 10:55:49+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-08-10 10:00:37+01:00
log7a7d0225d9825f0150e797a4ff06f6e56af08458
tree25b7e41db36efdcbbbdb6d07cc0701593fc960c3
parentf2c8fa769a92eb61c13f2cc0f75c526c8fd729a9
signaturelock-open Commit is signed but in an unrecognized format.

Sema: detect invalid field stores in tuple initialization

This bug was exposed by the previous commit, since array_init is now used for tuple parameters.

1 files changed, 14 insertions(+), 1 deletions(-)

src/Sema.zig+14-1
...@@ -19393,13 +19393,14 @@ fn zirArrayInit(...@@ -19393,13 +19393,14 @@ fn zirArrayInit(
19393 },19393 },
19394 else => |e| return e,19394 else => |e| return e,
19395 };19395 };
19396 const is_tuple = array_ty.zigTypeTag(mod) == .Struct;
19396 const sentinel_val = array_ty.sentinel(mod);19397 const sentinel_val = array_ty.sentinel(mod);
1939719398
19398 const resolved_args = try gpa.alloc(Air.Inst.Ref, args.len - 1 + @intFromBool(sentinel_val != null));19399 const resolved_args = try gpa.alloc(Air.Inst.Ref, args.len - 1 + @intFromBool(sentinel_val != null));
19399 defer gpa.free(resolved_args);19400 defer gpa.free(resolved_args);
19400 for (args[1..], 0..) |arg, i| {19401 for (args[1..], 0..) |arg, i| {
19401 const resolved_arg = try sema.resolveInst(arg);19402 const resolved_arg = try sema.resolveInst(arg);
19402 const elem_ty = if (array_ty.zigTypeTag(mod) == .Struct)19403 const elem_ty = if (is_tuple)
19403 array_ty.structFieldType(i, mod)19404 array_ty.structFieldType(i, mod)
19404 else19405 else
19405 array_ty.elemType2(mod);19406 array_ty.elemType2(mod);
...@@ -19412,6 +19413,18 @@ fn zirArrayInit(...@@ -19412,6 +19413,18 @@ fn zirArrayInit(
19412 },19413 },
19413 else => return err,19414 else => return err,
19414 };19415 };
19416 if (is_tuple) if (try array_ty.structFieldValueComptime(mod, i)) |field_val| {
19417 const init_val = try sema.resolveMaybeUndefVal(resolved_args[i]) orelse {
19418 const decl = mod.declPtr(block.src_decl);
19419 const elem_src = mod.initSrc(src.node_offset.x, decl, i);
19420 return sema.failWithNeededComptime(block, elem_src, "value stored in comptime field must be comptime-known");
19421 };
19422 if (!field_val.eql(init_val, elem_ty, mod)) {
19423 const decl = mod.declPtr(block.src_decl);
19424 const elem_src = mod.initSrc(src.node_offset.x, decl, i);
19425 return sema.failWithInvalidComptimeFieldStore(block, elem_src, array_ty, i);
19426 }
19427 };
19415 }19428 }
1941619429
19417 if (sentinel_val) |some| {19430 if (sentinel_val) |some| {