| author | |
| committer | |
| log | 297b5d1074008b52a8d08a32c9f3281542105bdd |
| tree | fbff3796a3c6bd3a214d2f9bfc68b58a77538ea1 |
| parent | f40539e5d83365412bf8c6973ce867125ea36faf |
```
$ 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 { |
| 3596 | 3596 | |
| 3597 | 3597 | fn intAbiSize(bits: u16, target: Target) u64 { |
| 3598 | 3598 | 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); | |
| 3600 | 3600 | } |
| 3601 | 3601 | |
| 3602 | 3602 | fn intAbiAlignment(bits: u16, target: Target) u32 { |
| 3603 | 3603 | return @min( |
| 3604 | std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8), | |
| 3604 | std.math.ceilPowerOfTwoPromote(u16, @intCast(u16, (@as(u17, bits) + 7) / 8)), | |
| 3605 | 3605 | target.maxIntAlignment(), |
| 3606 | 3606 | ); |
| 3607 | 3607 | } |
test/behavior/basic.zig+21| ... | ... | @@ -1124,3 +1124,24 @@ test "runtime-known globals initialized with undefined" { |
| 1124 | 1124 | try expect(S.s[0] == 1); |
| 1125 | 1125 | try expect(S.s[4] == 5); |
| 1126 | 1126 | } |
| 1127 | ||
| 1128 | test "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 | } |