commit
7d7cf4d42e
@ -147,6 +147,45 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
|
||||
)?;
|
||||
}
|
||||
}
|
||||
"realloc" => {
|
||||
let old_ptr = this.read_scalar(args[0])?.not_undef()?;
|
||||
let new_size = this.read_scalar(args[1])?.to_usize(this)?;
|
||||
let align = this.tcx.data_layout.pointer_align.abi;
|
||||
if old_ptr.is_null_ptr(this) {
|
||||
if new_size == 0 {
|
||||
this.write_null(dest)?;
|
||||
} else {
|
||||
let new_ptr = this.memory_mut().allocate(
|
||||
Size::from_bytes(new_size),
|
||||
align,
|
||||
MiriMemoryKind::C.into()
|
||||
);
|
||||
this.write_scalar(Scalar::Ptr(new_ptr), dest)?;
|
||||
}
|
||||
} else {
|
||||
let old_ptr = old_ptr.to_ptr()?;
|
||||
let memory = this.memory_mut();
|
||||
let old_size = Size::from_bytes(memory.get(old_ptr.alloc_id)?.bytes.len() as u64);
|
||||
if new_size == 0 {
|
||||
memory.deallocate(
|
||||
old_ptr,
|
||||
Some((old_size, align)),
|
||||
MiriMemoryKind::C.into(),
|
||||
)?;
|
||||
this.write_null(dest)?;
|
||||
} else {
|
||||
let new_ptr = memory.reallocate(
|
||||
old_ptr,
|
||||
old_size,
|
||||
align,
|
||||
Size::from_bytes(new_size),
|
||||
align,
|
||||
MiriMemoryKind::C.into(),
|
||||
)?;
|
||||
this.write_scalar(Scalar::Ptr(new_ptr), dest)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"__rust_alloc" => {
|
||||
let size = this.read_scalar(args[0])?.to_usize(this)?;
|
||||
|
45
tests/run-pass/realloc.rs
Normal file
45
tests/run-pass/realloc.rs
Normal file
@ -0,0 +1,45 @@
|
||||
//ignore-windows: Uses POSIX APIs
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
use core::{slice, ptr};
|
||||
|
||||
extern crate libc;
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
// Use calloc for initialized memory
|
||||
let p1 = libc::calloc(20, 1);
|
||||
|
||||
// old size < new size
|
||||
let p2 = libc::realloc(p1, 40);
|
||||
let slice = slice::from_raw_parts(p2 as *const u8, 20);
|
||||
assert_eq!(&slice, &[0_u8; 20]);
|
||||
|
||||
// old size == new size
|
||||
let p3 = libc::realloc(p2, 40);
|
||||
let slice = slice::from_raw_parts(p3 as *const u8, 20);
|
||||
assert_eq!(&slice, &[0_u8; 20]);
|
||||
|
||||
// old size > new size
|
||||
let p4 = libc::realloc(p3, 10);
|
||||
let slice = slice::from_raw_parts(p4 as *const u8, 10);
|
||||
assert_eq!(&slice, &[0_u8; 10]);
|
||||
|
||||
libc::free(p4);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let p1 = libc::malloc(20);
|
||||
|
||||
let p2 = libc::realloc(p1, 0);
|
||||
assert!(p2.is_null());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let p1 = libc::realloc(ptr::null_mut(), 20);
|
||||
assert!(!p1.is_null());
|
||||
|
||||
libc::free(p1);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user