]> git.lizzy.rs Git - rust.git/blob - tests/pass/pointers.rs
fix comparing wide raw pointers
[rust.git] / tests / pass / pointers.rs
1 use std::mem::transmute;
2
3 fn one_line_ref() -> i16 {
4     *&1
5 }
6
7 fn basic_ref() -> i16 {
8     let x = &1;
9     *x
10 }
11
12 fn basic_ref_mut() -> i16 {
13     let x = &mut 1;
14     *x += 2;
15     *x
16 }
17
18 fn basic_ref_mut_var() -> i16 {
19     let mut a = 1;
20     {
21         let x = &mut a;
22         *x += 2;
23     }
24     a
25 }
26
27 fn tuple_ref_mut() -> (i8, i8) {
28     let mut t = (10, 20);
29     {
30         let x = &mut t.1;
31         *x += 2;
32     }
33     t
34 }
35
36 fn match_ref_mut() -> i8 {
37     let mut t = (20, 22);
38     {
39         let opt = Some(&mut t);
40         match opt {
41             Some(&mut (ref mut x, ref mut y)) => *x += *y,
42             None => {}
43         }
44     }
45     t.0
46 }
47
48 fn dangling_pointer() -> *const i32 {
49     let b = Box::new((42, 42)); // make it bigger than the alignment, so that there is some "room" after this pointer
50     &b.0 as *const i32
51 }
52
53 fn wide_ptr_ops() {
54     let a: *const dyn Send = &1 as &dyn Send;
55     let b: *const dyn Send = &1 as &dyn Send;
56     let _val = a == b;
57     let _val = a != b;
58     let _val = a < b;
59     let _val = a <= b;
60     let _val = a > b;
61     let _val = a >= b;
62
63     let a: *const [u8] = unsafe { transmute((1usize, 1usize)) };
64     let b: *const [u8] = unsafe { transmute((1usize, 2usize)) };
65     // confirmed with rustc.
66     assert!(!(a == b));
67     assert!(a != b);
68     assert!(a <= b);
69     assert!(a < b);
70     assert!(!(a >= b));
71     assert!(!(a > b));
72 }
73
74 fn main() {
75     assert_eq!(one_line_ref(), 1);
76     assert_eq!(basic_ref(), 1);
77     assert_eq!(basic_ref_mut(), 3);
78     assert_eq!(basic_ref_mut_var(), 3);
79     assert_eq!(tuple_ref_mut(), (10, 22));
80     assert_eq!(match_ref_mut(), 42);
81
82     // Compare even dangling pointers with NULL, and with others in the same allocation, including
83     // out-of-bounds.
84     assert!(dangling_pointer() != std::ptr::null());
85     assert!(match dangling_pointer() as usize {
86         0 => false,
87         _ => true,
88     });
89     let dangling = dangling_pointer();
90     assert!(dangling == dangling);
91     assert!(dangling.wrapping_add(1) != dangling);
92     assert!(dangling.wrapping_sub(1) != dangling);
93
94     // Compare pointer with BIG integers
95     let dangling = dangling as usize;
96     assert!(dangling != usize::MAX);
97     assert!(dangling != usize::MAX - 1);
98     assert!(dangling != usize::MAX - 2);
99     assert!(dangling != usize::MAX - 3); // this is even 4-aligned, but it still cannot be equal because of the extra "room" after this pointer
100     assert_eq!((usize::MAX - 3) % 4, 0); // just to be sure we got this right
101
102     // Compare pointer with unaligned integers
103     assert!(dangling != 1usize);
104     assert!(dangling != 2usize);
105     assert!(dangling != 3usize);
106     // 4 is a possible choice! So we cannot compare with that.
107     assert!(dangling != 5usize);
108     assert!(dangling != 6usize);
109     assert!(dangling != 7usize);
110
111     // Using inequality to do the comparison.
112     assert!(dangling > 0);
113     assert!(dangling > 1);
114     assert!(dangling > 2);
115     assert!(dangling > 3);
116     assert!(dangling >= 4);
117
118     wide_ptr_ops();
119 }