From fbb1c280bf5f3d4fc68f323860ade8fa48d96979 Mon Sep 17 00:00:00 2001 From: Daiki Mizukami Date: Tue, 24 Apr 2018 01:45:44 +0900 Subject: [PATCH 1/2] core: Fix overflow in `int::mod_euc` when `self < 0 && rhs == MIN` --- src/libcore/num/mod.rs | 6 +++++- src/libcore/tests/lib.rs | 1 + src/libcore/tests/num/int_macros.rs | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index aa4d4bc638b1d..4893e05badcb5 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1765,7 +1765,11 @@ assert_eq!((-a).mod_euc(-b), 1); pub fn mod_euc(self, rhs: Self) -> Self { let r = self % rhs; if r < 0 { - r + rhs.abs() + if rhs.is_negative() { + r - rhs + } else { + r + rhs + } } else { r } diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 7d3852d2f2a98..ccf647c358d67 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -15,6 +15,7 @@ #![feature(core_private_diy_float)] #![feature(dec2flt)] #![feature(decode_utf8)] +#![feature(euclidean_division)] #![feature(exact_size_is_empty)] #![feature(fixed_size_array)] #![feature(float_internals)] diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs index 8d791283ab87e..71d2e7945389b 100644 --- a/src/libcore/tests/num/int_macros.rs +++ b/src/libcore/tests/num/int_macros.rs @@ -30,6 +30,11 @@ mod tests { num::test_num(10 as $T, 2 as $T); } + #[test] + fn test_mod_euc() { + assert!((-1 as $T).mod_euc(MIN) == MAX); + } + #[test] pub fn test_abs() { assert!((1 as $T).abs() == 1 as $T); From 104c64dc360f297fbdd4a467dac1c5006d76dece Mon Sep 17 00:00:00 2001 From: Daiki Mizukami Date: Tue, 24 Apr 2018 03:32:40 +0900 Subject: [PATCH 2/2] core: Minor cleanup --- src/libcore/num/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 4893e05badcb5..a062fbda5bad0 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1765,7 +1765,7 @@ assert_eq!((-a).mod_euc(-b), 1); pub fn mod_euc(self, rhs: Self) -> Self { let r = self % rhs; if r < 0 { - if rhs.is_negative() { + if rhs < 0 { r - rhs } else { r + rhs