fix(Sema): patch segfault in finishStructInit

This commit is contained in:
WillLillis
2024-07-25 20:52:49 -04:00
committed by Veikka Tuominen
parent cad65307b7
commit 28383d4d98
2 changed files with 35 additions and 4 deletions

View File

@@ -20345,7 +20345,12 @@ fn structInitEmpty(
defer gpa.free(field_inits);
@memset(field_inits, .none);
return sema.finishStructInit(block, init_src, dest_src, field_inits, struct_ty, struct_ty, false);
// Maps field index in the struct declaration to the field index in the initialization expression.
const field_assign_idxs = try gpa.alloc(?usize, struct_ty.structFieldCount(zcu));
defer gpa.free(field_assign_idxs);
@memset(field_assign_idxs, null);
return sema.finishStructInit(block, init_src, dest_src, field_inits, field_assign_idxs, struct_ty, struct_ty, false);
}
fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref {
@@ -20456,6 +20461,11 @@ fn zirStructInit(
defer gpa.free(field_inits);
@memset(field_inits, .none);
// Maps field index in the struct declaration to the field index in the initialization expression.
const field_assign_idxs = try gpa.alloc(?usize, resolved_ty.structFieldCount(zcu));
defer gpa.free(field_assign_idxs);
@memset(field_assign_idxs, null);
var field_i: u32 = 0;
var extra_index = extra.end;
@@ -20478,6 +20488,7 @@ fn zirStructInit(
else
try sema.structFieldIndex(block, resolved_ty, field_name, field_src);
assert(field_inits[field_index] == .none);
field_assign_idxs[field_index] = field_i;
found_fields[field_index] = item.data.field_type;
const uncoerced_init = try sema.resolveInst(item.data.init);
const field_ty = resolved_ty.fieldType(field_index, zcu);
@@ -20498,7 +20509,7 @@ fn zirStructInit(
}
}
return sema.finishStructInit(block, src, src, field_inits, resolved_ty, result_ty, is_ref);
return sema.finishStructInit(block, src, src, field_inits, field_assign_idxs, resolved_ty, result_ty, is_ref);
} else if (resolved_ty.zigTypeTag(zcu) == .@"union") {
if (extra.data.fields_len != 1) {
return sema.fail(block, src, "union initialization expects exactly one field", .{});
@@ -20583,6 +20594,7 @@ fn finishStructInit(
init_src: LazySrcLoc,
dest_src: LazySrcLoc,
field_inits: []Air.Inst.Ref,
field_assign_idxs: []?usize,
struct_ty: Type,
result_ty: Type,
is_ref: bool,
@@ -20684,9 +20696,9 @@ fn finishStructInit(
}
// Find which field forces the expression to be runtime, if any.
const opt_runtime_index = for (field_inits, 0..) |field_init, i| {
const opt_runtime_index = for (field_inits, field_assign_idxs) |field_init, field_assign| {
if (!(try sema.isComptimeKnown(field_init))) {
break i;
break field_assign;
}
} else null;

View File

@@ -0,0 +1,19 @@
const S = struct {
comptime_field: comptime_int = 2,
normal_ptr: *u32,
};
export fn a() void {
var value: u32 = 3;
const comptimeStruct = S {
.normal_ptr = &value,
};
_ = comptimeStruct;
}
// error
// backend=stage2
// target=native
//
// 9:6: error: unable to resolve comptime value
// 9:6: note: initializer of comptime only struct must be comptime-known