stage2 llvm: fix union init of byRef values

This commit is contained in:
Veikka Tuominen 2022-03-28 11:03:01 +03:00 committed by Andrew Kelley
parent 7e47f106cc
commit 3c4ac47e00
2 changed files with 29 additions and 4 deletions

View File

@ -6630,6 +6630,14 @@ pub const FuncGen = struct {
// tag and the payload. // tag and the payload.
const index_type = self.context.intType(32); 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) { if (layout.tag_size == 0) {
const indices: [3]*const llvm.Value = .{ const indices: [3]*const llvm.Value = .{
index_type.constNull(), 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 len: c_uint = if (field_size == layout.payload_size) 2 else 3;
const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, len, ""); const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, len, "");
const store_inst = self.builder.buildStore(llvm_payload, field_ptr); self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
store_inst.setAlignment(field_align);
return result_ptr; 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 len: c_uint = if (field_size == layout.payload_size) 2 else 3;
const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, len, ""); const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, len, "");
const store_inst = self.builder.buildStore(llvm_payload, field_ptr); self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
store_inst.setAlignment(field_align);
} }
{ {
const indices: [2]*const llvm.Value = .{ const indices: [2]*const llvm.Value = .{

View File

@ -1149,3 +1149,22 @@ test "union with no result loc initiated with a runtime value" {
var a: u32 = 1; var a: u32 = 1;
U.foo(U{ .a = a }); 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 });
}