a bit of refactoring and tweak the aligned-allocation tests

This commit is contained in:
Ralf Jung 2024-05-19 11:48:51 +02:00
parent 5ea21ca486
commit 430298c3ad
4 changed files with 61 additions and 62 deletions

View file

@ -175,10 +175,13 @@ fn realloc(
fn aligned_alloc(
&mut self,
align: u64,
size: u64,
align: &OpTy<'tcx, Provenance>,
size: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let this = self.eval_context_mut();
let align = this.read_target_usize(align)?;
let size = this.read_target_usize(size)?;
// Alignment must be a power of 2, and "supported by the implementation".
// We decide that "supported by the implementation" means that the
// size must be a multiple of the alignment. (This restriction seems common

View file

@ -300,9 +300,6 @@ fn emulate_foreign_item_inner(
// (MSVC explicitly does not support this.)
let [align, size] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let align = this.read_target_usize(align)?;
let size = this.read_target_usize(size)?;
let res = this.aligned_alloc(align, size)?;
this.write_pointer(res, dest)?;
}

View file

@ -29,9 +29,6 @@ fn emulate_foreign_item_inner(
"aligned_alloc" => {
let [align, size] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let align = this.read_target_usize(align)?;
let size = this.read_target_usize(size)?;
let res = this.aligned_alloc(align, size)?;
this.write_pointer(res, dest)?;
}

View file

@ -148,53 +148,55 @@ fn test_calloc() {
#[cfg(not(target_os = "windows"))]
fn test_memalign() {
// 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);
}
for _ in 0..16 {
// 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);
}
// 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 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);
// Non-null pointer is returned if size == 0.
// (This is not a guarantee, it just reflects our current behavior.)
assert!(!ptr.is_null());
assert!(ptr.is_aligned_to(align));
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);
// Non-null pointer is returned if size == 0.
// (This is not a guarantee, it just reflects our current behavior.)
assert!(!ptr.is_null());
assert!(ptr.is_aligned_to(align));
libc::free(ptr);
}
}
// Non-power of 2 align
@ -260,20 +262,20 @@ fn test_aligned_alloc() {
assert_eq!(p, ptr::null_mut());
}
// alignment lesser than a word but still a successful allocation
unsafe {
let p = aligned_alloc(1, 4);
assert!(!p.is_null());
assert!(p.is_aligned_to(4));
libc::free(p);
}
// repeated tests on correct alignment/size
for _ in 0..16 {
// alignment 1, size 4 should succeed and actually must align to 4 (because C says so...)
unsafe {
let p = aligned_alloc(16, 16);
let p = aligned_alloc(1, 4);
assert!(!p.is_null());
assert!(p.is_aligned_to(16));
assert!(p.is_aligned_to(4));
libc::free(p);
}
unsafe {
let p = aligned_alloc(64, 64);
assert!(!p.is_null());
assert!(p.is_aligned_to(64));
libc::free(p);
}
}