From c3d638a48ce4d3dcb9ac7f2c272070981b58e092 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Thu, 22 Dec 2022 12:45:51 +0200 Subject: [PATCH] value: fix bitcasting packed structs with `u0` fields Closes #13942 --- src/value.zig | 2 ++ test/behavior/cast.zig | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/value.zig b/src/value.zig index c86e5ab12c1a..eeb1228ebc04 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1378,6 +1378,7 @@ pub const Value = extern union { var enum_buffer: Payload.U64 = undefined; const int_val = val.enumToInt(ty, &enum_buffer); + if (abi_size == 0) return; if (abi_size <= @sizeOf(u64)) { const int: u64 = switch (int_val.tag()) { .zero => 0, @@ -1571,6 +1572,7 @@ pub const Value = extern union { const abi_size = @intCast(usize, ty.abiSize(target)); const bits = int_info.bits; + if (bits == 0) return Value.zero; if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u64 .signed => return Value.Tag.int_i64.create(arena, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)), .unsigned => return Value.Tag.int_u64.create(arena, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)), diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 0b276deba703..08066edc73bc 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -1505,3 +1505,16 @@ test "implicit cast from [:0]T to [*c]T" { try expect(c.len == a.len); try expect(c.ptr == a.ptr); } + +test "bitcast packed struct with u0" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + + const S = packed struct(u2) { a: u0, b: u2 }; + const s = @bitCast(S, @as(u2, 2)); + try expect(s.a == 0); + try expect(s.b == 2); + const i = @bitCast(u2, s); + try expect(i == 2); +}