]> git.lizzy.rs Git - rust.git/blob - src/tools/miri/tests/pass-dep/shims/posix_memalign.rs
Rollup merge of #101189 - daxpedda:ready-into-inner, r=joshtriplett
[rust.git] / src / tools / miri / tests / pass-dep / shims / posix_memalign.rs
1 //@ignore-target-windows: No libc on Windows
2
3 #![feature(pointer_is_aligned)]
4 #![feature(strict_provenance)]
5
6 use core::ptr;
7
8 fn main() {
9     // A normal allocation.
10     unsafe {
11         let mut ptr: *mut libc::c_void = ptr::null_mut();
12         let align = 8;
13         let size = 64;
14         assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
15         assert!(!ptr.is_null());
16         assert!(ptr.is_aligned_to(align));
17         ptr.cast::<u8>().write_bytes(1, size);
18         libc::free(ptr);
19     }
20
21     // Align > size.
22     unsafe {
23         let mut ptr: *mut libc::c_void = ptr::null_mut();
24         let align = 64;
25         let size = 8;
26         assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
27         assert!(!ptr.is_null());
28         assert!(ptr.is_aligned_to(align));
29         ptr.cast::<u8>().write_bytes(1, size);
30         libc::free(ptr);
31     }
32
33     // Size not multiple of align
34     unsafe {
35         let mut ptr: *mut libc::c_void = ptr::null_mut();
36         let align = 16;
37         let size = 31;
38         assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
39         assert!(!ptr.is_null());
40         assert!(ptr.is_aligned_to(align));
41         ptr.cast::<u8>().write_bytes(1, size);
42         libc::free(ptr);
43     }
44
45     // Size == 0
46     unsafe {
47         let mut ptr: *mut libc::c_void = ptr::null_mut();
48         let align = 64;
49         let size = 0;
50         assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
51         // We are not required to return null if size == 0, but we currently do.
52         // It's fine to remove this assert if we start returning non-null pointers.
53         assert!(ptr.is_null());
54         assert!(ptr.is_aligned_to(align));
55         // Regardless of what we return, it must be `free`able.
56         libc::free(ptr);
57     }
58
59     // Non-power of 2 align
60     unsafe {
61         let mut ptr: *mut libc::c_void = ptr::invalid_mut(0x1234567);
62         let align = 15;
63         let size = 8;
64         assert_eq!(libc::posix_memalign(&mut ptr, align, size), libc::EINVAL);
65         // The pointer is not modified on failure, posix_memalign(3) says:
66         // > On Linux (and other systems), posix_memalign() does  not  modify  memptr  on failure.
67         // > A requirement standardizing this behavior was added in POSIX.1-2008 TC2.
68         assert_eq!(ptr.addr(), 0x1234567);
69     }
70
71     // Too small align (smaller than ptr)
72     unsafe {
73         let mut ptr: *mut libc::c_void = ptr::invalid_mut(0x1234567);
74         let align = std::mem::size_of::<usize>() / 2;
75         let size = 8;
76         assert_eq!(libc::posix_memalign(&mut ptr, align, size), libc::EINVAL);
77         // The pointer is not modified on failure, posix_memalign(3) says:
78         // > On Linux (and other systems), posix_memalign() does  not  modify  memptr  on failure.
79         // > A requirement standardizing this behavior was added in POSIX.1-2008 TC2.
80         assert_eq!(ptr.addr(), 0x1234567);
81     }
82 }