authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-03-28 11:03:01+03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-28 13:04:50-07:00
log3c4ac47e00d961186c8728df964a29a33275514c
treed357889c3e99573985602602afa04995d2348807
parent7e47f106ccf73af4c890ecbb4d48e9e92d38d3c4

stage2 llvm: fix union init of byRef values


2 files changed, 29 insertions(+), 4 deletions(-)

src/codegen/llvm.zig+10-4
......@@ -6630,6 +6630,14 @@ pub const FuncGen = struct {
66306630 // tag and the payload.
66316631 const index_type = self.context.intType(32);
66326632
6633 var field_ptr_payload: Type.Payload.Pointer = .{
6634 .data = .{
6635 .pointee_type = field.ty,
6636 .@"align" = field_align,
6637 .@"addrspace" = .generic,
6638 },
6639 };
6640 const field_ptr_ty = Type.initPayload(&field_ptr_payload.base);
66336641 if (layout.tag_size == 0) {
66346642 const indices: [3]*const llvm.Value = .{
66356643 index_type.constNull(),
......@@ -6638,8 +6646,7 @@ pub const FuncGen = struct {
66386646 };
66396647 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;
66406648 const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, len, "");
6641 const store_inst = self.builder.buildStore(llvm_payload, field_ptr);
6642 store_inst.setAlignment(field_align);
6649 self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
66436650 return result_ptr;
66446651 }
66456652
......@@ -6651,8 +6658,7 @@ pub const FuncGen = struct {
66516658 };
66526659 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;
66536660 const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, len, "");
6654 const store_inst = self.builder.buildStore(llvm_payload, field_ptr);
6655 store_inst.setAlignment(field_align);
6661 self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
66566662 }
66576663 {
66586664 const indices: [2]*const llvm.Value = .{
test/behavior/union.zig+19
......@@ -1149,3 +1149,22 @@ test "union with no result loc initiated with a runtime value" {
11491149 var a: u32 = 1;
11501150 U.foo(U{ .a = a });
11511151}
1152
1153test "union with a large struct field" {
1154 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1155 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1156 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1157 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1158
1159 const S = struct {
1160 a: [8]usize,
1161 };
1162
1163 const U = union {
1164 s: S,
1165 b: u32,
1166 fn foo(_: @This()) void {}
1167 };
1168 var s: S = undefined;
1169 U.foo(U{ .s = s });
1170}