report better errors when using a fn ptr as memory and vice versa

This commit is contained in:
Oliver Schneider 2016-06-13 11:39:15 +02:00
parent 875e00fd6e
commit 4d090fa693
No known key found for this signature in database
GPG key ID: 56D6EEA0FC67AC46
2 changed files with 30 additions and 3 deletions

View file

@ -20,6 +20,8 @@ pub enum EvalError {
ReadUndefBytes,
InvalidBoolOp(mir::BinOp),
Unimplemented(String),
DerefFunctionPointer,
ExecuteMemory,
}
pub type EvalResult<T> = Result<T, EvalError>;
@ -48,6 +50,10 @@ impl Error for EvalError {
EvalError::InvalidBoolOp(_) =>
"invalid boolean operation",
EvalError::Unimplemented(ref msg) => msg,
EvalError::DerefFunctionPointer =>
"tried to dereference a function pointer",
EvalError::ExecuteMemory =>
"tried to treat a memory pointer as a function pointer",
}
}

View file

@ -46,7 +46,10 @@ impl Pointer {
////////////////////////////////////////////////////////////////////////////////
pub struct Memory<'tcx> {
/// Actual memory allocations (arbitrary bytes, may contain pointers into other allocations)
alloc_map: HashMap<AllocId, Allocation>,
/// Function "allocations". They exist solely so pointers have something to point to, and
/// we can figure out what they point to.
functions: HashMap<AllocId, (DefId, &'tcx Substs<'tcx>)>,
next_id: AllocId,
pub pointer_size: usize,
@ -137,16 +140,34 @@ impl<'tcx> Memory<'tcx> {
////////////////////////////////////////////////////////////////////////////////
pub fn get(&self, id: AllocId) -> EvalResult<&Allocation> {
self.alloc_map.get(&id).ok_or(EvalError::DanglingPointerDeref)
match self.alloc_map.get(&id) {
Some(alloc) => Ok(alloc),
None => match self.functions.get(&id) {
Some(_) => Err(EvalError::DerefFunctionPointer),
None => Err(EvalError::DanglingPointerDeref),
}
}
}
pub fn get_mut(&mut self, id: AllocId) -> EvalResult<&mut Allocation> {
self.alloc_map.get_mut(&id).ok_or(EvalError::DanglingPointerDeref)
match self.alloc_map.get_mut(&id) {
Some(alloc) => Ok(alloc),
None => match self.functions.get(&id) {
Some(_) => Err(EvalError::DerefFunctionPointer),
None => Err(EvalError::DanglingPointerDeref),
}
}
}
pub fn get_fn(&self, id: AllocId) -> EvalResult<(DefId, &'tcx Substs<'tcx>)> {
debug!("reading fn ptr: {}", id);
self.functions.get(&id).map(|&did| did).ok_or(EvalError::InvalidFunctionPointer)
match self.functions.get(&id) {
Some(&fn_id) => Ok(fn_id),
None => match self.alloc_map.get(&id) {
Some(_) => Err(EvalError::ExecuteMemory),
None => Err(EvalError::InvalidFunctionPointer),
}
}
}
/// Print an allocation and all allocations it points to, recursively.