Add handling for nullptr and size == 0

This commit is contained in:
Tim Diekmann 2019-04-18 15:20:32 +02:00
parent afb64232db
commit 9ecc07c9b2
No known key found for this signature in database
GPG key ID: 58CD76F88DF563E0
2 changed files with 50 additions and 14 deletions

View file

@ -147,22 +147,44 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
)?;
}
}
"realloc" => {
let ptr = this.read_scalar(args[0])?.to_ptr()?;
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;
let memory = this.memory_mut();
let old_size = memory.get(ptr.alloc_id)?.bytes.len();
let new_ptr = memory.reallocate(
ptr,
Size::from_bytes(old_size as u64),
align,
Size::from_bytes(new_size),
align,
MiriMemoryKind::C.into(),
)?;
this.write_scalar(Scalar::Ptr(new_ptr), dest)?;
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" => {

View file

@ -2,7 +2,7 @@
#![feature(rustc_private)]
use core::slice;
use core::{slice, ptr};
extern crate libc;
@ -28,4 +28,18 @@ fn main() {
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);
}
}