Skip to content

Commit d81a68c

Browse files
committed
update uses of overflow arithmetic builtins
1 parent 3e39cd5 commit d81a68c

28 files changed

+540
-403
lines changed

lib/compiler_rt/trunctfxf2.zig

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,16 @@ pub fn __trunctfxf2(a: f128) callconv(.C) f80 {
4949
const round_bits = a_abs & round_mask;
5050
if (round_bits > halfway) {
5151
// Round to nearest
52-
const carry = @boolToInt(@addWithOverflow(u64, res.fraction, 1, &res.fraction));
53-
res.exp += carry;
54-
res.fraction |= @as(u64, carry) << 63; // Restore integer bit after carry
52+
const ov = @addWithOverflow(res.fraction, 1);
53+
res.fraction = ov[0];
54+
res.exp += ov[1];
55+
res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry
5556
} else if (round_bits == halfway) {
5657
// Ties to even
57-
const carry = @boolToInt(@addWithOverflow(u64, res.fraction, res.fraction & 1, &res.fraction));
58-
res.exp += carry;
59-
res.fraction |= @as(u64, carry) << 63; // Restore integer bit after carry
58+
const ov = @addWithOverflow(res.fraction, res.fraction & 1);
59+
res.fraction = ov[0];
60+
res.exp += ov[1];
61+
res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry
6062
}
6163
if (res.exp == 0) res.fraction &= ~@as(u64, integer_bit); // Remove integer bit for de-normals
6264
}

lib/std/compress/deflate/compressor_test.zig

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,7 @@ test "deflate/inflate" {
172172
defer testing.allocator.free(large_data_chunk);
173173
// fill with random data
174174
for (large_data_chunk) |_, i| {
175-
var mul: u8 = @truncate(u8, i);
176-
_ = @mulWithOverflow(u8, mul, mul, &mul);
177-
large_data_chunk[i] = mul;
175+
large_data_chunk[i] = @truncate(u8, i) *% @truncate(u8, i);
178176
}
179177
try testToFromWithLimit(large_data_chunk, limits);
180178
}

lib/std/crypto/pcurves/p256/p256_64.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ pub const NonMontgomeryDomainFieldElement = [4]u64;
7575
inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
7676
@setRuntimeSafety(mode == .Debug);
7777

78-
var t: u64 = undefined;
79-
const carry1 = @addWithOverflow(u64, arg2, arg3, &t);
80-
const carry2 = @addWithOverflow(u64, t, arg1, out1);
81-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
78+
const ov1 = @addWithOverflow(arg2, arg3);
79+
const ov2 = @addWithOverflow(ov1[0], arg1);
80+
out1.* = ov2[0];
81+
out2.* = ov1[1] | ov2[1];
8282
}
8383

8484
/// The function subborrowxU64 is a subtraction with borrow.
@@ -97,10 +97,10 @@ inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) vo
9797
inline fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
9898
@setRuntimeSafety(mode == .Debug);
9999

100-
var t: u64 = undefined;
101-
const carry1 = @subWithOverflow(u64, arg2, arg3, &t);
102-
const carry2 = @subWithOverflow(u64, t, arg1, out1);
103-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
100+
const ov1 = @subWithOverflow(arg2, arg3);
101+
const ov2 = @subWithOverflow(ov1[0], arg1);
102+
out1.* = ov2[0];
103+
out2.* = ov1[1] | ov2[1];
104104
}
105105

106106
/// The function mulxU64 is a multiplication, returning the full double-width result.

lib/std/crypto/pcurves/p256/p256_scalar_64.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ pub const NonMontgomeryDomainFieldElement = [4]u64;
7575
inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
7676
@setRuntimeSafety(mode == .Debug);
7777

