about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2018-04-24 11:57:11 +0800
committerGitHub <noreply@github.com>2018-04-24 11:57:11 +0800
commit893774e119b3197e12c1891b39d0e1e2830a362d (patch)
treed9d69bd70bdb7985d5953b151d57a4028714640c
parent8d0c5da7e84cc7f970e9f1d04e30dcd9ecae08d8 (diff)
parent104c64dc360f297fbdd4a467dac1c5006d76dece (diff)
downloadrust-893774e119b3197e12c1891b39d0e1e2830a362d.tar.gz
rust-893774e119b3197e12c1891b39d0e1e2830a362d.zip
Rollup merge of #50185 - dmizuk:mod_euc-fix-overflow, r=kennytm
core: Fix overflow in `int::mod_euc` when `self < 0 && rhs == MIN`

This commit removes usage of `abs`, which overflows when `self == MIN`.
-rw-r--r--src/libcore/num/mod.rs6
-rw-r--r--src/libcore/tests/lib.rs1
-rw-r--r--src/libcore/tests/num/int_macros.rs5
3 files changed, 11 insertions, 1 deletions
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index aa4d4bc638b..a062fbda5ba 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 < 0 {
+                        r - rhs
+                    } else {
+                        r + rhs
+                    }
                 } else {
                     r
                 }
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 2b69f04013d..e4d27717938 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -16,6 +16,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 8d791283ab8..71d2e794538 100644
--- a/src/libcore/tests/num/int_macros.rs
+++ b/src/libcore/tests/num/int_macros.rs
@@ -31,6 +31,11 @@ mod tests {
     }
 
     #[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);
         assert!((0 as $T).abs() == 0 as $T);