]> git.lizzy.rs Git - rust.git/blob - src/tools/miri/tests/pass/ptr_offset.rs
Auto merge of #104915 - weihanglo:update-cargo, r=ehuss
[rust.git] / src / tools / miri / tests / pass / ptr_offset.rs
1 //@compile-flags: -Zmiri-permissive-provenance
2 #![feature(ptr_sub_ptr)]
3 use std::{mem, ptr};
4
5 fn main() {
6     smoke();
7     test_offset_from();
8     test_vec_into_iter();
9     ptr_arith_offset();
10     ptr_arith_offset_overflow();
11     ptr_offset();
12 }
13
14 fn smoke() {
15     // Smoke-test various offsetting operations.
16     let ptr = &5;
17     let ptr = ptr as *const i32;
18     let _val = ptr.wrapping_offset(0);
19     let _val = unsafe { ptr.offset(0) };
20     let _val = ptr.wrapping_add(0);
21     let _val = unsafe { ptr.add(0) };
22     let _val = ptr.wrapping_sub(0);
23     let _val = unsafe { ptr.sub(0) };
24     let _val = unsafe { ptr.offset_from(ptr) };
25     let _val = unsafe { ptr.sub_ptr(ptr) };
26 }
27
28 fn test_offset_from() {
29     unsafe {
30         let buf = [0u32; 4];
31
32         let x = buf.as_ptr() as *const u8;
33         let y = x.offset(12);
34
35         assert_eq!(y.offset_from(x), 12);
36         assert_eq!(y.sub_ptr(x), 12);
37         assert_eq!(x.offset_from(y), -12);
38         assert_eq!((y as *const u32).offset_from(x as *const u32), 12 / 4);
39         assert_eq!((x as *const u32).offset_from(y as *const u32), -12 / 4);
40
41         let x = (((x as usize) * 2) / 2) as *const u8;
42         assert_eq!(y.offset_from(x), 12);
43         assert_eq!(y.sub_ptr(x), 12);
44         assert_eq!(x.offset_from(y), -12);
45     }
46 }
47
48 // This also internally uses offset_from.
49 fn test_vec_into_iter() {
50     let v = Vec::<i32>::new();
51     let i = v.into_iter();
52     i.size_hint();
53 }
54
55 fn ptr_arith_offset() {
56     let v = [1i16, 2];
57     let x = &v as *const [i16] as *const i16;
58     let x = x.wrapping_offset(1);
59     assert_eq!(unsafe { *x }, 2);
60 }
61
62 fn ptr_arith_offset_overflow() {
63     let v = [1i16, 2];
64     let x = &mut ptr::null(); // going through memory as there are more sanity checks along that path
65     *x = v.as_ptr().wrapping_offset(1); // ptr to the 2nd element
66     // Adding 2*isize::max and then 1 is like substracting 1
67     *x = x.wrapping_offset(isize::MAX);
68     *x = x.wrapping_offset(isize::MAX);
69     *x = x.wrapping_offset(1);
70     assert_eq!(unsafe { **x }, 1);
71 }
72
73 fn ptr_offset() {
74     fn f() -> i32 {
75         42
76     }
77
78     let v = [1i16, 2];
79     let x = &v as *const [i16; 2] as *const i16;
80     let x = unsafe { x.offset(1) };
81     assert_eq!(unsafe { *x }, 2);
82
83     // fn ptr offset
84     unsafe {
85         let p = f as fn() -> i32 as usize;
86         let x = (p as *mut u32).offset(0) as usize;
87         // *cast* to ptr, then transmute to fn ptr.
88         // (transmuting int to [fn]ptr causes trouble.)
89         let f: fn() -> i32 = mem::transmute(x as *const ());
90         assert_eq!(f(), 42);
91     }
92 }