authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-14 19:01:04+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-14 14:57:03-05:00
log505b9db9090c7decba68c7882b1330f48aff0c10
tree24e46643cef2522f37b41af28cd0032d9871e200
parentaf2ede4d96d5dd01a9db2f6fbfbe430214beaf63

Fix codegen error for some union initializers

Closes #3377

2 files changed, 11 insertions(+), 2 deletions(-)

src/codegen.cpp+2-2
...@@ -7195,7 +7195,7 @@ check: switch (const_val->special) {...@@ -7195,7 +7195,7 @@ check: switch (const_val->special) {
7195 union_value_ref = LLVMGetUndef(union_type_ref);7195 union_value_ref = LLVMGetUndef(union_type_ref);
7196 make_unnamed_struct = false;7196 make_unnamed_struct = false;
7197 } else {7197 } else {
7198 uint64_t field_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,7198 uint64_t field_type_bytes = LLVMABISizeOfType(g->target_data_ref,
7199 get_llvm_type(g, payload_value->type));7199 get_llvm_type(g, payload_value->type));
7200 uint64_t pad_bytes = type_entry->data.unionation.union_abi_size - field_type_bytes;7200 uint64_t pad_bytes = type_entry->data.unionation.union_abi_size - field_type_bytes;
7201 LLVMValueRef correctly_typed_value = gen_const_val(g, payload_value, "");7201 LLVMValueRef correctly_typed_value = gen_const_val(g, payload_value, "");
...@@ -7235,7 +7235,7 @@ check: switch (const_val->special) {...@@ -7235,7 +7235,7 @@ check: switch (const_val->special) {
7235 uint64_t last_field_offset = LLVMOffsetOfElement(g->target_data_ref, LLVMTypeOf(result), 1);7235 uint64_t last_field_offset = LLVMOffsetOfElement(g->target_data_ref, LLVMTypeOf(result), 1);
7236 uint64_t end_offset = last_field_offset +7236 uint64_t end_offset = last_field_offset +
7237 LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(fields[1]));7237 LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(fields[1]));
7238 uint64_t expected_sz = LLVMStoreSizeOfType(g->target_data_ref, get_llvm_type(g, type_entry));7238 uint64_t expected_sz = LLVMABISizeOfType(g->target_data_ref, get_llvm_type(g, type_entry));
7239 unsigned pad_sz = expected_sz - end_offset;7239 unsigned pad_sz = expected_sz - end_offset;
7240 if (pad_sz != 0) {7240 if (pad_sz != 0) {
7241 fields[2] = LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), pad_sz));7241 fields[2] = LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), pad_sz));
test/stage1/behavior/union.zig+9
...@@ -620,3 +620,12 @@ test "0-sized extern union definition" {...@@ -620,3 +620,12 @@ test "0-sized extern union definition" {
620620
621 expect(U.f == 1);621 expect(U.f == 1);
622}622}
623
624test "union initializer generates padding only if needed" {
625 const U = union(enum) {
626 A: u24,
627 };
628
629 var v = U{ .A = 532 };
630 expect(v.A == 532);
631}