authorgravatar for r00ster91@proton.meWooster <r00ster91@proton.me> 2023-05-01 19:15:51+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-05-09 11:58:34+03:00
log297b5d1074008b52a8d08a32c9f3281542105bdd
treefbff3796a3c6bd3a214d2f9bfc68b58a77538ea1
parentf40539e5d83365412bf8c6973ce867125ea36faf

fix `[x]u65529` and above overflowing

``` $ cat overflow.zig test { var a: [1]u65535 = undefined; _ = a; } $ zig-out/bin/zig test overflow.zig thread 290266 panic: integer overflow zig/src/type.zig:3604:55: 0xada43d in intAbiAlignment (zig) std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8), ^ zig/src/type.zig:3598:42: 0xadd4ea in intAbiSize (zig) const alignment = intAbiAlignment(bits, target); ^ zig/src/type.zig:3500:61: 0x92be91 in abiSizeAdvanced (zig) return AbiSizeAdvanced{ .scalar = intAbiSize(bits, target) }; ^ zig/src/type.zig:3385:62: 0x928933 in abiSizeAdvanced (zig) switch (try payload.elem_type.abiSizeAdvanced(target, strat)) { ^ zig/src/type.zig:3268:32: 0x92c012 in abiSize (zig) return (abiSizeAdvanced(ty, target, .eager) catch unreachable).scalar; ^ ``` This is only noticed in a debug build of zig and silently does the wrong thing and overflows in release builds. This happened to `[x]u65529` and above because of the ` + 7` on a `u16`.

2 files changed, 23 insertions(+), 2 deletions(-)

src/type.zig+2-2
......@@ -3596,12 +3596,12 @@ pub const Type = extern union {
35963596
35973597 fn intAbiSize(bits: u16, target: Target) u64 {
35983598 const alignment = intAbiAlignment(bits, target);
3599 return std.mem.alignForwardGeneric(u64, (bits + 7) / 8, alignment);
3599 return std.mem.alignForwardGeneric(u64, @intCast(u16, (@as(u17, bits) + 7) / 8), alignment);
36003600 }
36013601
36023602 fn intAbiAlignment(bits: u16, target: Target) u32 {
36033603 return @min(
3604 std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8),
3604 std.math.ceilPowerOfTwoPromote(u16, @intCast(u16, (@as(u17, bits) + 7) / 8)),
36053605 target.maxIntAlignment(),
36063606 );
36073607 }
test/behavior/basic.zig+21
......@@ -1124,3 +1124,24 @@ test "runtime-known globals initialized with undefined" {
11241124 try expect(S.s[0] == 1);
11251125 try expect(S.s[4] == 5);
11261126}
1127
1128test "arrays and vectors with big integers" {
1129 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1130 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
1131 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1132 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1133 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1134
1135 // TODO: only aarch64-windows didn't pass in the PR that added this code.
1136 // figure out why if you can run this target.
1137 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64) return error.SkipZigTest;
1138
1139 inline for (.{ u65528, u65529, u65535 }) |Int| {
1140 var a: [1]Int = undefined;
1141 a[0] = std.math.maxInt(Int);
1142 try expect(a[0] == comptime std.math.maxInt(Int));
1143 var b: @Vector(1, Int) = undefined;
1144 b[0] = std.math.maxInt(Int);
1145 try expect(b[0] == comptime std.math.maxInt(Int));
1146 }
1147}