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(...@@ -19705,20 +19705,24 @@ fn zirArrayInit(
19705 },19705 },
19706 else => return err,19706 else => return err,
19707 };19707 };
19708 if (is_tuple) if (try array_ty.structFieldValueComptime(mod, i)) |field_val| {19708 if (is_tuple) {
19709 const init_val = try sema.resolveValue(dest.*) orelse {19709 if (array_ty.structFieldIsComptime(i, mod))
19710 const decl = mod.declPtr(block.src_decl);19710 try sema.resolveStructFieldInits(array_ty);
19711 const elem_src = mod.initSrc(src.node_offset.x, decl, i);19711 if (try array_ty.structFieldValueComptime(mod, i)) |field_val| {
19712 return sema.failWithNeededComptime(block, elem_src, .{19712 const init_val = try sema.resolveValue(dest.*) orelse {
19713 .needed_comptime_reason = "value stored in comptime field must be comptime-known",19713 const decl = mod.declPtr(block.src_decl);
19714 });19714 const elem_src = mod.initSrc(src.node_offset.x, decl, i);
19715 };19715 return sema.failWithNeededComptime(block, elem_src, .{
19716 if (!field_val.eql(init_val, elem_ty, mod)) {19716 .needed_comptime_reason = "value stored in comptime field must be comptime-known",
19717 const decl = mod.declPtr(block.src_decl);19717 });
19718 const elem_src = mod.initSrc(src.node_offset.x, decl, i);19718 };
19719 return sema.failWithInvalidComptimeFieldStore(block, elem_src, array_ty, i);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 }
19720 }19724 }
19721 };19725 }
19722 }19726 }
1972319727
19724 if (root_msg) |msg| {19728 if (root_msg) |msg| {
...@@ -31481,7 +31485,10 @@ fn coerceTupleToTuple(...@@ -31481,7 +31485,10 @@ fn coerceTupleToTuple(
31481 anon_struct_type.names.get(ip)[field_i]31485 anon_struct_type.names.get(ip)[field_i]
31482 else31486 else
31483 try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),31487 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}),
31485 else => unreachable,31492 else => unreachable,
31486 };31493 };
3148731494
test/behavior/struct.zig+9
...@@ -1881,3 +1881,12 @@ test "field calls do not force struct field init resolution" {...@@ -1881,3 +1881,12 @@ test "field calls do not force struct field init resolution" {
1881 _ = &s;1881 _ = &s;
1882 try expect(s.x == 123);1882 try expect(s.x == 123);
1883}1883}
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}