authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-12-20 12:36:15-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-12-20 12:36:15-05:00
log0f54194e6ab2b0cbdc798b84cc4213a07ed1d0c1
tree5d421882b9195d98e530e1374f0d0db14275f271
parentfb81b1978b87be5a72328a4d9efc21561ae53cfc
signature Commit is signed but in an unrecognized format.

fixups


1 files changed, 33 insertions(+), 39 deletions(-)

src/analyze.cpp+33-39
...@@ -2681,48 +2681,50 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {...@@ -2681,48 +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);
26832683
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) {
26872688 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 bool self_resolving = false;2690 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2690 for (size_t i = 0; i < field_count; i += 1) {2691 break;
2691 TypeStructField *field = &struct_type->data.structure.fields[i];2692 }
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;
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 }
27102713
2711 if (!type_has_bits(field->type_entry))2714 if (!type_has_bits(field->type_entry))
2712 continue;2715 continue;
27132716
2714 // alignment of structs is the alignment of the most-aligned field
2715 if (struct_type->data.structure.layout != ContainerLayoutPacked) {
2716 if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) {2717 if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) {
2717 struct_type->data.structure.resolve_status = ResolveStatusInvalid;2718 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2718 break;2719 break;
2719 }2720 }
27202721
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 assert(this_field_align != 0);2723 assert(this_field_align != 0);
2723 if (this_field_align > struct_type->data.structure.abi_alignment) {2724 }
2724 struct_type->data.structure.abi_alignment = this_field_align;2725 // alignment of structs is the alignment of the most-aligned field
2725 }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 }
27282730
...@@ -2732,14 +2734,6 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {...@@ -2732,14 +2734,6 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
2732 return ErrorSemanticAnalyzeFail;2734 return ErrorSemanticAnalyzeFail;
2733 }2735 }
27342736
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 struct_type->data.structure.resolve_status = ResolveStatusAlignmentKnown;2737 struct_type->data.structure.resolve_status = ResolveStatusAlignmentKnown;
2744 return ErrorNone;2738 return ErrorNone;
2745}2739}