| ... | @@ -828,56 +828,72 @@ test "128-bit multiplication" { | ... | @@ -828,56 +828,72 @@ test "128-bit multiplication" { |
| 828 | } | 828 | } |
| 829 | } | 829 | } |
| 830 | | 830 | |
| | 831 | fn testAddWithOverflow(comptime T: type, a: T, b: T, add: T, bit: u1) !void { |
| | 832 | const ov = @addWithOverflow(a, b); |
| | 833 | try expect(ov[0] == add); |
| | 834 | try expect(ov[1] == bit); |
| | 835 | } |
| | 836 | |
| 831 | test "@addWithOverflow" { | 837 | test "@addWithOverflow" { |
| 832 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 838 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 833 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 839 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 834 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 840 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 835 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 841 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 836 | | 842 | |
| 837 | { | 843 | try testAddWithOverflow(u8, 250, 100, 94, 1); |
| 838 | var a: u8 = 250; | 844 | try testAddWithOverflow(u8, 100, 150, 250, 0); |
| 839 | _ = &a; | | |
| 840 | const ov = @addWithOverflow(a, 100); | | |
| 841 | try expect(ov[0] == 94); | | |
| 842 | try expect(ov[1] == 1); | | |
| 843 | } | | |
| 844 | { | | |
| 845 | var a: u8 = 100; | | |
| 846 | _ = &a; | | |
| 847 | const ov = @addWithOverflow(a, 150); | | |
| 848 | try expect(ov[0] == 250); | | |
| 849 | try expect(ov[1] == 0); | | |
| 850 | } | | |
| 851 | { | | |
| 852 | var a: u8 = 200; | | |
| 853 | _ = &a; | | |
| 854 | var b: u8 = 99; | | |
| 855 | var ov = @addWithOverflow(a, b); | | |
| 856 | try expect(ov[0] == 43); | | |
| 857 | try expect(ov[1] == 1); | | |
| 858 | b = 55; | | |
| 859 | ov = @addWithOverflow(a, b); | | |
| 860 | try expect(ov[0] == 255); | | |
| 861 | try expect(ov[1] == 0); | | |
| 862 | } | | |
| 863 | | 845 | |
| 864 | { | 846 | try testAddWithOverflow(u8, 200, 99, 43, 1); |
| 865 | var a: usize = 6; | 847 | try testAddWithOverflow(u8, 200, 55, 255, 0); |
| 866 | var b: usize = 6; | | |
| 867 | _ = .{ &a, &b }; | | |
| 868 | const ov = @addWithOverflow(a, b); | | |
| 869 | try expect(ov[0] == 12); | | |
| 870 | try expect(ov[1] == 0); | | |
| 871 | } | | |
| 872 | | 848 | |
| 873 | { | 849 | try testAddWithOverflow(usize, 6, 6, 12, 0); |
| 874 | var a: isize = -6; | 850 | try testAddWithOverflow(usize, maxInt(usize), 6, 5, 1); |
| 875 | var b: isize = -6; | 851 | |
| 876 | _ = .{ &a, &b }; | 852 | try testAddWithOverflow(isize, -6, -6, -12, 0); |
| 877 | const ov = @addWithOverflow(a, b); | 853 | try testAddWithOverflow(isize, minInt(isize), -6, maxInt(isize) - 5, 1); |
| 878 | try expect(ov[0] == -12); | 854 | } |
| 879 | try expect(ov[1] == 0); | 855 | |
| 880 | } | 856 | test "@addWithOverflow > 64 bits" { |
| | 857 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| | 858 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| | 859 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| | 860 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| | 861 | |
| | 862 | try testAddWithOverflow(u65, 4, 105, 109, 0); |
| | 863 | try testAddWithOverflow(u65, 1000, 100, 1100, 0); |
| | 864 | try testAddWithOverflow(u65, 100, maxInt(u65) - 99, 0, 1); |
| | 865 | try testAddWithOverflow(u65, maxInt(u65), maxInt(u65), maxInt(u65) - 1, 1); |
| | 866 | try testAddWithOverflow(u65, maxInt(u65) - 1, maxInt(u65), maxInt(u65) - 2, 1); |
| | 867 | try testAddWithOverflow(u65, maxInt(u65), maxInt(u65) - 1, maxInt(u65) - 2, 1); |
| | 868 | |
| | 869 | try testAddWithOverflow(u128, 4, 105, 109, 0); |
| | 870 | try testAddWithOverflow(u128, 1000, 100, 1100, 0); |
| | 871 | try testAddWithOverflow(u128, 100, maxInt(u128) - 99, 0, 1); |
| | 872 | try testAddWithOverflow(u128, maxInt(u128), maxInt(u128), maxInt(u128) - 1, 1); |
| | 873 | try testAddWithOverflow(u128, maxInt(u128) - 1, maxInt(u128), maxInt(u128) - 2, 1); |
| | 874 | try testAddWithOverflow(u128, maxInt(u128), maxInt(u128) - 1, maxInt(u128) - 2, 1); |
| | 875 | |
| | 876 | try testAddWithOverflow(i65, 4, -105, -101, 0); |
| | 877 | try testAddWithOverflow(i65, 1000, 100, 1100, 0); |
| | 878 | try testAddWithOverflow(i65, minInt(i65), 1, minInt(i65) + 1, 0); |
| | 879 | try testAddWithOverflow(i65, maxInt(i65), minInt(i65), -1, 0); |
| | 880 | try testAddWithOverflow(i65, minInt(i65), maxInt(i65), -1, 0); |
| | 881 | try testAddWithOverflow(i65, maxInt(i65), -2, maxInt(i65) - 2, 0); |
| | 882 | try testAddWithOverflow(i65, maxInt(i65), maxInt(i65), -2, 1); |
| | 883 | try testAddWithOverflow(i65, minInt(i65), minInt(i65), 0, 1); |
| | 884 | try testAddWithOverflow(i65, maxInt(i65) - 1, maxInt(i65), -3, 1); |
| | 885 | try testAddWithOverflow(i65, maxInt(i65), maxInt(i65) - 1, -3, 1); |
| | 886 | |
| | 887 | try testAddWithOverflow(i128, 4, -105, -101, 0); |
| | 888 | try testAddWithOverflow(i128, 1000, 100, 1100, 0); |
| | 889 | try testAddWithOverflow(i128, minInt(i128), 1, minInt(i128) + 1, 0); |
| | 890 | try testAddWithOverflow(i128, maxInt(i128), minInt(i128), -1, 0); |
| | 891 | try testAddWithOverflow(i128, minInt(i128), maxInt(i128), -1, 0); |
| | 892 | try testAddWithOverflow(i128, maxInt(i128), -2, maxInt(i128) - 2, 0); |
| | 893 | try testAddWithOverflow(i128, maxInt(i128), maxInt(i128), -2, 1); |
| | 894 | try testAddWithOverflow(i128, minInt(i128), minInt(i128), 0, 1); |
| | 895 | try testAddWithOverflow(i128, maxInt(i128) - 1, maxInt(i128), -3, 1); |
| | 896 | try testAddWithOverflow(i128, maxInt(i128), maxInt(i128) - 1, -3, 1); |
| 881 | } | 897 | } |
| 882 | | 898 | |
| 883 | test "small int addition" { | 899 | test "small int addition" { |
| ... | @@ -1265,56 +1281,68 @@ test "@mulWithOverflow u256" { | ... | @@ -1265,56 +1281,68 @@ test "@mulWithOverflow u256" { |
| 1265 | } | 1281 | } |
| 1266 | } | 1282 | } |
| 1267 | | 1283 | |
| | 1284 | fn testSubWithOverflow(comptime T: type, a: T, b: T, sub: T, bit: u1) !void { |
| | 1285 | const ov = @subWithOverflow(a, b); |
| | 1286 | try expect(ov[0] == sub); |
| | 1287 | try expect(ov[1] == bit); |
| | 1288 | } |
| | 1289 | |
| 1268 | test "@subWithOverflow" { | 1290 | test "@subWithOverflow" { |
| 1269 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1291 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1270 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1292 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1271 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1293 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1272 | | 1294 | |
| 1273 | { | 1295 | try testSubWithOverflow(u8, 1, 2, 255, 1); |
| 1274 | var a: u8 = 1; | 1296 | try testSubWithOverflow(u8, 1, 1, 0, 0); |
| 1275 | _ = &a; | | |
| 1276 | const ov = @subWithOverflow(a, 2); | | |
| 1277 | try expect(ov[0] == 255); | | |
| 1278 | try expect(ov[1] == 1); | | |
| 1279 | } | | |
| 1280 | { | | |
| 1281 | var a: u8 = 1; | | |
| 1282 | _ = &a; | | |
| 1283 | const ov = @subWithOverflow(a, 1); | | |
| 1284 | try expect(ov[0] == 0); | | |
| 1285 | try expect(ov[1] == 0); | | |
| 1286 | } | | |
| 1287 | | 1297 | |
| 1288 | { | 1298 | try testSubWithOverflow(u16, 10000, 10002, 65534, 1); |
| 1289 | var a: u8 = 1; | 1299 | try testSubWithOverflow(u16, 10000, 9999, 1, 0); |
| 1290 | _ = &a; | | |
| 1291 | var b: u8 = 2; | | |
| 1292 | var ov = @subWithOverflow(a, b); | | |
| 1293 | try expect(ov[0] == 255); | | |
| 1294 | try expect(ov[1] == 1); | | |
| 1295 | b = 1; | | |
| 1296 | ov = @subWithOverflow(a, b); | | |
| 1297 | try expect(ov[0] == 0); | | |
| 1298 | try expect(ov[1] == 0); | | |
| 1299 | } | | |
| 1300 | | 1300 | |
| 1301 | { | 1301 | try testSubWithOverflow(usize, 6, 6, 0, 0); |
| 1302 | var a: usize = 6; | 1302 | try testSubWithOverflow(usize, 6, 7, maxInt(usize), 1); |
| 1303 | var b: usize = 6; | 1303 | try testSubWithOverflow(isize, -6, -6, 0, 0); |
| 1304 | _ = .{ &a, &b }; | 1304 | try testSubWithOverflow(isize, minInt(isize), 6, maxInt(isize) - 5, 1); |
| 1305 | const ov = @subWithOverflow(a, b); | 1305 | } |
| 1306 | try expect(ov[0] == 0); | | |
| 1307 | try expect(ov[1] == 0); | | |
| 1308 | } | | |
| 1309 | | 1306 | |
| 1310 | { | 1307 | test "@subWithOverflow > 64 bits" { |
| 1311 | var a: isize = -6; | 1308 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1312 | var b: isize = -6; | 1309 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1313 | _ = .{ &a, &b }; | 1310 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1314 | const ov = @subWithOverflow(a, b); | 1311 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1315 | try expect(ov[0] == 0); | 1312 | |
| 1316 | try expect(ov[1] == 0); | 1313 | try testSubWithOverflow(u65, 4, 105, maxInt(u65) - 100, 1); |
| 1317 | } | 1314 | try testSubWithOverflow(u65, 1000, 100, 900, 0); |
| | 1315 | try testSubWithOverflow(u65, maxInt(u65), maxInt(u65), 0, 0); |
| | 1316 | try testSubWithOverflow(u65, maxInt(u65) - 1, maxInt(u65), maxInt(u65), 1); |
| | 1317 | try testSubWithOverflow(u65, maxInt(u65), maxInt(u65) - 1, 1, 0); |
| | 1318 | |
| | 1319 | try testSubWithOverflow(u128, 4, 105, maxInt(u128) - 100, 1); |
| | 1320 | try testSubWithOverflow(u128, 1000, 100, 900, 0); |
| | 1321 | try testSubWithOverflow(u128, maxInt(u128), maxInt(u128), 0, 0); |
| | 1322 | try testSubWithOverflow(u128, maxInt(u128) - 1, maxInt(u128), maxInt(u128), 1); |
| | 1323 | try testSubWithOverflow(u128, maxInt(u128), maxInt(u128) - 1, 1, 0); |
| | 1324 | |
| | 1325 | try testSubWithOverflow(i65, 4, 105, -101, 0); |
| | 1326 | try testSubWithOverflow(i65, 1000, 100, 900, 0); |
| | 1327 | try testSubWithOverflow(i65, maxInt(i65), maxInt(i65), 0, 0); |
| | 1328 | try testSubWithOverflow(i65, minInt(i65), minInt(i65), 0, 0); |
| | 1329 | try testSubWithOverflow(i65, maxInt(i65) - 1, maxInt(i65), -1, 0); |
| | 1330 | try testSubWithOverflow(i65, maxInt(i65), maxInt(i65) - 1, 1, 0); |
| | 1331 | try testSubWithOverflow(i65, minInt(i65), 1, maxInt(i65), 1); |
| | 1332 | try testSubWithOverflow(i65, maxInt(i65), minInt(i65), -1, 1); |
| | 1333 | try testSubWithOverflow(i65, minInt(i65), maxInt(i65), 1, 1); |
| | 1334 | try testSubWithOverflow(i65, maxInt(i65), -2, minInt(i65) + 1, 1); |
| | 1335 | |
| | 1336 | try testSubWithOverflow(i128, 4, 105, -101, 0); |
| | 1337 | try testSubWithOverflow(i128, 1000, 100, 900, 0); |
| | 1338 | try testSubWithOverflow(i128, maxInt(i128), maxInt(i128), 0, 0); |
| | 1339 | try testSubWithOverflow(i128, minInt(i128), minInt(i128), 0, 0); |
| | 1340 | try testSubWithOverflow(i128, maxInt(i128) - 1, maxInt(i128), -1, 0); |
| | 1341 | try testSubWithOverflow(i128, maxInt(i128), maxInt(i128) - 1, 1, 0); |
| | 1342 | try testSubWithOverflow(i128, minInt(i128), 1, maxInt(i128), 1); |
| | 1343 | try testSubWithOverflow(i128, maxInt(i128), minInt(i128), -1, 1); |
| | 1344 | try testSubWithOverflow(i128, minInt(i128), maxInt(i128), 1, 1); |
| | 1345 | try testSubWithOverflow(i128, maxInt(i128), -2, minInt(i128) + 1, 1); |
| 1318 | } | 1346 | } |
| 1319 | | 1347 | |
| 1320 | test "@shlWithOverflow" { | 1348 | test "@shlWithOverflow" { |