zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit e7bf143b364f004a76e86cad5fd3256fa87761e4 (tree)
parent 8fab4f98c4ee511ba56fec2f38e2d80535c327a9
Author: kcbanner <kcbanner@gmail.com>
Date:   Sun, 24 Sep 2023 18:38:14 -0400

type: handle the 0-length array case in abiSizeAdvanced

This fixes a panic in `unionAbiSize` when a 0-length array of a union is used as a struct field.

Because `resolveTypeLayout` does not resolve the `elem_ty` if `arrayLenIncludingSentinel` returns
0 for the array, the child union type is not guaranteed to have a resolved layout at this point.

Fixed this case by just returning 0 here.

Diffstat:
Msrc/type.zig | 1+
Mtest/behavior/struct.zig | 18++++++++++++++++++
2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/src/type.zig b/src/type.zig @@ -1244,6 +1244,7 @@ pub const Type = struct { .array_type => |array_type| { const len = array_type.len + @intFromBool(array_type.sentinel != .none); + if (len == 0) return .{ .scalar = 0 }; switch (try array_type.child.toType().abiSizeAdvanced(mod, strat)) { .scalar => |elem_size| return .{ .scalar = len * elem_size }, .val => switch (strat) { diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig @@ -995,6 +995,24 @@ test "struct with union field" { try expect(True.kind.Bool); } +test "struct with 0-length union array field" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + + const U = union { + a: u32, + b: u64, + }; + + const S = struct { + zero_length: [0]U, + }; + + var s: S = undefined; + try expectEqual(@as(usize, 0), s.zero_length.len); +} + test "type coercion of anon struct literal to struct" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO