Commit e7bf143b36

kcbanner <kcbanner@gmail.com>
2023-09-25 00:38:14
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.
1 parent 8fab4f9
Changed files (2)
src
test
behavior
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) {
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