78-
var t: u64 = undefined;
79-
const carry1 = @addWithOverflow(u64, arg2, arg3, &t);
80-
const carry2 = @addWithOverflow(u64, t, arg1, out1);
81-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
78+
const ov1 = @addWithOverflow(arg2, arg3);
79+
const ov2 = @addWithOverflow(ov1[0], arg1);
80+
out1.* = ov2[0];
81+
out2.* = ov1[1] | ov2[1];
8282
}
8383

8484
/// The function subborrowxU64 is a subtraction with borrow.
@@ -97,10 +97,10 @@ inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) vo
9797
inline fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
9898
@setRuntimeSafety(mode == .Debug);
9999

100-
var t: u64 = undefined;
101-
const carry1 = @subWithOverflow(u64, arg2, arg3, &t);
102-
const carry2 = @subWithOverflow(u64, t, arg1, out1);
103-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
100+
const ov1 = @subWithOverflow(arg2, arg3);
101+
const ov2 = @subWithOverflow(ov1[0], arg1);
102+
out1.* = ov2[0];
103+
out2.* = ov1[1] | ov2[1];
104104
}
105105

106106
/// The function mulxU64 is a multiplication, returning the full double-width result.

lib/std/crypto/pcurves/p384/p384_64.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ pub const NonMontgomeryDomainFieldElement = [6]u64;
4444
inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
4545
@setRuntimeSafety(mode == .Debug);
4646

47-
var t: u64 = undefined;
48-
const carry1 = @addWithOverflow(u64, arg2, arg3, &t);
49-
const carry2 = @addWithOverflow(u64, t, arg1, out1);
50-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
47+
const ov1 = @addWithOverflow(arg2, arg3);
48+
const ov2 = @addWithOverflow(ov1[0], arg1);
49+
out1.* = ov2[0];
50+
out2.* = ov1[1] | ov2[1];
5151
}
5252

5353
/// The function subborrowxU64 is a subtraction with borrow.
@@ -66,10 +66,10 @@ inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) vo
6666
inline fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
6767
@setRuntimeSafety(mode == .Debug);
6868

69-
var t: u64 = undefined;
70-
const carry1 = @subWithOverflow(u64, arg2, arg3, &t);
71-
const carry2 = @subWithOverflow(u64, t, arg1, out1);
72-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
69+
const ov1 = @subWithOverflow(arg2, arg3);
70+
const ov2 = @subWithOverflow(ov1[0], arg1);
71+
out1.* = ov2[0];
72+
out2.* = ov1[1] | ov2[1];
7373
}
7474

7575
/// The function mulxU64 is a multiplication, returning the full double-width result.

lib/std/crypto/pcurves/p384/p384_scalar_64.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ pub const NonMontgomeryDomainFieldElement = [6]u64;
4444
inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
4545
@setRuntimeSafety(mode == .Debug);
4646

47-
var t: u64 = undefined;
48-
const carry1 = @addWithOverflow(u64, arg2, arg3, &t);
49-
const carry2 = @addWithOverflow(u64, t, arg1, out1);
50-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
47+
const ov1 = @addWithOverflow(arg2, arg3);
48+
const ov2 = @addWithOverflow(ov1[0], arg1);
49+
out1.* = ov2[0];
50+
out2.* = ov1[1] | ov2[1];
5151
}
5252

5353
/// The function subborrowxU64 is a subtraction with borrow.
@@ -66,10 +66,10 @@ inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) vo
6666
inline fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
6767
@setRuntimeSafety(mode == .Debug);
6868

69-
var t: u64 = undefined;
70-
const carry1 = @subWithOverflow(u64, arg2, arg3, &t);
71-
const carry2 = @subWithOverflow(u64, t, arg1, out1);
72-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
69+
const ov1 = @subWithOverflow(arg2, arg3);
70+
const ov2 = @subWithOverflow(ov1[0], arg1);
71+
out1.* = ov2[0];
72+
out2.* = ov1[1] | ov2[1];
7373
}
7474

7575
/// The function mulxU64 is a multiplication, returning the full double-width result.

