authorgravatar for will.lillis24@gmail.comWill Lillis <will.lillis24@gmail.com> 2024-07-25 20:52:49-04:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2024-09-01 17:31:00+03:00
log28383d4d985cd04c897f6b6a63bd2107d8e2a8e9
tree8fa7df88c64a5574bdcb0ccad579e8c578fbd336
parentcad65307b757d4dfcbae018dbdb4c2a98b87b7e3

fix(Sema): patch segfault in `finishStructInit`


2 files changed, 35 insertions(+), 4 deletions(-)

src/Sema.zig+16-4
......@@ -20345,7 +20345,12 @@ fn structInitEmpty(
2034520345 defer gpa.free(field_inits);
2034620346 @memset(field_inits, .none);
2034720347
20348 return sema.finishStructInit(block, init_src, dest_src, field_inits, struct_ty, struct_ty, false);
20348 // Maps field index in the struct declaration to the field index in the initialization expression.
20349 const field_assign_idxs = try gpa.alloc(?usize, struct_ty.structFieldCount(zcu));
20350 defer gpa.free(field_assign_idxs);
20351 @memset(field_assign_idxs, null);
20352
20353 return sema.finishStructInit(block, init_src, dest_src, field_inits, field_assign_idxs, struct_ty, struct_ty, false);
2034920354}
2035020355
2035120356fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref {
......@@ -20456,6 +20461,11 @@ fn zirStructInit(
2045620461 defer gpa.free(field_inits);
2045720462 @memset(field_inits, .none);
2045820463
20464 // Maps field index in the struct declaration to the field index in the initialization expression.
20465 const field_assign_idxs = try gpa.alloc(?usize, resolved_ty.structFieldCount(zcu));
20466 defer gpa.free(field_assign_idxs);
20467 @memset(field_assign_idxs, null);
20468
2045920469 var field_i: u32 = 0;
2046020470 var extra_index = extra.end;
2046120471
......@@ -20478,6 +20488,7 @@ fn zirStructInit(
2047820488 else
2047920489 try sema.structFieldIndex(block, resolved_ty, field_name, field_src);
2048020490 assert(field_inits[field_index] == .none);
20491 field_assign_idxs[field_index] = field_i;
2048120492 found_fields[field_index] = item.data.field_type;
2048220493 const uncoerced_init = try sema.resolveInst(item.data.init);
2048320494 const field_ty = resolved_ty.fieldType(field_index, zcu);
......@@ -20498,7 +20509,7 @@ fn zirStructInit(
2049820509 }
2049920510 }
2050020511
20501 return sema.finishStructInit(block, src, src, field_inits, resolved_ty, result_ty, is_ref);
20512 return sema.finishStructInit(block, src, src, field_inits, field_assign_idxs, resolved_ty, result_ty, is_ref);
2050220513 } else if (resolved_ty.zigTypeTag(zcu) == .@"union") {
2050320514 if (extra.data.fields_len != 1) {
2050420515 return sema.fail(block, src, "union initialization expects exactly one field", .{});
......@@ -20583,6 +20594,7 @@ fn finishStructInit(
2058320594 init_src: LazySrcLoc,
2058420595 dest_src: LazySrcLoc,
2058520596 field_inits: []Air.Inst.Ref,
20597 field_assign_idxs: []?usize,
2058620598 struct_ty: Type,
2058720599 result_ty: Type,
2058820600 is_ref: bool,
......@@ -20684,9 +20696,9 @@ fn finishStructInit(
2068420696 }
2068520697
2068620698 // Find which field forces the expression to be runtime, if any.
20687 const opt_runtime_index = for (field_inits, 0..) |field_init, i| {
20699 const opt_runtime_index = for (field_inits, field_assign_idxs) |field_init, field_assign| {
2068820700 if (!(try sema.isComptimeKnown(field_init))) {
20689 break i;
20701 break field_assign;
2069020702 }
2069120703 } else null;
2069220704
test/cases/compile_errors/compile_time_struct_field.zig created+19
......@@ -0,0 +1,19 @@
1const S = struct {
2 comptime_field: comptime_int = 2,
3 normal_ptr: *u32,
4};
5
6export fn a() void {
7 var value: u32 = 3;
8 const comptimeStruct = S {
9 .normal_ptr = &value,
10 };
11 _ = comptimeStruct;
12}
13
14// error
15// backend=stage2
16// target=native
17//
18// 9:6: error: unable to resolve comptime value
19// 9:6: note: initializer of comptime only struct must be comptime-known