zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit bece97ef248ad36d31a48fb761b4a41324c9c5d5 (tree)
parent 2fefc0b5c7618012916e75e3058b381cf48f0ebb
Author: Bogdan Romanyuk <65823030+wrongnull@users.noreply.github.com>
Date:   Sat, 25 Nov 2023 17:05:51 +0300

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


Diffstat:
Msrc/Sema.zig | 35+++++++++++++++++++++--------------
Mtest/behavior/struct.zig | 9+++++++++
2 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/src/Sema.zig b/src/Sema.zig @@ -19705,20 +19705,24 @@ fn zirArrayInit( }, else => return err, }; - if (is_tuple) if (try array_ty.structFieldValueComptime(mod, i)) |field_val| { - const init_val = try sema.resolveValue(dest.*) orelse { - const decl = mod.declPtr(block.src_decl); - const elem_src = mod.initSrc(src.node_offset.x, decl, i); - return sema.failWithNeededComptime(block, elem_src, .{ - .needed_comptime_reason = "value stored in comptime field must be comptime-known", - }); - }; - if (!field_val.eql(init_val, elem_ty, mod)) { - const decl = mod.declPtr(block.src_decl); - const elem_src = mod.initSrc(src.node_offset.x, decl, i); - return sema.failWithInvalidComptimeFieldStore(block, elem_src, array_ty, i); + if (is_tuple) { + if (array_ty.structFieldIsComptime(i, mod)) + try sema.resolveStructFieldInits(array_ty); + if (try array_ty.structFieldValueComptime(mod, i)) |field_val| { + const init_val = try sema.resolveValue(dest.*) orelse { + const decl = mod.declPtr(block.src_decl); + const elem_src = mod.initSrc(src.node_offset.x, decl, i); + return sema.failWithNeededComptime(block, elem_src, .{ + .needed_comptime_reason = "value stored in comptime field must be comptime-known", + }); + }; + if (!field_val.eql(init_val, elem_ty, mod)) { + const decl = mod.declPtr(block.src_decl); + const elem_src = mod.initSrc(src.node_offset.x, decl, i); + return sema.failWithInvalidComptimeFieldStore(block, elem_src, array_ty, i); + } } - }; + } } if (root_msg) |msg| { @@ -31481,7 +31485,10 @@ fn coerceTupleToTuple( anon_struct_type.names.get(ip)[field_i] else try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}), - .struct_type => |struct_type| struct_type.field_names.get(ip)[field_i], + .struct_type => |struct_type| if (struct_type.field_names.len > 0) + struct_type.field_names.get(ip)[field_i] + else + try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}), else => unreachable, }; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig @@ -1881,3 +1881,12 @@ test "field calls do not force struct field init resolution" { _ = &s; try expect(s.x == 123); } + +test "tuple with comptime-only field" { + const x = getTuple(); + try expect(x.@"0" == 0); +} + +fn getTuple() struct { comptime_int } { + return struct { comptime comptime_int = 0 }{0}; +}