lib/std/crypto/pcurves/secp256k1/secp256k1_64.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ pub const NonMontgomeryDomainFieldElement = [4]u64;
4444
inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
4545
@setRuntimeSafety(mode == .Debug);
4646

47-
var t: u64 = undefined;
48-
const carry1 = @addWithOverflow(u64, arg2, arg3, &t);
49-
const carry2 = @addWithOverflow(u64, t, arg1, out1);
50-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
47+
const ov1 = @addWithOverflow(arg2, arg3);
48+
const ov2 = @addWithOverflow(ov1[0], arg1);
49+
out1.* = ov2[0];
50+
out2.* = ov1[1] | ov2[1];
5151
}
5252

5353
/// The function subborrowxU64 is a subtraction with borrow.
@@ -66,10 +66,10 @@ inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) vo
6666
inline fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
6767
@setRuntimeSafety(mode == .Debug);
6868

69-
var t: u64 = undefined;
70-
const carry1 = @subWithOverflow(u64, arg2, arg3, &t);
71-
const carry2 = @subWithOverflow(u64, t, arg1, out1);
72-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
69+
const ov1 = @subWithOverflow(arg2, arg3);
70+
const ov2 = @subWithOverflow(ov1[0], arg1);
71+
out1.* = ov2[0];
72+
out2.* = ov1[1] | ov2[1];
7373
}
7474

7575
/// The function mulxU64 is a multiplication, returning the full double-width result.

lib/std/crypto/pcurves/secp256k1/secp256k1_scalar_64.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ pub const NonMontgomeryDomainFieldElement = [4]u64;
4444
inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
4545
@setRuntimeSafety(mode == .Debug);
4646

47-
var t: u64 = undefined;
48-
const carry1 = @addWithOverflow(u64, arg2, arg3, &t);
49-
const carry2 = @addWithOverflow(u64, t, arg1, out1);
50-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
47+
const ov1 = @addWithOverflow(arg2, arg3);
48+
const ov2 = @addWithOverflow(ov1[0], arg1);
49+
out1.* = ov2[0];
50+
out2.* = ov1[1] | ov2[1];
5151
}
5252

5353
/// The function subborrowxU64 is a subtraction with borrow.
@@ -66,10 +66,10 @@ inline fn addcarryxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) vo
6666
inline fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void {
6767
@setRuntimeSafety(mode == .Debug);
6868

69-
var t: u64 = undefined;
70-
const carry1 = @subWithOverflow(u64, arg2, arg3, &t);
71-
const carry2 = @subWithOverflow(u64, t, arg1, out1);
72-
out2.* = @boolToInt(carry1) | @boolToInt(carry2);
69+
const ov1 = @subWithOverflow(arg2, arg3);
70+
const ov2 = @subWithOverflow(ov1[0], arg1);
71+
out1.* = ov2[0];
72+
out2.* = ov1[1] | ov2[1];
7373
}
7474

7575
/// The function mulxU64 is a multiplication, returning the full double-width result.

