| ... | ... | @@ -2686,13 +2686,22 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2686 | 2686 | } |
| 2687 | 2687 | |
| 2688 | 2688 | size_t field_count = struct_type->data.structure.src_field_count; |
| 2689 | bool self_resolving = false; |
| 2689 | 2690 | for (size_t i = 0; i < field_count; i += 1) { |
| 2690 | 2691 | TypeStructField *field = &struct_type->data.structure.fields[i]; |
| 2691 | 2692 | |
| 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); |
| 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 | } |
| 2696 | 2705 | |
| 2697 | 2706 | if (type_is_invalid(field->type_entry)) { |
| 2698 | 2707 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| ... | ... | @@ -2723,6 +2732,14 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2723 | 2732 | return ErrorSemanticAnalyzeFail; |
| 2724 | 2733 | } |
| 2725 | 2734 | |
| 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 | } |
| 2726 | 2743 | struct_type->data.structure.resolve_status = ResolveStatusAlignmentKnown; |
| 2727 | 2744 | return ErrorNone; |
| 2728 | 2745 | } |