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
signaturelock-open 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) {
26812681 assert(decl_node->type == NodeTypeContainerDecl);
26822682 assert(struct_type->di_type);
26832683
2684 size_t field_count = struct_type->data.structure.src_field_count;
26842685 if (struct_type->data.structure.layout == ContainerLayoutPacked) {
26852686 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 }
27092693 }
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))
2712 continue;
2714 if (!type_has_bits(field->type_entry))
2715 continue;
27132716
2714 // alignment of structs is the alignment of the most-aligned field
2715 if (struct_type->data.structure.layout != ContainerLayoutPacked) {
27162717 if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) {
27172718 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
27182719 break;
27192720 }
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);
27222723 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;
27262728 }
27272729 }
27282730
......@@ -2732,14 +2734,6 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
27322734 return ErrorSemanticAnalyzeFail;
27332735 }
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 }
27432737 struct_type->data.structure.resolve_status = ResolveStatusAlignmentKnown;
27442738 return ErrorNone;
27452739}