@@ -2681,39 +2681,50 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
2681
2681
assert(decl_node->type == NodeTypeContainerDecl);
2682
2682
assert(struct_type->di_type);
2683
2683
2684
+ size_t field_count = struct_type->data.structure.src_field_count;
2684
2685
if (struct_type->data.structure.layout == ContainerLayoutPacked) {
2685
2686
struct_type->data.structure.abi_alignment = 1;
2686
- }
2687
-
2688
- size_t field_count = struct_type->data.structure.src_field_count;
2689
- for (size_t i = 0; i < field_count; i += 1) {
2690
- TypeStructField *field = &struct_type->data.structure.fields[i];
2691
-
2692
- // If this assertion trips, look up the call stack. Probably something is
2693
- // calling type_resolve with ResolveStatusAlignmentKnown when it should only
2694
- // be resolving ResolveStatusZeroBitsKnown
2695
- assert(field->type_entry != nullptr);
2696
-
2697
- if (type_is_invalid(field->type_entry)) {
2698
- struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2699
- break;
2687
+ for (size_t i = 0; i < field_count; i += 1) {
2688
+ TypeStructField *field = &struct_type->data.structure.fields[i];
2689
+ if (field->type_entry != nullptr && type_is_invalid(field->type_entry)) {
2690
+ struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2691
+ break;
2692
+ }
2700
2693
}
2694
+ } else for (size_t i = 0; i < field_count; i += 1) {
2695
+ TypeStructField *field = &struct_type->data.structure.fields[i];
2696
+ uint32_t this_field_align;
2697
+
2698
+ // TODO If we have no type_entry for the field, we've already failed to
2699
+ // compile the program correctly. This stage1 compiler needs a deeper
2700
+ // reworking to make this correct, or we can ignore the problem
2701
+ // and make sure it is fixed in stage2. This workaround is for when
2702
+ // there is a false positive of a dependency loop, of alignment depending
2703
+ // on itself. When this false positive happens we assume a pointer-aligned
2704
+ // field, which is usually fine but could be incorrectly over-aligned or
2705
+ // even under-aligned. See https://github.com/ziglang/zig/issues/1512
2706
+ if (field->type_entry == nullptr) {
2707
+ this_field_align = LLVMABIAlignmentOfType(g->target_data_ref, LLVMPointerType(LLVMInt8Type(), 0));
2708
+ } else {
2709
+ if (type_is_invalid(field->type_entry)) {
2710
+ struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2711
+ break;
2712
+ }
2701
2713
2702
- if (!type_has_bits(field->type_entry))
2703
- continue;
2714
+ if (!type_has_bits(field->type_entry))
2715
+ continue;
2704
2716
2705
- // alignment of structs is the alignment of the most-aligned field
2706
- if (struct_type->data.structure.layout != ContainerLayoutPacked) {
2707
2717
if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) {
2708
2718
struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2709
2719
break;
2710
2720
}
2711
2721
2712
- uint32_t this_field_align = get_abi_alignment(g, field->type_entry);
2722
+ this_field_align = get_abi_alignment(g, field->type_entry);
2713
2723
assert(this_field_align != 0);
2714
- if (this_field_align > struct_type->data.structure.abi_alignment) {
2715
- struct_type->data.structure.abi_alignment = this_field_align;
2716
- }
2724
+ }
2725
+ // alignment of structs is the alignment of the most-aligned field
2726
+ if (this_field_align > struct_type->data.structure.abi_alignment) {
2727
+ struct_type->data.structure.abi_alignment = this_field_align;
2717
2728
}
2718
2729
}
2719
2730
0 commit comments