a bit of refactoring and tweak the aligned-allocation tests
This commit is contained in:
parent
5ea21ca486
commit
430298c3ad
4 changed files with 61 additions and 62 deletions
|
@ -175,10 +175,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
|
|
||||||
fn aligned_alloc(
|
fn aligned_alloc(
|
||||||
&mut self,
|
&mut self,
|
||||||
align: u64,
|
align: &OpTy<'tcx, Provenance>,
|
||||||
size: u64,
|
size: &OpTy<'tcx, Provenance>,
|
||||||
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||||
let this = self.eval_context_mut();
|
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".
|
// Alignment must be a power of 2, and "supported by the implementation".
|
||||||
// We decide that "supported by the implementation" means that the
|
// We decide that "supported by the implementation" means that the
|
||||||
// size must be a multiple of the alignment. (This restriction seems common
|
// size must be a multiple of the alignment. (This restriction seems common
|
||||||
|
|
|
@ -300,9 +300,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
// (MSVC explicitly does not support this.)
|
// (MSVC explicitly does not support this.)
|
||||||
let [align, size] =
|
let [align, size] =
|
||||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
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)?;
|
let res = this.aligned_alloc(align, size)?;
|
||||||
this.write_pointer(res, dest)?;
|
this.write_pointer(res, dest)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
"aligned_alloc" => {
|
"aligned_alloc" => {
|
||||||
let [align, size] =
|
let [align, size] =
|
||||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
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)?;
|
let res = this.aligned_alloc(align, size)?;
|
||||||
this.write_pointer(res, dest)?;
|
this.write_pointer(res, dest)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,53 +148,55 @@ fn test_calloc() {
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
fn test_memalign() {
|
fn test_memalign() {
|
||||||
// A normal allocation.
|
for _ in 0..16 {
|
||||||
unsafe {
|
// A normal allocation.
|
||||||
let mut ptr: *mut libc::c_void = ptr::null_mut();
|
unsafe {
|
||||||
let align = 8;
|
let mut ptr: *mut libc::c_void = ptr::null_mut();
|
||||||
let size = 64;
|
let align = 8;
|
||||||
assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
|
let size = 64;
|
||||||
assert!(!ptr.is_null());
|
assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
|
||||||
assert!(ptr.is_aligned_to(align));
|
assert!(!ptr.is_null());
|
||||||
ptr.cast::<u8>().write_bytes(1, size);
|
assert!(ptr.is_aligned_to(align));
|
||||||
libc::free(ptr);
|
ptr.cast::<u8>().write_bytes(1, size);
|
||||||
}
|
libc::free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
// Align > size.
|
// Align > size.
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut ptr: *mut libc::c_void = ptr::null_mut();
|
let mut ptr: *mut libc::c_void = ptr::null_mut();
|
||||||
let align = 64;
|
let align = 64;
|
||||||
let size = 8;
|
let size = 8;
|
||||||
assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
|
assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
|
||||||
assert!(!ptr.is_null());
|
assert!(!ptr.is_null());
|
||||||
assert!(ptr.is_aligned_to(align));
|
assert!(ptr.is_aligned_to(align));
|
||||||
ptr.cast::<u8>().write_bytes(1, size);
|
ptr.cast::<u8>().write_bytes(1, size);
|
||||||
libc::free(ptr);
|
libc::free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size not multiple of align
|
// Size not multiple of align
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut ptr: *mut libc::c_void = ptr::null_mut();
|
let mut ptr: *mut libc::c_void = ptr::null_mut();
|
||||||
let align = 16;
|
let align = 16;
|
||||||
let size = 31;
|
let size = 31;
|
||||||
assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
|
assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
|
||||||
assert!(!ptr.is_null());
|
assert!(!ptr.is_null());
|
||||||
assert!(ptr.is_aligned_to(align));
|
assert!(ptr.is_aligned_to(align));
|
||||||
ptr.cast::<u8>().write_bytes(1, size);
|
ptr.cast::<u8>().write_bytes(1, size);
|
||||||
libc::free(ptr);
|
libc::free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size == 0
|
// Size == 0
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut ptr: *mut libc::c_void = ptr::null_mut();
|
let mut ptr: *mut libc::c_void = ptr::null_mut();
|
||||||
let align = 64;
|
let align = 64;
|
||||||
let size = 0;
|
let size = 0;
|
||||||
assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
|
assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
|
||||||
// Non-null pointer is returned if size == 0.
|
// Non-null pointer is returned if size == 0.
|
||||||
// (This is not a guarantee, it just reflects our current behavior.)
|
// (This is not a guarantee, it just reflects our current behavior.)
|
||||||
assert!(!ptr.is_null());
|
assert!(!ptr.is_null());
|
||||||
assert!(ptr.is_aligned_to(align));
|
assert!(ptr.is_aligned_to(align));
|
||||||
libc::free(ptr);
|
libc::free(ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-power of 2 align
|
// Non-power of 2 align
|
||||||
|
@ -260,20 +262,20 @@ fn test_aligned_alloc() {
|
||||||
assert_eq!(p, ptr::null_mut());
|
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
|
// repeated tests on correct alignment/size
|
||||||
for _ in 0..16 {
|
for _ in 0..16 {
|
||||||
|
// alignment 1, size 4 should succeed and actually must align to 4 (because C says so...)
|
||||||
unsafe {
|
unsafe {
|
||||||
let p = aligned_alloc(16, 16);
|
let p = aligned_alloc(1, 4);
|
||||||
assert!(!p.is_null());
|
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);
|
libc::free(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue