From 4d090fa6932853b0035745a51fbd4bd88f2ee9b1 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 13 Jun 2016 11:39:15 +0200 Subject: [PATCH] report better errors when using a fn ptr as memory and vice versa --- src/error.rs | 6 ++++++ src/memory.rs | 27 ++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/error.rs b/src/error.rs index a4ae8cbdda25..49fd8564be63 100644 --- a/src/error.rs +++ b/src/error.rs @@ -20,6 +20,8 @@ pub enum EvalError { ReadUndefBytes, InvalidBoolOp(mir::BinOp), Unimplemented(String), + DerefFunctionPointer, + ExecuteMemory, } pub type EvalResult = Result; @@ -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", } } diff --git a/src/memory.rs b/src/memory.rs index ad6c60ef517c..2bc5ff184de0 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -46,7 +46,10 @@ impl Pointer { //////////////////////////////////////////////////////////////////////////////// pub struct Memory<'tcx> { + /// Actual memory allocations (arbitrary bytes, may contain pointers into other allocations) alloc_map: HashMap, + /// Function "allocations". They exist solely so pointers have something to point to, and + /// we can figure out what they point to. functions: HashMap)>, 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.