authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2023-09-24 18:38:14-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-25 05:24:55-07:00
loge7bf143b364f004a76e86cad5fd3256fa87761e4
tree2732efe1bc7912c7ef10578213e2d529318bedcd
parent8fab4f98c4ee511ba56fec2f38e2d80535c327a9

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.

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

src/type.zig+1
...@@ -1244,6 +1244,7 @@ pub const Type = struct {...@@ -1244,6 +1244,7 @@ pub const Type = struct {
12441244
1245 .array_type => |array_type| {1245 .array_type => |array_type| {
1246 const len = array_type.len + @intFromBool(array_type.sentinel != .none);1246 const len = array_type.len + @intFromBool(array_type.sentinel != .none);
1247 if (len == 0) return .{ .scalar = 0 };
1247 switch (try array_type.child.toType().abiSizeAdvanced(mod, strat)) {1248 switch (try array_type.child.toType().abiSizeAdvanced(mod, strat)) {
1248 .scalar => |elem_size| return .{ .scalar = len * elem_size },1249 .scalar => |elem_size| return .{ .scalar = len * elem_size },
1249 .val => switch (strat) {1250 .val => switch (strat) {
test/behavior/struct.zig+18
...@@ -995,6 +995,24 @@ test "struct with union field" {...@@ -995,6 +995,24 @@ test "struct with union field" {
995 try expect(True.kind.Bool);995 try expect(True.kind.Bool);
996}996}
997997
998test "struct with 0-length union array field" {
999 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1000 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1001 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1002
1003 const U = union {
1004 a: u32,
1005 b: u64,
1006 };
1007
1008 const S = struct {
1009 zero_length: [0]U,
1010 };
1011
1012 var s: S = undefined;
1013 try expectEqual(@as(usize, 0), s.zero_length.len);
1014}
1015
998test "type coercion of anon struct literal to struct" {1016test "type coercion of anon struct literal to struct" {
999 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1017 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1000 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1018 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO