aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
authorLemonBoy <thatlemon@gmail.com>2019-09-07 11:17:12 +0200
committerAndrew Kelley <andrew@ziglang.org>2019-09-10 10:07:32 -0400
commit8fbae77770a77ccd645054e06baab45b03c8befd (patch)
tree274683fbf2812e735de6cc7228430f2f50d4ad12 /src/analyze.cpp
parenta06f84fcc62396dc4216d5c9f8da1f0463d17f50 (diff)
downloadzig-8fbae77770a77ccd645054e06baab45b03c8befd.tar.gz
zig-8fbae77770a77ccd645054e06baab45b03c8befd.zip
Force LLVM to generate byte-aligned packed unions
Sometimes the frontend and LLVM would disagree on the ABI alignment of a packed union. Solve the problem by telling LLVM we're gonna manage the struct layout by ourselves. Closes #3184
Diffstat (limited to 'src/analyze.cpp')
-rw-r--r--src/analyze.cpp8
1 files changed, 5 insertions, 3 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index e06faba7a9..b845dc8388 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -7905,6 +7905,8 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu
static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveStatus wanted_resolve_status) {
if (union_type->data.unionation.resolve_status >= wanted_resolve_status) return;
+ bool packed = (union_type->data.unionation.layout == ContainerLayoutPacked);
+
TypeUnionField *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member;
ZigType *tag_type = union_type->data.unionation.tag_type;
uint32_t gen_field_count = union_type->data.unionation.gen_field_count;
@@ -7971,9 +7973,9 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
most_aligned_union_member->type_entry->llvm_type,
get_llvm_type(g, padding_array),
};
- LLVMStructSetBody(union_type->llvm_type, union_element_types, 2, false);
+ LLVMStructSetBody(union_type->llvm_type, union_element_types, 2, packed);
} else {
- LLVMStructSetBody(union_type->llvm_type, &most_aligned_union_member->type_entry->llvm_type, 1, false);
+ LLVMStructSetBody(union_type->llvm_type, &most_aligned_union_member->type_entry->llvm_type, 1, packed);
}
union_type->data.unionation.union_llvm_type = union_type->llvm_type;
union_type->data.unionation.gen_tag_index = SIZE_MAX;
@@ -8012,7 +8014,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
LLVMTypeRef root_struct_element_types[2];
root_struct_element_types[union_type->data.unionation.gen_tag_index] = get_llvm_type(g, tag_type);
root_struct_element_types[union_type->data.unionation.gen_union_index] = union_type_ref;
- LLVMStructSetBody(union_type->llvm_type, root_struct_element_types, 2, false);
+ LLVMStructSetBody(union_type->llvm_type, root_struct_element_types, 2, packed);
// create debug type for union
ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,