authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-03-20 18:05:52+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-03-21 00:34:12+02:00
log773b1c4c5cdf9fde19cbf09d0f81f1bfe27ed7ca
tree61c419ac3a8f30d31ad1f6190ca7b7a08af2f249
parent0c169127338ef8af752d1a077e412b5135e300d5

llvm: fix lowering packed union initiated to zero-bit value

Closes #14980

2 files changed, 22 insertions(+), 0 deletions(-)

src/codegen/llvm.zig+2
...@@ -3815,6 +3815,8 @@ pub const DeclGen = struct {...@@ -3815,6 +3815,8 @@ pub const DeclGen = struct {
38153815
3816 const field_ty = union_obj.fields.values()[field_index].ty;3816 const field_ty = union_obj.fields.values()[field_index].ty;
3817 if (union_obj.layout == .Packed) {3817 if (union_obj.layout == .Packed) {
3818 if (!field_ty.hasRuntimeBits())
3819 return llvm_union_ty.constNull();
3818 const non_int_val = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val });3820 const non_int_val = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val });
3819 const ty_bit_size = @intCast(u16, field_ty.bitSize(target));3821 const ty_bit_size = @intCast(u16, field_ty.bitSize(target));
3820 const small_int_ty = dg.context.intType(ty_bit_size);3822 const small_int_ty = dg.context.intType(ty_bit_size);
test/behavior/union.zig+20
...@@ -1493,3 +1493,23 @@ test "union reassignment can use previous value" {...@@ -1493,3 +1493,23 @@ test "union reassignment can use previous value" {
1493 a = U{ .b = a.a };1493 a = U{ .b = a.a };
1494 try expect(a.b == 32);1494 try expect(a.b == 32);
1495}1495}
1496
1497test "packed union with zero-bit field" {
1498 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1499 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1500 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1501 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1502
1503 const S = packed struct {
1504 nested: packed union {
1505 zero: void,
1506 sized: u32,
1507 },
1508 bar: u32,
1509
1510 fn doTest(self: @This()) !void {
1511 try expect(self.bar == 42);
1512 }
1513 };
1514 try S.doTest(.{ .nested = .{ .zero = {} }, .bar = 42 });
1515}