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