From b5c22777f839f926ff3e272c9285d4d3e6402c0d Mon Sep 17 00:00:00 2001 From: dweiller <4678790+dweiller@users.noreply.github.com> Date: Wed, 9 Apr 2025 14:25:37 +1000 Subject: [PATCH] sema: do checked cast when resolving aggregate size --- src/Sema.zig | 20 ++++++++++-- .../compile_errors/aggregate_too_large.zig | 31 +++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 test/cases/compile_errors/aggregate_too_large.zig diff --git a/src/Sema.zig b/src/Sema.zig index 3403d1f030..a686a3d8f2 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -35540,7 +35540,15 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { offsets[i] = @intCast(aligns[i].forward(offset)); offset = offsets[i] + sizes[i]; } - struct_type.setLayoutResolved(ip, @intCast(big_align.forward(offset)), big_align); + const size = std.math.cast(u32, big_align.forward(offset)) orelse { + const msg = try sema.errMsg( + ty.srcLoc(zcu), + "struct layout requires size {d}, this compiler implementation supports up to {d}", + .{ big_align.forward(offset), std.math.maxInt(u32) }, + ); + return sema.failWithOwnedErrorMsg(null, msg); + }; + struct_type.setLayoutResolved(ip, size, big_align); _ = try ty.comptimeOnlySema(pt); } @@ -35815,7 +35823,15 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { break :layout .{ size, max_align.max(tag_align), padding }; } else .{ max_align.forward(max_size), max_align, 0 }; - union_type.setHaveLayout(ip, @intCast(size), padding, alignment); + const casted_size = std.math.cast(u32, size) orelse { + const msg = try sema.errMsg( + ty.srcLoc(pt.zcu), + "union layout requires size {d}, this compiler implementation supports up to {d}", + .{ size, std.math.maxInt(u32) }, + ); + return sema.failWithOwnedErrorMsg(null, msg); + }; + union_type.setHaveLayout(ip, casted_size, padding, alignment); if (union_type.flagsUnordered(ip).assumed_runtime_bits and !(try ty.hasRuntimeBitsSema(pt))) { const msg = try sema.errMsg( diff --git a/test/cases/compile_errors/aggregate_too_large.zig b/test/cases/compile_errors/aggregate_too_large.zig new file mode 100644 index 0000000000..4a4daeda93 --- /dev/null +++ b/test/cases/compile_errors/aggregate_too_large.zig @@ -0,0 +1,31 @@ +const S = struct { + data: [1 << 32]u8, +}; + +const T = struct { + d1: [1 << 31]u8, + d2: [1 << 31]u8, +}; + +const U = union { + a: u32, + b: [1 << 32]u8, +}; + +const V = union { + a: u32, + b: T, +}; + +comptime { + _ = S; + _ = T; + _ = U; + _ = V; +} + +// error +// +// :1:11: error: struct layout requires size 4294967296, this compiler implementation supports up to 4294967295 +// :5:11: error: struct layout requires size 4294967296, this compiler implementation supports up to 4294967295 +// :10:11: error: union layout requires size 4294967300, this compiler implementation supports up to 4294967295