authorgravatar for wrongnull@gmail.comBogdan Romanyuk <wrongnull@gmail.com> 2023-11-25 17:05:51+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-11-25 14:05:51+00:00
logbece97ef248ad36d31a48fb761b4a41324c9c5d5
tree14a254df83aa69e8296270e13df68753fca57c02
parent2fefc0b5c7618012916e75e3058b381cf48f0ebb
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Sema: ensure tuple fields is resolved and fix internal out-of-bounds access


2 files changed, 30 insertions(+), 14 deletions(-)

src/Sema.zig+21-14
......@@ -19705,20 +19705,24 @@ fn zirArrayInit(
1970519705 },
1970619706 else => return err,
1970719707 };
19708 if (is_tuple) if (try array_ty.structFieldValueComptime(mod, i)) |field_val| {
19709 const init_val = try sema.resolveValue(dest.*) orelse {
19710 const decl = mod.declPtr(block.src_decl);
19711 const elem_src = mod.initSrc(src.node_offset.x, decl, i);
19712 return sema.failWithNeededComptime(block, elem_src, .{
19713 .needed_comptime_reason = "value stored in comptime field must be comptime-known",
19714 });
19715 };
19716 if (!field_val.eql(init_val, elem_ty, mod)) {
19717 const decl = mod.declPtr(block.src_decl);
19718 const elem_src = mod.initSrc(src.node_offset.x, decl, i);
19719 return sema.failWithInvalidComptimeFieldStore(block, elem_src, array_ty, i);
19708 if (is_tuple) {
19709 if (array_ty.structFieldIsComptime(i, mod))
19710 try sema.resolveStructFieldInits(array_ty);
19711 if (try array_ty.structFieldValueComptime(mod, i)) |field_val| {
19712 const init_val = try sema.resolveValue(dest.*) orelse {
19713 const decl = mod.declPtr(block.src_decl);
19714 const elem_src = mod.initSrc(src.node_offset.x, decl, i);
19715 return sema.failWithNeededComptime(block, elem_src, .{
19716 .needed_comptime_reason = "value stored in comptime field must be comptime-known",
19717 });
19718 };
19719 if (!field_val.eql(init_val, elem_ty, mod)) {
19720 const decl = mod.declPtr(block.src_decl);
19721 const elem_src = mod.initSrc(src.node_offset.x, decl, i);
19722 return sema.failWithInvalidComptimeFieldStore(block, elem_src, array_ty, i);
19723 }
1972019724 }
19721 };
19725 }
1972219726 }
1972319727
1972419728 if (root_msg) |msg| {
......@@ -31481,7 +31485,10 @@ fn coerceTupleToTuple(
3148131485 anon_struct_type.names.get(ip)[field_i]
3148231486 else
3148331487 try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),
31484 .struct_type => |struct_type| struct_type.field_names.get(ip)[field_i],
31488 .struct_type => |struct_type| if (struct_type.field_names.len > 0)
31489 struct_type.field_names.get(ip)[field_i]
31490 else
31491 try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),
3148531492 else => unreachable,
3148631493 };
3148731494
test/behavior/struct.zig+9
......@@ -1881,3 +1881,12 @@ test "field calls do not force struct field init resolution" {
18811881 _ = &s;
18821882 try expect(s.x == 123);
18831883}
1884
1885test "tuple with comptime-only field" {
1886 const x = getTuple();
1887 try expect(x.@"0" == 0);
1888}
1889
1890fn getTuple() struct { comptime_int } {
1891 return struct { comptime comptime_int = 0 }{0};
1892}