diff options
| author | Felix S. Klock II <pnkfelix@pnkfx.org> | 2015-04-01 23:47:19 +0200 |
|---|---|---|
| committer | Felix S. Klock II <pnkfelix@pnkfx.org> | 2015-04-01 23:47:19 +0200 |
| commit | b85c4d16d52c7f0a3fec5d4ce4d686f0a70fa512 (patch) | |
| tree | 24b66ba6638f806b4fc0cc6ba66a5216bd3f6f81 /src/libcore/num | |
| parent | 1c11748a54027dc5f89185dcbb39ff8996d71515 (diff) | |
| download | rust-b85c4d16d52c7f0a3fec5d4ce4d686f0a70fa512.tar.gz rust-b85c4d16d52c7f0a3fec5d4ce4d686f0a70fa512.zip | |
Fix bug in `OverflowOps` impl for unsigned integers.
Namely, the special case treatment for `div`/`rem` is only applicable to signed integer values. Clearly RFC 1027 would have saved us here! ;)
Diffstat (limited to 'src/libcore/num')
| -rw-r--r-- | src/libcore/num/wrapping.rs | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index a78eed8ae5f..28276d0bf01 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -30,7 +30,7 @@ use intrinsics::{i16_mul_with_overflow, u16_mul_with_overflow}; use intrinsics::{i32_mul_with_overflow, u32_mul_with_overflow}; use intrinsics::{i64_mul_with_overflow, u64_mul_with_overflow}; -use ::{i8,i16,i32,i64,u8,u16,u32,u64}; +use ::{i8,i16,i32,i64}; #[unstable(feature = "core", reason = "may be removed, renamed, or relocated")] #[deprecated(since = "1.0.0", reason = "moved to inherent methods")] @@ -206,7 +206,7 @@ mod shift_max { pub const u64: u32 = i64; } -macro_rules! overflowing_impl { +macro_rules! signed_overflowing_impl { ($($t:ident)*) => ($( impl OverflowingOps for $t { #[inline(always)] @@ -259,7 +259,53 @@ macro_rules! overflowing_impl { )*) } -overflowing_impl! { u8 u16 u32 u64 i8 i16 i32 i64 } +macro_rules! unsigned_overflowing_impl { + ($($t:ident)*) => ($( + impl OverflowingOps for $t { + #[inline(always)] + fn overflowing_add(self, rhs: $t) -> ($t, bool) { + unsafe { + concat_idents!($t, _add_with_overflow)(self, rhs) + } + } + #[inline(always)] + fn overflowing_sub(self, rhs: $t) -> ($t, bool) { + unsafe { + concat_idents!($t, _sub_with_overflow)(self, rhs) + } + } + #[inline(always)] + fn overflowing_mul(self, rhs: $t) -> ($t, bool) { + unsafe { + concat_idents!($t, _mul_with_overflow)(self, rhs) + } + } + + #[inline(always)] + fn overflowing_div(self, rhs: $t) -> ($t, bool) { + (self/rhs, false) + } + #[inline(always)] + fn overflowing_rem(self, rhs: $t) -> ($t, bool) { + (self % rhs, false) + } + + #[inline(always)] + fn overflowing_shl(self, rhs: u32) -> ($t, bool) { + (self << (rhs & self::shift_max::$t), + (rhs > self::shift_max::$t)) + } + #[inline(always)] + fn overflowing_shr(self, rhs: u32) -> ($t, bool) { + (self >> (rhs & self::shift_max::$t), + (rhs > self::shift_max::$t)) + } + } + )*) +} + +signed_overflowing_impl! { i8 i16 i32 i64 } +unsigned_overflowing_impl! { u8 u16 u32 u64 } #[cfg(target_pointer_width = "64")] impl OverflowingOps for usize { |
