Skip to content

Commit

Permalink
a bit of refactoring and tweak the aligned-allocation tests
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed May 19, 2024
1 parent d654b73 commit 78ed7ac
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 62 deletions.
7 changes: 5 additions & 2 deletions src/shims/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {

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
Expand Down
3 changes: 0 additions & 3 deletions src/shims/unix/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
// (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)?;
}
Expand Down
3 changes: 0 additions & 3 deletions src/shims/wasi/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
"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)?;
}
Expand Down
110 changes: 56 additions & 54 deletions tests/pass-dep/libc/libc-mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(1, 4);
assert!(!p.is_null());
assert!(p.is_aligned_to(4));
libc::free(p);
}

unsafe {
let p = aligned_alloc(16, 16);
let p = aligned_alloc(64, 64);
assert!(!p.is_null());
assert!(p.is_aligned_to(16));
assert!(p.is_aligned_to(64));
libc::free(p);
}
}
Expand Down

0 comments on commit 78ed7ac

Please sign in to comment.