rust/tests/pass-dep/shims/posix_memalign.rs

83 lines
2.8 KiB
Rust

//@ignore-target-windows: No libc on Windows
#![feature(pointer_is_aligned)]
#![feature(strict_provenance)]
use core::ptr;
fn main() {
// A normal allocation.
unsafe {
let mut ptr: *mut libc::c_void = ptr::null_mut();
let align = 8;
let size = 64;
assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
assert!(!ptr.is_null());
assert!(ptr.is_aligned_to(align));
ptr.cast::<u8>().write_bytes(1, size);
libc::free(ptr);
}
// Align > size.
unsafe {
let mut ptr: *mut libc::c_void = ptr::null_mut();
let align = 64;
let size = 8;
assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
assert!(!ptr.is_null());
assert!(ptr.is_aligned_to(align));
ptr.cast::<u8>().write_bytes(1, size);
libc::free(ptr);
}
// Size not multiple of align
unsafe {
let mut ptr: *mut libc::c_void = ptr::null_mut();
let align = 16;
let size = 31;
assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
assert!(!ptr.is_null());
assert!(ptr.is_aligned_to(align));
ptr.cast::<u8>().write_bytes(1, size);
libc::free(ptr);
}
// Size == 0
unsafe {
let mut ptr: *mut libc::c_void = ptr::null_mut();
let align = 64;
let size = 0;
assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
// We are not required to return null if size == 0, but we currently do.
// It's fine to remove this assert if we start returning non-null pointers.
assert!(ptr.is_null());
assert!(ptr.is_aligned_to(align));
// Regardless of what we return, it must be `free`able.
libc::free(ptr);
}
// Non-power of 2 align
unsafe {
let mut ptr: *mut libc::c_void = ptr::invalid_mut(0x1234567);
let align = 15;
let size = 8;
assert_eq!(libc::posix_memalign(&mut ptr, align, size), libc::EINVAL);
// The pointer is not modified on failure, posix_memalign(3) says:
// > On Linux (and other systems), posix_memalign() does not modify memptr on failure.
// > A requirement standardizing this behavior was added in POSIX.1-2008 TC2.
assert_eq!(ptr.addr(), 0x1234567);
}
// Too small align (smaller than ptr)
unsafe {
let mut ptr: *mut libc::c_void = ptr::invalid_mut(0x1234567);
let align = std::mem::size_of::<usize>() / 2;
let size = 8;
assert_eq!(libc::posix_memalign(&mut ptr, align, size), libc::EINVAL);
// The pointer is not modified on failure, posix_memalign(3) says:
// > On Linux (and other systems), posix_memalign() does not modify memptr on failure.
// > A requirement standardizing this behavior was added in POSIX.1-2008 TC2.
assert_eq!(ptr.addr(), 0x1234567);
}
}