Commit 9c0f3163a8

Veikka Tuominen <git@vexu.eu>
2022-12-22 11:45:51
value: fix bitcasting packed structs with `u0` fields
Closes #13942
1 parent b7730c7
Changed files (2)
src
test
behavior
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)),
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);
+}