]> git.lizzy.rs Git - rust.git/blob - src/tools/miri/tests/pass/pointers.rs
Auto merge of #104915 - weihanglo:update-cargo, r=ehuss
[rust.git] / src / tools / miri / tests / pass / pointers.rs
1 //@compile-flags: -Zmiri-permissive-provenance
2 #![feature(ptr_metadata, const_raw_ptr_comparison)]
3
4 use std::mem::{self, transmute};
5 use std::ptr;
6
7 fn one_line_ref() -> i16 {
8     *&1
9 }
10
11 fn basic_ref() -> i16 {
12     let x = &1;
13     *x
14 }
15
16 fn basic_ref_mut() -> i16 {
17     let x = &mut 1;
18     *x += 2;
19     *x
20 }
21
22 fn basic_ref_mut_var() -> i16 {
23     let mut a = 1;
24     {
25         let x = &mut a;
26         *x += 2;
27     }
28     a
29 }
30
31 fn tuple_ref_mut() -> (i8, i8) {
32     let mut t = (10, 20);
33     {
34         let x = &mut t.1;
35         *x += 2;
36     }
37     t
38 }
39
40 fn match_ref_mut() -> i8 {
41     let mut t = (20, 22);
42     {
43         let opt = Some(&mut t);
44         match opt {
45             Some(&mut (ref mut x, ref mut y)) => *x += *y,
46             None => {}
47         }
48     }
49     t.0
50 }
51
52 fn dangling_pointer() -> *const i32 {
53     let b = Box::new((42, 42)); // make it bigger than the alignment, so that there is some "room" after this pointer
54     &b.0 as *const i32
55 }
56
57 fn wide_ptr_ops() {
58     let a: *const dyn Send = &1 as &dyn Send;
59     let b: *const dyn Send = &1 as &dyn Send;
60     let _val = a == b;
61     let _val = a != b;
62     let _val = a < b;
63     let _val = a <= b;
64     let _val = a > b;
65     let _val = a >= b;
66
67     let a: *const [u8] = unsafe { transmute((1usize, 1usize)) };
68     let b: *const [u8] = unsafe { transmute((1usize, 2usize)) };
69     // confirmed with rustc.
70     assert!(!(a == b));
71     assert!(a != b);
72     assert!(a <= b);
73     assert!(a < b);
74     assert!(!(a >= b));
75     assert!(!(a > b));
76 }
77
78 fn metadata_vtable() {
79     let p = &0i32 as &dyn std::fmt::Debug;
80     let meta: ptr::DynMetadata<_> = ptr::metadata(p as *const _);
81     assert_eq!(meta.size_of(), mem::size_of::<i32>());
82     assert_eq!(meta.align_of(), mem::align_of::<i32>());
83
84     type T = [i32; 16];
85     let p = &T::default() as &dyn std::fmt::Debug;
86     let meta: ptr::DynMetadata<_> = ptr::metadata(p as *const _);
87     assert_eq!(meta.size_of(), mem::size_of::<T>());
88     assert_eq!(meta.align_of(), mem::align_of::<T>());
89 }
90
91 fn main() {
92     assert_eq!(one_line_ref(), 1);
93     assert_eq!(basic_ref(), 1);
94     assert_eq!(basic_ref_mut(), 3);
95     assert_eq!(basic_ref_mut_var(), 3);
96     assert_eq!(tuple_ref_mut(), (10, 22));
97     assert_eq!(match_ref_mut(), 42);
98
99     // Compare even dangling pointers with NULL, and with others in the same allocation, including
100     // out-of-bounds.
101     assert!(dangling_pointer() != std::ptr::null());
102     assert!(match dangling_pointer() as usize {
103         0 => false,
104         _ => true,
105     });
106     let dangling = dangling_pointer();
107     assert!(dangling == dangling);
108     assert!(dangling.wrapping_add(1) != dangling);
109     assert!(dangling.wrapping_sub(1) != dangling);
110
111     // Compare pointer with BIG integers
112     let dangling = dangling as usize;
113     assert!(dangling != usize::MAX);
114     assert!(dangling != usize::MAX - 1);
115     assert!(dangling != usize::MAX - 2);
116     assert!(dangling != usize::MAX - 3); // this is even 4-aligned, but it still cannot be equal because of the extra "room" after this pointer
117     assert_eq!((usize::MAX - 3) % 4, 0); // just to be sure we got this right
118
119     // Compare pointer with unaligned integers
120     assert!(dangling != 1usize);
121     assert!(dangling != 2usize);
122     assert!(dangling != 3usize);
123     // 4 is a possible choice! So we cannot compare with that.
124     assert!(dangling != 5usize);
125     assert!(dangling != 6usize);
126     assert!(dangling != 7usize);
127
128     // Using inequality to do the comparison.
129     assert!(dangling > 0);
130     assert!(dangling > 1);
131     assert!(dangling > 2);
132     assert!(dangling > 3);
133     assert!(dangling >= 4);
134
135     // CTFE-specific equality tests, need to also work at runtime.
136     let addr = &13 as *const i32;
137     let addr2 = (addr as usize).wrapping_add(usize::MAX).wrapping_add(1);
138     assert_eq!(addr.guaranteed_eq(addr2 as *const _), Some(true));
139     assert_eq!(addr.guaranteed_ne(0x100 as *const _), Some(true));
140
141     wide_ptr_ops();
142     metadata_vtable();
143 }