lib/std/crypto/salsa20.zig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,9 @@ fn SalsaNonVecImpl(comptime rounds: comptime_int) type {
263263
while (j < 64) : (j += 1) {
264264
xout[j] ^= buf[j];
265265
}
266-
ctx[9] += @boolToInt(@addWithOverflow(u32, ctx[8], 1, &ctx[8]));
266+
const ov = @addWithOverflow(ctx[8], 1);
267+
ctx[8] = ov[0];
268+
ctx[9] += ov[1];
267269
}
268270
if (i < in.len) {
269271
salsaCore(x[0..], ctx, true);

lib/std/crypto/utils.zig

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,19 @@ pub fn timingSafeAdd(comptime T: type, a: []const T, b: []const T, result: []T,
8787
if (endian == .Little) {
8888
var i: usize = 0;
8989
while (i < len) : (i += 1) {
90-
const tmp = @boolToInt(@addWithOverflow(u8, a[i], b[i], &result[i]));
91-
carry = tmp | @boolToInt(@addWithOverflow(u8, result[i], carry, &result[i]));
90+
const ov1 = @addWithOverflow(a[i], b[i]);
91+
const ov2 = @addWithOverflow(ov1[0], carry);
92+
result[i] = ov2[0];
93+
carry = ov1[1] | ov2[1];
9294
}
9395
} else {
9496
var i: usize = len;
9597
while (i != 0) {
9698
i -= 1;
97-
const tmp = @boolToInt(@addWithOverflow(u8, a[i], b[i], &result[i]));
98-
carry = tmp | @boolToInt(@addWithOverflow(u8, result[i], carry, &result[i]));
99+
const ov1 = @addWithOverflow(a[i], b[i]);
100+
const ov2 = @addWithOverflow(ov1[0], carry);
101+
result[i] = ov2[0];
102+
carry = ov1[1] | ov2[1];
99103
}
100104
}
101105
return @bitCast(bool, carry);
@@ -110,15 +114,19 @@ pub fn timingSafeSub(comptime T: type, a: []const T, b: []const T, result: []T,
110114
if (endian == .Little) {
111115
var i: usize = 0;
112116
while (i < len) : (i += 1) {
113-
const tmp = @boolToInt(@subWithOverflow(u8, a[i], b[i], &result[i]));
114-
borrow = tmp | @boolToInt(@subWithOverflow(u8, result[i], borrow, &result[i]));
117+
const ov1 = @subWithOverflow(a[i], b[i]);
118+
const ov2 = @subWithOverflow(ov1[0], borrow);
119+
result[i] = ov2[0];
120+
borrow = ov1[1] | ov2[1];
115121
}
116122
} else {
117123
var i: usize = len;
118124
while (i != 0) {
119125
i -= 1;
120-
const tmp = @boolToInt(@subWithOverflow(u8, a[i], b[i], &result[i]));
121-
borrow = tmp | @boolToInt(@subWithOverflow(u8, result[i], borrow, &result[i]));
126+
const ov1 = @subWithOverflow(a[i], b[i]);
127+
const ov2 = @subWithOverflow(ov1[0], borrow);
128+
result[i] = ov2[0];
129+
borrow = ov1[1] | ov2[1];
122130
}
123131
}
124132
return @bitCast(bool, borrow);

lib/std/heap.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,7 @@ pub fn testAllocatorLargeAlignment(base_allocator: mem.Allocator) !void {
789789
const large_align: usize = mem.page_size / 2;
790790

791791
var align_mask: usize = undefined;
792-
_ = @shlWithOverflow(usize, ~@as(usize, 0), @as(Allocator.Log2Align, @ctz(large_align)), &align_mask);
792+
align_mask = @shlWithOverflow(~@as(usize, 0), @as(Allocator.Log2Align, @ctz(large_align)))[0];
793793

794794
var slice = try allocator.alignedAlloc(u8, large_align, 500);
795795
try testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));

lib/std/leb128.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ pub fn readULEB128(comptime T: type, reader: anytype) !T {
1515

1616
while (group < max_group) : (group += 1) {
1717
const byte = try reader.readByte();
18-
var temp = @as(U, byte & 0x7f);
1918

20-
if (@shlWithOverflow(U, temp, group * 7, &temp)) return error.Overflow;
19+
const ov = @shlWithOverflow(@as(U, byte & 0x7f), group * 7);
20+
if (ov[1] != 0) return error.Overflow;
2121

22-
value |= temp;
22+
value |= ov[0];
2323
if (byte & 0x80 == 0) break;
2424
} else {
2525
return error.Overflow;
@@ -65,13 +65,13 @@ pub fn readILEB128(comptime T: type, reader: anytype) !T {
6565

6666
while (group < max_group) : (group += 1) {
6767
const byte = try reader.readByte();
68-
var temp = @as(U, byte & 0x7f);
6968

7069
const shift = group * 7;
71-
if (@shlWithOverflow(U, temp, shift, &temp)) {
70+
const ov = @shlWithOverflow(@as(U, byte & 0x7f), shift);
71+
if (ov[1] != 0) {
7272
// Overflow is ok so long as the sign bit is set and this is the last byte
7373
if (byte & 0x80 != 0) return error.Overflow;
74-
if (@bitCast(S, temp) >= 0) return error.Overflow;
74+
if (@bitCast(S, ov[0]) >= 0) return error.Overflow;
7575

7676
// and all the overflowed bits are 1
7777
const remaining_shift = @intCast(u3, @typeInfo(U).Int.bits - @as(u16, shift));
@@ -80,14 +80,14 @@ pub fn readILEB128(comptime T: type, reader: anytype) !T {
8080
} else {
8181
// If we don't overflow and this is the last byte and the number being decoded
8282
// is negative, check that the remaining bits are 1
83-
if ((byte & 0x80 == 0) and (@bitCast(S, temp) < 0)) {
83+
if ((byte & 0x80 == 0) and (@bitCast(S, ov[0]) < 0)) {
8484
const remaining_shift = @intCast(u3, @typeInfo(U).Int.bits - @as(u16, shift));
8585
const remaining_bits = @bitCast(i8, byte | 0x80) >> remaining_shift;
8686
if (remaining_bits != -1) return error.Overflow;
8787
}
8888
}
8989

90-
value |= temp;
90+
value |= ov[0];
9191
if (byte & 0x80 == 0) {
9292
const needs_sign_ext = group + 1 < max_group;
9393
if (byte & 0x40 != 0 and needs_sign_ext) {

lib/std/math.zig

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -468,21 +468,26 @@ test "clamp" {
468468

469469
/// Returns the product of a and b. Returns an error on overflow.
470470
pub fn mul(comptime T: type, a: T, b: T) (error{Overflow}!T) {
471-
var answer: T = undefined;
472-
return if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer;
471+
if (T == comptime_int) return a * b;
472+
const ov = @mulWithOverflow(a, b);
473+
if (ov[1] != 0) return error.Overflow;
474+
return ov[0];
473475
}
474476

475477
/// Returns the sum of a and b. Returns an error on overflow.
476478
pub fn add(comptime T: type, a: T, b: T) (error{Overflow}!T) {
477479
if (T == comptime_int) return a + b;
478-
var answer: T = undefined;
479-
return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;
480+
const ov = @addWithOverflow(a, b);
481+
if (ov[1] != 0) return error.Overflow;
482+
return ov[0];
480483
}
481484

482485
/// Returns a - b, or an error on overflow.
483486
pub fn sub(comptime T: type, a: T, b: T) (error{Overflow}!T) {
484-
var answer: T = undefined;
485-
return if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer;
487+
if (T == comptime_int) return a - b;
488+
const ov = @subWithOverflow(a, b);
489+
if (ov[1] != 0) return error.Overflow;
490+
return ov[0];
486491
}
487492

488493
pub fn negate(x: anytype) !@TypeOf(x) {
@@ -492,8 +497,10 @@ pub fn negate(x: anytype) !@TypeOf(x) {
492497
/// Shifts a left by shift_amt. Returns an error on overflow. shift_amt
493498
/// is unsigned.
494499
pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) !T {
495-
var answer: T = undefined;
496-
return if (@shlWithOverflow(T, a, shift_amt, &answer)) error.Overflow else answer;
500+
if (T == comptime_int) return a << shift_amt;
501+
const ov = @shlWithOverflow(a, shift_amt);
502+
if (ov[1] != 0) return error.Overflow;
503+
return ov[0];
497504
}
498505

499506
/// Shifts left. Overflowed bits are truncated.

0 commit comments

Comments
 (0)