Commit 3c4ac47e00

Veikka Tuominen <git@vexu.eu>
2022-03-28 10:03:01
stage2 llvm: fix union init of byRef values
1 parent 7e47f10
Changed files (2)
src
codegen
test
behavior
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 });
+}