diff --git a/src/test/run-pass/shift-near-oflo.rs b/src/test/run-pass/shift-near-oflo.rs index 542e8de9e53..527ced54c42 100644 --- a/src/test/run-pass/shift-near-oflo.rs +++ b/src/test/run-pass/shift-near-oflo.rs @@ -18,39 +18,51 @@ fn main() { test_right_shift(); } +pub static mut HACK: i32 = 0; + +// Work around constant-evaluation +// The point of this test is to exercise the code generated for execution at runtime, +// `id` can never be flagged as a const fn by future aggressive analyses... +// due to the modification of the static +#[inline(never)] +fn id(x: T) -> T { + unsafe { HACK += 1; } + x +} + 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) << 0; + let x = (1 as $iN) << id(0); assert_eq!(x, 1); - let x = (1 as $uN) << 0; + let x = (1 as $uN) << id(0); assert_eq!(x, 1); - let x = (1 as $iN) << $max_rhs; + let x = (1 as $iN) << id($max_rhs); assert_eq!(x, $expect_i); - let x = (1 as $uN) << $max_rhs; + 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) << $max_rhs; + let x = (3 as $iN) << id($max_rhs); assert_eq!(x, $expect_i); - let x = (3 as $uN) << $max_rhs; + let x = (3 as $uN) << id($max_rhs); assert_eq!(x, $expect_u); } } } - let x = 1_i8 << 0; + let x = 1_i8 << id(0); assert_eq!(x, 1); - let x = 1_u8 << 0; + let x = 1_u8 << id(0); assert_eq!(x, 1); - let x = 1_i8 << 7; + let x = 1_i8 << id(7); assert_eq!(x, std::i8::MIN); - let x = 1_u8 << 7; + let x = 1_u8 << id(7); assert_eq!(x, 0x80); // high-order bits on LHS are silently discarded without panic. - let x = 3_i8 << 7; + let x = 3_i8 << id(7); assert_eq!(x, std::i8::MIN); - let x = 3_u8 << 7; + let x = 3_u8 << id(7); assert_eq!(x, 0x80); // above is (approximately) expanded from: @@ -68,23 +80,23 @@ fn test_right_shift() { ($iN:ty, $uN:ty, $max_rhs:expr, $signbit_i:expr, $highbit_i:expr, $highbit_u:expr) => { { - let x = (1 as $iN) >> 0; + let x = (1 as $iN) >> id(0); assert_eq!(x, 1); - let x = (1 as $uN) >> 0; + let x = (1 as $uN) >> id(0); assert_eq!(x, 1); - let x = ($highbit_i) >> $max_rhs-1; + let x = ($highbit_i) >> id($max_rhs-1); assert_eq!(x, 1); - let x = ($highbit_u) >> $max_rhs; + let x = ($highbit_u) >> id($max_rhs); assert_eq!(x, 1); // sign-bit is carried by arithmetic right shift - let x = ($signbit_i) >> $max_rhs; + 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) >> $max_rhs-1; + let x = ($highbit_i + 1) >> id($max_rhs-1); assert_eq!(x, 1); - let x = ($highbit_u + 1) >> $max_rhs; + let x = ($highbit_u + 1) >> id($max_rhs); assert_eq!(x, 1); - let x = ($signbit_i + 1) >> $max_rhs; + let x = ($signbit_i + 1) >> id($max_rhs); assert_eq!(x, -1); } } }