| ... | ... | @@ -2681,48 +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 | | bool self_resolving = false; |
| 2690 | | for (size_t i = 0; i < field_count; i += 1) { |
| 2691 | | TypeStructField *field = &struct_type->data.structure.fields[i]; |
| 2692 | | |
| 2693 | | // If we have no type_entry for the field, assume that we are in the |
| 2694 | | // midst of resolving this struct. We further assume that since the |
| 2695 | | // resolved alignment of the other fields of this struct is ultimately |
| 2696 | | // equal to the resolved alignment of this struct, we can safely ignore. |
| 2697 | | // |
| 2698 | | // If this struct is used down-stream in aligning a sub-struct, ignoring |
| 2699 | | // this struct in the context of a sub struct has the same effect since |
| 2700 | | // the other fields will be calculated and bubble-up. |
| 2701 | | if (nullptr == field->type_entry) { |
| 2702 | | self_resolving = true; |
| 2703 | | continue; |
| 2704 | | } |
| 2705 | | |
| 2706 | | if (type_is_invalid(field->type_entry)) { |
| 2707 | | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2708 | | 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 | } |
| 2709 | 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 | } |
| 2710 | 2713 | |
| 2711 | | if (!type_has_bits(field->type_entry)) |
| 2712 | | continue; |
| 2714 | if (!type_has_bits(field->type_entry)) |
| 2715 | continue; |
| 2713 | 2716 | |
| 2714 | | // alignment of structs is the alignment of the most-aligned field |
| 2715 | | if (struct_type->data.structure.layout != ContainerLayoutPacked) { |
| 2716 | 2717 | if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) { |
| 2717 | 2718 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2718 | 2719 | break; |
| 2719 | 2720 | } |
| 2720 | 2721 | |
| 2721 | | uint32_t this_field_align = get_abi_alignment(g, field->type_entry); |
| 2722 | this_field_align = get_abi_alignment(g, field->type_entry); |
| 2722 | 2723 | assert(this_field_align != 0); |
| 2723 | | if (this_field_align > struct_type->data.structure.abi_alignment) { |
| 2724 | | struct_type->data.structure.abi_alignment = this_field_align; |
| 2725 | | } |
| 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; |
| 2726 | 2728 | } |
| 2727 | 2729 | } |
| 2728 | 2730 | |
| ... | ... | @@ -2732,14 +2734,6 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2732 | 2734 | return ErrorSemanticAnalyzeFail; |
| 2733 | 2735 | } |
| 2734 | 2736 | |
| 2735 | | if ( self_resolving |
| 2736 | | && field_count > 0 |
| 2737 | | ) { |
| 2738 | | // If we get here it's due to self-referencing this struct before it has been fully resolved. |
| 2739 | | // In this case, set alignment to target pointer default. |
| 2740 | | struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref, |
| 2741 | | LLVMPointerType(LLVMInt8Type(), 0)); |
| 2742 | | } |
| 2743 | 2737 | struct_type->data.structure.resolve_status = ResolveStatusAlignmentKnown; |
| 2744 | 2738 | return ErrorNone; |
| 2745 | 2739 | } |