diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-03-23 15:08:17 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-03-23 15:08:17 -0700 |
| commit | c77af69a3793bc0c3c49b05ceffb15dccf5ed4d0 (patch) | |
| tree | be30a92e8aee79ab617e035e12f009725ddb4ac0 /src/test/run-pass | |
| parent | 68cf9e09c22302983ed46635d6d8b7dac3091f24 (diff) | |
| parent | bb9d210c99ab248e81598d70c39c3968ab9d09eb (diff) | |
| download | rust-c77af69a3793bc0c3c49b05ceffb15dccf5ed4d0.tar.gz rust-c77af69a3793bc0c3c49b05ceffb15dccf5ed4d0.zip | |
rollup merge of #23536: pnkfelix/arith-oflo-shifts
overflow-checking for rhs of shift operators Subtask of #22020 ([RFC 560](https://github.com/rust-lang/rfcs/blob/master/text/0560-integer-overflow.md))
Diffstat (limited to 'src/test/run-pass')
| -rw-r--r-- | src/test/run-pass/over-constrained-vregs.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/shift-near-oflo.rs | 100 |
2 files changed, 101 insertions, 1 deletions
diff --git a/src/test/run-pass/over-constrained-vregs.rs b/src/test/run-pass/over-constrained-vregs.rs index 1118638fe07..c2b42ac1c81 100644 --- a/src/test/run-pass/over-constrained-vregs.rs +++ b/src/test/run-pass/over-constrained-vregs.rs @@ -11,7 +11,7 @@ // Regression test for issue #152. pub fn main() { let mut b: uint = 1_usize; - while b <= 32_usize { + while b < std::mem::size_of::<usize>() { 0_usize << b; b <<= 1_usize; println!("{}", b); diff --git a/src/test/run-pass/shift-near-oflo.rs b/src/test/run-pass/shift-near-oflo.rs new file mode 100644 index 00000000000..4ff058f3366 --- /dev/null +++ b/src/test/run-pass/shift-near-oflo.rs @@ -0,0 +1,100 @@ +// Copyright 2015 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. + +// compile-flags: -C debug-assertions + +// Check that we do *not* overflow on a number of edge cases. +// (compare with test/run-fail/overflowing-{lsh,rsh}*.rs) + +// (Work around constant-evaluation) +fn id<T>(x: T) -> T { x } + +fn main() { + test_left_shift(); + test_right_shift(); +} + +fn test_left_shift() { + // negative rhs can panic, but values in [0,N-1] are okay for iN + + macro_rules! tests { + ($iN:ty, $uN:ty, $max_rhs:expr, $expect_i:expr, $expect_u:expr) => { { + let x = (1 as $iN) << id(0); + assert_eq!(x, 1); + let x = (1 as $uN) << id(0); + assert_eq!(x, 1); + let x = (1 as $iN) << id($max_rhs); + assert_eq!(x, $expect_i); + let x = (1 as $uN) << id($max_rhs); + assert_eq!(x, $expect_u); + // high-order bits on LHS are silently discarded without panic. + let x = (3 as $iN) << id($max_rhs); + assert_eq!(x, $expect_i); + let x = (3 as $uN) << id($max_rhs); + assert_eq!(x, $expect_u); + } } + } + + let x = 1_i8 << id(0); + assert_eq!(x, 1); + let x = 1_u8 << id(0); + assert_eq!(x, 1); + let x = 1_i8 << id(7); + assert_eq!(x, std::i8::MIN); + let x = 1_u8 << id(7); + assert_eq!(x, 0x80); + // high-order bits on LHS are silently discarded without panic. + let x = 3_i8 << id(7); + assert_eq!(x, std::i8::MIN); + let x = 3_u8 << id(7); + assert_eq!(x, 0x80); + + // above is (approximately) expanded from: + tests!(i8, u8, 7, std::i8::MIN, 0x80_u8); + + tests!(i16, u16, 15, std::i16::MIN, 0x8000_u16); + tests!(i32, u32, 31, std::i32::MIN, 0x8000_0000_u32); + tests!(i64, u64, 63, std::i64::MIN, 0x8000_0000_0000_0000_u64); +} + +fn test_right_shift() { + // negative rhs can panic, but values in [0,N-1] are okay for iN + + macro_rules! tests { + ($iN:ty, $uN:ty, $max_rhs:expr, + $signbit_i:expr, $highbit_i:expr, $highbit_u:expr) => + { { + let x = (1 as $iN) >> id(0); + assert_eq!(x, 1); + let x = (1 as $uN) >> id(0); + assert_eq!(x, 1); + let x = ($highbit_i) >> id($max_rhs-1); + assert_eq!(x, 1); + let x = ($highbit_u) >> id($max_rhs); + assert_eq!(x, 1); + // sign-bit is carried by arithmetic right shift + let x = ($signbit_i) >> id($max_rhs); + assert_eq!(x, -1); + // low-order bits on LHS are silently discarded without panic. + let x = ($highbit_i + 1) >> id($max_rhs-1); + assert_eq!(x, 1); + let x = ($highbit_u + 1) >> id($max_rhs); + assert_eq!(x, 1); + let x = ($signbit_i + 1) >> id($max_rhs); + assert_eq!(x, -1); + } } + } + + tests!(i8, u8, 7, std::i8::MIN, 0x40_i8, 0x80_u8); + tests!(i16, u16, 15, std::i16::MIN, 0x4000_u16, 0x8000_u16); + tests!(i32, u32, 31, std::i32::MIN, 0x4000_0000_u32, 0x8000_0000_u32); + tests!(i64, u64, 63, std::i64::MIN, + 0x4000_0000_0000_0000_u64, 0x8000_0000_0000_0000_u64); +} |
