Skip to content

Commit

Permalink
std: use math overflow helpers instead of builtins
Browse files Browse the repository at this point in the history
This patch replaces all usages of the `@___WithOverflow` builtins where
the overflow result is discarded with the nicer `math` helpers that
return `error.Overflow`. This cleaned up a bit of code and hopefully
impresses the useful `math` functions on more Zig code later.
  • Loading branch information
sno2 authored and andrewrk committed Mar 14, 2024
1 parent 0103c4b commit 3481c47
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 67 deletions.
7 changes: 3 additions & 4 deletions lib/std/leb128.zig
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const std = @import("std");
const math = std.math;
const testing = std.testing;

/// Read a single unsigned LEB128 value from the given reader as type T,
Expand All @@ -15,10 +16,8 @@ pub fn readULEB128(comptime T: type, reader: anytype) !T {
while (group < max_group) : (group += 1) {
const byte = try reader.readByte();

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

value |= ov[0];
const mask = try math.shlExact(U, byte & 0x7f, group * 7);
value |= mask;
if (byte & 0x80 == 0) break;
} else {
return error.Overflow;
Expand Down
12 changes: 3 additions & 9 deletions lib/std/math/powi.zig
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,16 @@ pub fn powi(comptime T: type, x: T, y: T) (error{

while (exp > 1) {
if (exp & 1 == 1) {
const ov = @mulWithOverflow(acc, base);
if (ov[1] != 0) return error.Overflow;
acc = ov[0];
acc = try math.mul(T, acc, base);
}

exp >>= 1;

const ov = @mulWithOverflow(base, base);
if (ov[1] != 0) return error.Overflow;
base = ov[0];
base = try math.mul(T, base, base);
}

if (exp == 1) {
const ov = @mulWithOverflow(acc, base);
if (ov[1] != 0) return error.Overflow;
acc = ov[0];
acc = try math.mul(T, acc, base);
}

return acc;
Expand Down
7 changes: 3 additions & 4 deletions lib/std/mem.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3779,13 +3779,12 @@ pub fn alignPointerOffset(ptr: anytype, align_to: usize) ?usize {

// Calculate the aligned base address with an eye out for overflow.
const addr = @intFromPtr(ptr);
var ov = @addWithOverflow(addr, align_to - 1);
if (ov[1] != 0) return null;
ov[0] &= ~@as(usize, align_to - 1);
var aligned_addr = math.add(usize, addr, align_to - 1) catch return null;
aligned_addr &= ~@as(usize, align_to - 1);

// The delta is expressed in terms of bytes, turn it into a number of child
// type elements.
const delta = ov[0] - addr;
const delta = aligned_addr - addr;
const pointee_size = @sizeOf(info.Pointer.child);
if (delta % pointee_size != 0) return null;
return delta / pointee_size;
Expand Down
36 changes: 6 additions & 30 deletions lib/std/net.zig
Original file line number Diff line number Diff line change
Expand Up @@ -401,16 +401,8 @@ pub const Ip6Address = extern struct {
if (scope_id) {
if (c >= '0' and c <= '9') {
const digit = c - '0';
{
const ov = @mulWithOverflow(result.sa.scope_id, 10);
if (ov[1] != 0) return error.Overflow;
result.sa.scope_id = ov[0];
}
{
const ov = @addWithOverflow(result.sa.scope_id, digit);
if (ov[1] != 0) return error.Overflow;
result.sa.scope_id = ov[0];
}
result.sa.scope_id = try std.math.mul(u32, result.sa.scope_id, 10);
result.sa.scope_id = try std.math.add(u32, result.sa.scope_id, digit);
} else {
return error.InvalidCharacter;
}
Expand Down Expand Up @@ -461,16 +453,8 @@ pub const Ip6Address = extern struct {
return result;
} else {
const digit = try std.fmt.charToDigit(c, 16);
{
const ov = @mulWithOverflow(x, 16);
if (ov[1] != 0) return error.Overflow;
x = ov[0];
}
{
const ov = @addWithOverflow(x, digit);
if (ov[1] != 0) return error.Overflow;
x = ov[0];
}
x = try std.math.mul(u16, x, 16);
x = try std.math.add(u16, x, digit);
saw_any_digits = true;
}
}
Expand Down Expand Up @@ -583,16 +567,8 @@ pub const Ip6Address = extern struct {
return result;
} else {
const digit = try std.fmt.charToDigit(c, 16);
{
const ov = @mulWithOverflow(x, 16);
if (ov[1] != 0) return error.Overflow;
x = ov[0];
}
{
const ov = @addWithOverflow(x, digit);
if (ov[1] != 0) return error.Overflow;
x = ov[0];
}
x = try std.math.mul(u16, x, 16);
x = try std.math.add(u16, x, digit);
saw_any_digits = true;
}
}
Expand Down
24 changes: 4 additions & 20 deletions lib/std/process.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1419,16 +1419,8 @@ pub fn posixGetUserInfo(name: []const u8) !UserInfo {
'0'...'9' => byte - '0',
else => return error.CorruptPasswordFile,
};
{
const ov = @mulWithOverflow(uid, 10);
if (ov[1] != 0) return error.CorruptPasswordFile;
uid = ov[0];
}
{
const ov = @addWithOverflow(uid, digit);
if (ov[1] != 0) return error.CorruptPasswordFile;
uid = ov[0];
}
uid = std.math.mul(os.uid_t, uid, 10) catch return error.CorruptPasswordFile;
uid = std.math.add(os.uid_t, uid, digit) catch return error.CorruptPasswordFile;
},
},
.ReadGroupId => switch (byte) {
Expand All @@ -1443,16 +1435,8 @@ pub fn posixGetUserInfo(name: []const u8) !UserInfo {
'0'...'9' => byte - '0',
else => return error.CorruptPasswordFile,
};
{
const ov = @mulWithOverflow(gid, 10);
if (ov[1] != 0) return error.CorruptPasswordFile;
gid = ov[0];
}
{
const ov = @addWithOverflow(gid, digit);
if (ov[1] != 0) return error.CorruptPasswordFile;
gid = ov[0];
}
gid = std.math.mul(os.gid_t, gid, 10) catch return error.CorruptPasswordFile;
gid = std.math.add(os.gid_t, gid, digit) catch return error.CorruptPasswordFile;
},
},
}
Expand Down

0 comments on commit 3481c47

Please sign in to comment.