1 //@compile-flags: -Zmiri-symbolic-alignment-check
2 #![feature(strict_provenance)]
6 fn test_align_offset() {
7 let d = Box::new([0u32; 4]);
8 // Get u8 pointer to base
9 let raw = d.as_ptr() as *const u8;
11 assert_eq!(raw.align_offset(2), 0);
12 assert_eq!(raw.align_offset(4), 0);
13 assert_eq!(raw.align_offset(8), usize::MAX); // requested alignment higher than allocation alignment
15 assert_eq!(raw.wrapping_offset(1).align_offset(2), 1);
16 assert_eq!(raw.wrapping_offset(1).align_offset(4), 3);
17 assert_eq!(raw.wrapping_offset(1).align_offset(8), usize::MAX); // requested alignment higher than allocation alignment
19 assert_eq!(raw.wrapping_offset(2).align_offset(2), 0);
20 assert_eq!(raw.wrapping_offset(2).align_offset(4), 2);
21 assert_eq!(raw.wrapping_offset(2).align_offset(8), usize::MAX); // requested alignment higher than allocation alignment
23 let p = ptr::invalid::<()>(1);
24 assert_eq!(p.align_offset(1), 0);
29 let d = Box::new([0u32; N]);
30 // Get u8 slice covering the entire thing
31 let s = unsafe { std::slice::from_raw_parts(d.as_ptr() as *const u8, 4 * N) };
35 let (l, m, r) = unsafe { s.align_to::<u32>() };
36 assert_eq!(l.len(), 0);
37 assert_eq!(r.len(), 0);
38 assert_eq!(m.len(), N);
39 assert_eq!(raw, m.as_ptr() as *const u8);
43 let (l, m, r) = unsafe { s[1..].align_to::<u32>() };
44 assert_eq!(l.len(), 3);
45 assert_eq!(m.len(), N - 1);
46 assert_eq!(r.len(), 0);
47 assert_eq!(raw.wrapping_offset(4), m.as_ptr() as *const u8);
51 let (l, m, r) = unsafe { s[..4 * N - 1].align_to::<u32>() };
52 assert_eq!(l.len(), 0);
53 assert_eq!(m.len(), N - 1);
54 assert_eq!(r.len(), 3);
55 assert_eq!(raw, m.as_ptr() as *const u8);
59 let (l, m, r) = unsafe { s[1..4 * N - 1].align_to::<u32>() };
60 assert_eq!(l.len(), 3);
61 assert_eq!(m.len(), N - 2);
62 assert_eq!(r.len(), 3);
63 assert_eq!(raw.wrapping_offset(4), m.as_ptr() as *const u8);
70 let (l, m, r) = unsafe { s.align_to::<Align8>() }; // requested alignment higher than allocation alignment
71 assert_eq!(l.len(), 4 * N);
72 assert_eq!(r.len(), 0);
73 assert_eq!(m.len(), 0);
79 let vec = vec![0x4141414141414141u64; N];
80 let content = unsafe { std::slice::from_raw_parts(vec.as_ptr() as *const u8, 8 * N) };
81 println!("{:?}", std::str::from_utf8(content).unwrap());
87 struct AlignToU64<T>(T);
89 const BYTE_LEN: usize = std::mem::size_of::<[u64; 4]>();
90 type Data = AlignToU64<[u8; BYTE_LEN]>;
92 fn example(data: &Data) {
93 let (head, u64_arrays, tail) = unsafe { data.0.align_to::<[u64; 4]>() };
95 assert!(head.is_empty(), "buffer was not aligned for 64-bit numbers");
96 assert_eq!(u64_arrays.len(), 1, "buffer was not long enough");
97 assert!(tail.is_empty(), "buffer was too long");
99 let u64_array = &u64_arrays[0];
100 let _val = u64_array[0]; // make sure we can actually load this
103 example(&Data::default());