diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index a24c14c9c6..300a24280a 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -8897,7 +8897,7 @@ pub const FuncGen = struct { return union_llvm_ty.constInt(tag_int, .False); } assert(isByRef(union_ty)); - // The llvm type of the alloca will the the named LLVM union type, which will not + // The llvm type of the alloca will be the named LLVM union type, and will not // necessarily match the format that we need, depending on which tag is active. We // must construct the correct unnamed struct type here and bitcast, in order to // then set the fields appropriately. @@ -8922,7 +8922,7 @@ pub const FuncGen = struct { const fields: [2]*llvm.Type = .{ field_llvm_ty, self.context.intType(8).arrayType(padding_len), }; - break :p self.context.structType(&fields, fields.len, .False); + break :p self.context.structType(&fields, fields.len, .True); }; if (layout.tag_size == 0) { const fields: [1]*llvm.Type = .{payload}; diff --git a/test/behavior.zig b/test/behavior.zig index 6c181d38bb..6a6844a840 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -100,6 +100,7 @@ test { _ = @import("behavior/bugs/12928.zig"); _ = @import("behavior/bugs/12945.zig"); _ = @import("behavior/bugs/12984.zig"); + _ = @import("behavior/bugs/13128.zig"); _ = @import("behavior/byteswap.zig"); _ = @import("behavior/byval_arg_var.zig"); _ = @import("behavior/call.zig"); diff --git a/test/behavior/bugs/13128.zig b/test/behavior/bugs/13128.zig new file mode 100644 index 0000000000..057270a96f --- /dev/null +++ b/test/behavior/bugs/13128.zig @@ -0,0 +1,29 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const expect = std.testing.expect; + +const U = union(enum) { + x: u128, + y: [17]u8, +}; + +fn foo(val: U) !void { + try expect(val.x == 1); +} + +test "runtime union init, most-aligned field != largest" { + 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 + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + + var x: u8 = 1; + try foo(.{ .x = x }); + + const val: U = @unionInit(U, "x", x); + try expect(val.x == 1); + + const val2: U = .{ .x = x }; + try expect(val2.x == 1); +}