Commit 3c4ac47e00
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 = .{
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 });
+}