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, diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig index 7c5c653275..21308b0ea2 100644 --- a/test/stage1/behavior/union.zig +++ b/test/stage1/behavior/union.zig @@ -482,3 +482,15 @@ test "comparison between union and enum literal" { testComparison(); comptime testComparison(); } + +test "packed union generates correctly aligned LLVM type" { + const U = packed union { + f1: fn () void, + f2: u32, + }; + var foo = [_]U{ + U{ .f1 = doTest }, + U{ .f2 = 0 }, + }; + foo[0].f1(); +}