]> git.lizzy.rs Git - rust.git/blob - src/test/ui/numbers-arithmetic/shift-near-oflo.rs
Update tests to remove old numeric constants
[rust.git] / src / test / ui / numbers-arithmetic / shift-near-oflo.rs
1 // run-pass
2 // compile-flags: -C debug-assertions
3
4 // Check that we do *not* overflow on a number of edge cases.
5 // (compare with test/run-fail/overflowing-{lsh,rsh}*.rs)
6
7 fn main() {
8     test_left_shift();
9     test_right_shift();
10 }
11
12 pub static mut HACK: i32 = 0;
13
14 // Work around constant-evaluation
15 // The point of this test is to exercise the code generated for execution at runtime,
16 // `id` can never be flagged as a const fn by future aggressive analyses...
17 // due to the modification of the static
18 #[inline(never)]
19 fn id<T>(x: T) -> T {
20     unsafe { HACK += 1; }
21     x
22 }
23
24 fn test_left_shift() {
25     // negative rhs can panic, but values in [0,N-1] are okay for iN
26
27     macro_rules! tests {
28         ($iN:ty, $uN:ty, $max_rhs:expr, $expect_i:expr, $expect_u:expr) => { {
29             let x = (1 as $iN) << id(0);
30             assert_eq!(x, 1);
31             let x = (1 as $uN) << id(0);
32             assert_eq!(x, 1);
33             let x = (1 as $iN) << id($max_rhs);
34             assert_eq!(x, $expect_i);
35             let x = (1 as $uN) << id($max_rhs);
36             assert_eq!(x, $expect_u);
37             // high-order bits on LHS are silently discarded without panic.
38             let x = (3 as $iN) << id($max_rhs);
39             assert_eq!(x, $expect_i);
40             let x = (3 as $uN) << id($max_rhs);
41             assert_eq!(x, $expect_u);
42         } }
43     }
44
45     let x = 1_i8 << id(0);
46     assert_eq!(x, 1);
47     let x = 1_u8 << id(0);
48     assert_eq!(x, 1);
49     let x = 1_i8 << id(7);
50     assert_eq!(x, i8::MIN);
51     let x = 1_u8 << id(7);
52     assert_eq!(x, 0x80);
53     // high-order bits on LHS are silently discarded without panic.
54     let x = 3_i8 << id(7);
55     assert_eq!(x, i8::MIN);
56     let x = 3_u8 << id(7);
57     assert_eq!(x, 0x80);
58
59     // above is (approximately) expanded from:
60     tests!(i8, u8, 7, i8::MIN, 0x80_u8);
61
62     tests!(i16, u16, 15, i16::MIN, 0x8000_u16);
63     tests!(i32, u32, 31, i32::MIN, 0x8000_0000_u32);
64     tests!(i64, u64, 63, i64::MIN, 0x8000_0000_0000_0000_u64);
65 }
66
67 fn test_right_shift() {
68     // negative rhs can panic, but values in [0,N-1] are okay for iN
69
70     macro_rules! tests {
71         ($iN:ty, $uN:ty, $max_rhs:expr,
72          $signbit_i:expr, $highbit_i:expr, $highbit_u:expr) =>
73         { {
74             let x = (1 as $iN) >> id(0);
75             assert_eq!(x, 1);
76             let x = (1 as $uN) >> id(0);
77             assert_eq!(x, 1);
78             let x = ($highbit_i) >> id($max_rhs-1);
79             assert_eq!(x, 1);
80             let x = ($highbit_u) >> id($max_rhs);
81             assert_eq!(x, 1);
82             // sign-bit is carried by arithmetic right shift
83             let x = ($signbit_i) >> id($max_rhs);
84             assert_eq!(x, -1);
85             // low-order bits on LHS are silently discarded without panic.
86             let x = ($highbit_i + 1) >> id($max_rhs-1);
87             assert_eq!(x, 1);
88             let x = ($highbit_u + 1) >> id($max_rhs);
89             assert_eq!(x, 1);
90             let x = ($signbit_i + 1) >> id($max_rhs);
91             assert_eq!(x, -1);
92         } }
93     }
94
95     tests!(i8, u8, 7, i8::MIN, 0x40_i8, 0x80_u8);
96     tests!(i16, u16, 15, i16::MIN, 0x4000_u16, 0x8000_u16);
97     tests!(i32, u32, 31, i32::MIN, 0x4000_0000_u32, 0x8000_0000_u32);
98     tests!(i64, u64, 63, i64::MIN,
99            0x4000_0000_0000_0000_u64, 0x8000_0000_0000_0000_u64);
100 }