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.
This commit is contained in:
kcbanner 2023-09-24 18:38:14 -04:00 committed by Andrew Kelley
parent 8fab4f98c4
commit e7bf143b36
2 changed files with 19 additions and 0 deletions

View File

@ -1244,6 +1244,7 @@ pub const Type = struct {
.array_type => |array_type| { .array_type => |array_type| {
const len = array_type.len + @intFromBool(array_type.sentinel != .none); 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)) { switch (try array_type.child.toType().abiSizeAdvanced(mod, strat)) {
.scalar => |elem_size| return .{ .scalar = len * elem_size }, .scalar => |elem_size| return .{ .scalar = len * elem_size },
.val => switch (strat) { .val => switch (strat) {

View File

@ -995,6 +995,24 @@ test "struct with union field" {
try expect(True.kind.Bool); 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" { test "type coercion of anon struct literal to struct" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO