about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/num/mod.rs26
-rw-r--r--src/test/run-fail/overflowing-pow-signed.rs (renamed from src/test/run-fail/overflowing-pow.rs)0
-rw-r--r--src/test/run-fail/overflowing-pow-unsigned.rs16
3 files changed, 27 insertions, 15 deletions
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 29ee29eb3eb..5c2cc671969 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -2211,25 +2211,21 @@ macro_rules! uint_impl {
             let mut base = self;
             let mut acc = 1;
 
-            let mut prev_base = self;
-            let mut base_oflo = false;
-            while exp > 0 {
+            while exp > 1 {
                 if (exp & 1) == 1 {
-                    if base_oflo {
-                        // ensure overflow occurs in the same manner it
-                        // would have otherwise (i.e. signal any exception
-                        // it would have otherwise).
-                        acc = acc * (prev_base * prev_base);
-                    } else {
-                        acc = acc * base;
-                    }
+                    acc = acc * base;
                 }
-                prev_base = base;
-                let (new_base, new_base_oflo) = base.overflowing_mul(base);
-                base = new_base;
-                base_oflo = new_base_oflo;
                 exp /= 2;
+                base = base * base;
             }
+
+            // Deal with the final bit of the exponent separately, since
+            // squaring the base afterwards is not necessary and may cause a
+            // needless overflow.
+            if exp == 1 {
+                acc = acc * base;
+            }
+
             acc
         }
 
diff --git a/src/test/run-fail/overflowing-pow.rs b/src/test/run-fail/overflowing-pow-signed.rs
index b0ff0df5577..b0ff0df5577 100644
--- a/src/test/run-fail/overflowing-pow.rs
+++ b/src/test/run-fail/overflowing-pow-signed.rs
diff --git a/src/test/run-fail/overflowing-pow-unsigned.rs b/src/test/run-fail/overflowing-pow-unsigned.rs
new file mode 100644
index 00000000000..d3e7035279f
--- /dev/null
+++ b/src/test/run-fail/overflowing-pow-unsigned.rs
@@ -0,0 +1,16 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern:thread 'main' panicked at 'attempt to multiply with overflow'
+// compile-flags: -C debug-assertions
+
+fn main() {
+    let _x = 2u32.pow(1024);
+}