| ... | @@ -2686,13 +2686,22 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { | ... | @@ -2686,13 +2686,22 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2686 | } | 2686 | } |
| 2687 | | 2687 | |
| 2688 | size_t field_count = struct_type->data.structure.src_field_count; | 2688 | size_t field_count = struct_type->data.structure.src_field_count; |
| | 2689 | bool self_resolving = false; |
| 2689 | for (size_t i = 0; i < field_count; i += 1) { | 2690 | for (size_t i = 0; i < field_count; i += 1) { |
| 2690 | TypeStructField *field = &struct_type->data.structure.fields[i]; | 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 | // If we have no type_entry for the field, assume that we are in the |
| 2693 | // calling type_resolve with ResolveStatusAlignmentKnown when it should only | 2694 | // midst of resolving this struct. We further assume that since the |
| 2694 | // be resolving ResolveStatusZeroBitsKnown | 2695 | // resolved alignment of the other fields of this struct is ultimately |
| 2695 | assert(field->type_entry != nullptr); | 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 | if (type_is_invalid(field->type_entry)) { | 2706 | if (type_is_invalid(field->type_entry)) { |
| 2698 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2707 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| ... | @@ -2723,6 +2732,14 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { | ... | @@ -2723,6 +2732,14 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2723 | return ErrorSemanticAnalyzeFail; | 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 | struct_type->data.structure.resolve_status = ResolveStatusAlignmentKnown; | 2743 | struct_type->data.structure.resolve_status = ResolveStatusAlignmentKnown; |
| 2727 | return ErrorNone; | 2744 | return ErrorNone; |
| 2728 | } | 2745 | } |