Merge pull request #696 from TimDiekmann/realloc

Add `realloc`
This commit is contained in:
Ralf Jung 2019-04-18 17:21:04 +02:00 committed by GitHub
commit 7d7cf4d42e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 84 additions and 0 deletions

View File

@ -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
View 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);
}
}