| ... | @@ -2681,39 +2681,50 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { | ... | @@ -2681,39 +2681,50 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2681 | assert(decl_node->type == NodeTypeContainerDecl); | 2681 | assert(decl_node->type == NodeTypeContainerDecl); |
| 2682 | assert(struct_type->di_type); | 2682 | assert(struct_type->di_type); |
| 2683 | | 2683 | |
| | 2684 | size_t field_count = struct_type->data.structure.src_field_count; |
| 2684 | if (struct_type->data.structure.layout == ContainerLayoutPacked) { | 2685 | if (struct_type->data.structure.layout == ContainerLayoutPacked) { |
| 2685 | struct_type->data.structure.abi_alignment = 1; | 2686 | struct_type->data.structure.abi_alignment = 1; |
| 2686 | } | 2687 | for (size_t i = 0; i < field_count; i += 1) { |
| 2687 | | 2688 | TypeStructField *field = &struct_type->data.structure.fields[i]; |
| 2688 | size_t field_count = struct_type->data.structure.src_field_count; | 2689 | if (field->type_entry != nullptr && type_is_invalid(field->type_entry)) { |
| 2689 | for (size_t i = 0; i < field_count; i += 1) { | 2690 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2690 | TypeStructField *field = &struct_type->data.structure.fields[i]; | 2691 | break; |
| 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); | | |
| 2696 | | | |
| 2697 | if (type_is_invalid(field->type_entry)) { | | |
| 2698 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | | |
| 2699 | break; | | |
| 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)) | 2714 | if (!type_has_bits(field->type_entry)) |
| 2703 | continue; | 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 | if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) { | 2717 | if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) { |
| 2708 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2718 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2709 | break; | 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 | assert(this_field_align != 0); | 2723 | assert(this_field_align != 0); |
| 2714 | if (this_field_align > struct_type->data.structure.abi_alignment) { | 2724 | } |
| 2715 | struct_type->data.structure.abi_alignment = this_field_align; | 2725 | // alignment of structs is the alignment of the most-aligned field |
| 2716 | } | 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 | |