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

This commit is contained in:
Bogdan Romanyuk 2023-11-25 17:05:51 +03:00 committed by GitHub
parent 2fefc0b5c7
commit bece97ef24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 14 deletions

View File

@ -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,
};

View File

@ -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};
}