]> git.lizzy.rs Git - rust.git/blob - src/tools/miri/tests/pass/align_offset_symbolic.rs
Auto merge of #101833 - jyn514:cross-compile-compiler-builtins, r=Mark-Simulacrum
[rust.git] / src / tools / miri / tests / pass / align_offset_symbolic.rs
1 //@compile-flags: -Zmiri-symbolic-alignment-check
2
3 fn test_align_offset() {
4     let d = Box::new([0u32; 4]);
5     // Get u8 pointer to base
6     let raw = d.as_ptr() as *const u8;
7
8     assert_eq!(raw.align_offset(2), 0);
9     assert_eq!(raw.align_offset(4), 0);
10     assert_eq!(raw.align_offset(8), usize::MAX); // requested alignment higher than allocation alignment
11
12     assert_eq!(raw.wrapping_offset(1).align_offset(2), 1);
13     assert_eq!(raw.wrapping_offset(1).align_offset(4), 3);
14     assert_eq!(raw.wrapping_offset(1).align_offset(8), usize::MAX); // requested alignment higher than allocation alignment
15
16     assert_eq!(raw.wrapping_offset(2).align_offset(2), 0);
17     assert_eq!(raw.wrapping_offset(2).align_offset(4), 2);
18     assert_eq!(raw.wrapping_offset(2).align_offset(8), usize::MAX); // requested alignment higher than allocation alignment
19 }
20
21 fn test_align_to() {
22     const N: usize = 4;
23     let d = Box::new([0u32; N]);
24     // Get u8 slice covering the entire thing
25     let s = unsafe { std::slice::from_raw_parts(d.as_ptr() as *const u8, 4 * N) };
26     let raw = s.as_ptr();
27
28     {
29         let (l, m, r) = unsafe { s.align_to::<u32>() };
30         assert_eq!(l.len(), 0);
31         assert_eq!(r.len(), 0);
32         assert_eq!(m.len(), N);
33         assert_eq!(raw, m.as_ptr() as *const u8);
34     }
35
36     {
37         let (l, m, r) = unsafe { s[1..].align_to::<u32>() };
38         assert_eq!(l.len(), 3);
39         assert_eq!(m.len(), N - 1);
40         assert_eq!(r.len(), 0);
41         assert_eq!(raw.wrapping_offset(4), m.as_ptr() as *const u8);
42     }
43
44     {
45         let (l, m, r) = unsafe { s[..4 * N - 1].align_to::<u32>() };
46         assert_eq!(l.len(), 0);
47         assert_eq!(m.len(), N - 1);
48         assert_eq!(r.len(), 3);
49         assert_eq!(raw, m.as_ptr() as *const u8);
50     }
51
52     {
53         let (l, m, r) = unsafe { s[1..4 * N - 1].align_to::<u32>() };
54         assert_eq!(l.len(), 3);
55         assert_eq!(m.len(), N - 2);
56         assert_eq!(r.len(), 3);
57         assert_eq!(raw.wrapping_offset(4), m.as_ptr() as *const u8);
58     }
59
60     {
61         #[repr(align(8))]
62         struct Align8(u64);
63
64         let (l, m, r) = unsafe { s.align_to::<Align8>() }; // requested alignment higher than allocation alignment
65         assert_eq!(l.len(), 4 * N);
66         assert_eq!(r.len(), 0);
67         assert_eq!(m.len(), 0);
68     }
69 }
70
71 fn test_from_utf8() {
72     const N: usize = 10;
73     let vec = vec![0x4141414141414141u64; N];
74     let content = unsafe { std::slice::from_raw_parts(vec.as_ptr() as *const u8, 8 * N) };
75     println!("{:?}", std::str::from_utf8(content).unwrap());
76 }
77
78 fn test_u64_array() {
79     #[derive(Default)]
80     #[repr(align(8))]
81     struct AlignToU64<T>(T);
82
83     const BYTE_LEN: usize = std::mem::size_of::<[u64; 4]>();
84     type Data = AlignToU64<[u8; BYTE_LEN]>;
85
86     fn example(data: &Data) {
87         let (head, u64_arrays, tail) = unsafe { data.0.align_to::<[u64; 4]>() };
88
89         assert!(head.is_empty(), "buffer was not aligned for 64-bit numbers");
90         assert_eq!(u64_arrays.len(), 1, "buffer was not long enough");
91         assert!(tail.is_empty(), "buffer was too long");
92
93         let u64_array = &u64_arrays[0];
94         let _val = u64_array[0]; // make sure we can actually load this
95     }
96
97     example(&Data::default());
98 }
99
100 fn main() {
101     test_align_offset();
102     test_align_to();
103     test_from_utf8();
104     test_u64_array();
105 }