authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-22 12:45:51+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-27 15:33:27+02:00
log9c0f3163a876859d3cf10c8b57d81cae381c46dc
tree194842cd1aea1e311200392f118e5b22c8eb0aea
parentb7730c74789d8f34748e516398de892646e88bc6

value: fix bitcasting packed structs with `u0` fields

Closes #13942

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

src/value.zig+2
...@@ -1378,6 +1378,7 @@ pub const Value = extern union {...@@ -1378,6 +1378,7 @@ pub const Value = extern union {
1378 var enum_buffer: Payload.U64 = undefined;1378 var enum_buffer: Payload.U64 = undefined;
1379 const int_val = val.enumToInt(ty, &enum_buffer);1379 const int_val = val.enumToInt(ty, &enum_buffer);
13801380
1381 if (abi_size == 0) return;
1381 if (abi_size <= @sizeOf(u64)) {1382 if (abi_size <= @sizeOf(u64)) {
1382 const int: u64 = switch (int_val.tag()) {1383 const int: u64 = switch (int_val.tag()) {
1383 .zero => 0,1384 .zero => 0,
...@@ -1571,6 +1572,7 @@ pub const Value = extern union {...@@ -1571,6 +1572,7 @@ pub const Value = extern union {
1571 const abi_size = @intCast(usize, ty.abiSize(target));1572 const abi_size = @intCast(usize, ty.abiSize(target));
15721573
1573 const bits = int_info.bits;1574 const bits = int_info.bits;
1575 if (bits == 0) return Value.zero;
1574 if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u641576 if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u64
1575 .signed => return Value.Tag.int_i64.create(arena, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)),1577 .signed => return Value.Tag.int_i64.create(arena, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)),
1576 .unsigned => return Value.Tag.int_u64.create(arena, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)),1578 .unsigned => return Value.Tag.int_u64.create(arena, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)),
test/behavior/cast.zig+13
...@@ -1505,3 +1505,16 @@ test "implicit cast from [:0]T to [*c]T" {...@@ -1505,3 +1505,16 @@ test "implicit cast from [:0]T to [*c]T" {
1505 try expect(c.len == a.len);1505 try expect(c.len == a.len);
1506 try expect(c.ptr == a.ptr);1506 try expect(c.ptr == a.ptr);
1507}1507}
1508
1509test "bitcast packed struct with u0" {
1510 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1511 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1512 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1513
1514 const S = packed struct(u2) { a: u0, b: u2 };
1515 const s = @bitCast(S, @as(u2, 2));
1516 try expect(s.a == 0);
1517 try expect(s.b == 2);
1518 const i = @bitCast(u2, s);
1519 try expect(i == 2);
1520}