From 3c4ac47e00d961186c8728df964a29a33275514c Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Mon, 28 Mar 2022 11:03:01 +0300 Subject: [PATCH] stage2 llvm: fix union init of byRef values --- src/codegen/llvm.zig | 14 ++++++++++---- test/behavior/union.zig | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 431d158293..2e2e4ca819 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -6630,6 +6630,14 @@ pub const FuncGen = struct { // tag and the payload. const index_type = self.context.intType(32); + var field_ptr_payload: Type.Payload.Pointer = .{ + .data = .{ + .pointee_type = field.ty, + .@"align" = field_align, + .@"addrspace" = .generic, + }, + }; + const field_ptr_ty = Type.initPayload(&field_ptr_payload.base); if (layout.tag_size == 0) { const indices: [3]*const llvm.Value = .{ index_type.constNull(), @@ -6638,8 +6646,7 @@ pub const FuncGen = struct { }; const len: c_uint = if (field_size == layout.payload_size) 2 else 3; const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, len, ""); - const store_inst = self.builder.buildStore(llvm_payload, field_ptr); - store_inst.setAlignment(field_align); + self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic); return result_ptr; } @@ -6651,8 +6658,7 @@ pub const FuncGen = struct { }; const len: c_uint = if (field_size == layout.payload_size) 2 else 3; const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, len, ""); - const store_inst = self.builder.buildStore(llvm_payload, field_ptr); - store_inst.setAlignment(field_align); + self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic); } { const indices: [2]*const llvm.Value = .{ diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 532d4f79eb..87efcbd5f1 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -1149,3 +1149,22 @@ test "union with no result loc initiated with a runtime value" { var a: u32 = 1; U.foo(U{ .a = a }); } + +test "union with a large struct field" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + + const S = struct { + a: [8]usize, + }; + + const U = union { + s: S, + b: u32, + fn foo(_: @This()) void {} + }; + var s: S = undefined; + U.foo(U{ .s = s }); +}