| author | |
| committer | |
| log | e7bf143b364f004a76e86cad5fd3256fa87761e4 |
| tree | 2732efe1bc7912c7ef10578213e2d529318bedcd |
| parent | 8fab4f98c4ee511ba56fec2f38e2d80535c327a9 |
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 | 1244 | |
| 1245 | 1245 | .array_type => |array_type| { |
| 1246 | 1246 | const len = array_type.len + @intFromBool(array_type.sentinel != .none); |
| 1247 | if (len == 0) return .{ .scalar = 0 }; | |
| 1247 | 1248 | switch (try array_type.child.toType().abiSizeAdvanced(mod, strat)) { |
| 1248 | 1249 | .scalar => |elem_size| return .{ .scalar = len * elem_size }, |
| 1249 | 1250 | .val => switch (strat) { |
test/behavior/struct.zig+18| ... | ... | @@ -995,6 +995,24 @@ test "struct with union field" { |
| 995 | 995 | try expect(True.kind.Bool); |
| 996 | 996 | } |
| 997 | 997 | |
| 998 | test "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 | ||
| 998 | 1016 | test "type coercion of anon struct literal to struct" { |
| 999 | 1017 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1000 | 1018 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |