1
Fork 0

print stacktrace when miri can't find the MIR for something

This commit is contained in:
Oliver Schneider 2016-09-27 17:01:06 +02:00
parent 69aeaea01f
commit db8185e439
No known key found for this signature in database
GPG key ID: 56D6EEA0FC67AC46
4 changed files with 18 additions and 11 deletions

View file

@ -9,6 +9,7 @@ use syntax::codemap::Span;
#[derive(Clone, Debug)]
pub enum EvalError<'tcx> {
FunctionPointerTyMismatch(&'tcx BareFnTy<'tcx>, &'tcx BareFnTy<'tcx>),
NoMirFor(String),
DanglingPointerDeref,
InvalidMemoryAccess,
InvalidFunctionPointer,
@ -82,6 +83,8 @@ impl<'tcx> Error for EvalError<'tcx> {
"array index out of bounds",
EvalError::Math(..) =>
"mathematical operation failed",
EvalError::NoMirFor(..) =>
"mir not found",
EvalError::InvalidChar(..) =>
"tried to interpret an invalid 32-bit value as a char",
EvalError::OutOfMemory{..} =>
@ -113,6 +116,7 @@ impl<'tcx> fmt::Display for EvalError<'tcx> {
write!(f, "memory access of {}..{} outside bounds of allocation {} which has size {}",
ptr.offset, ptr.offset + size, ptr.alloc_id, allocation_size)
},
EvalError::NoMirFor(ref func) => write!(f, "no mir for `{}`", func),
EvalError::FunctionPointerTyMismatch(expected, got) =>
write!(f, "tried to call a function of type {:?} through a function pointer of type {:?}", expected, got),
EvalError::ArrayIndexOutOfBounds(span, len, index) =>

View file

@ -267,22 +267,25 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
ty.is_sized(self.tcx, &self.tcx.empty_parameter_environment(), DUMMY_SP)
}
pub fn load_mir(&self, def_id: DefId) -> CachedMir<'a, 'tcx> {
pub fn load_mir(&self, def_id: DefId) -> EvalResult<'tcx, CachedMir<'a, 'tcx>> {
trace!("load mir {:?}", def_id);
if def_id.is_local() {
CachedMir::Ref(self.mir_map.map.get(&def_id).unwrap())
Ok(CachedMir::Ref(self.mir_map.map.get(&def_id).unwrap()))
} else {
let mut mir_cache = self.mir_cache.borrow_mut();
if let Some(mir) = mir_cache.get(&def_id) {
return CachedMir::Owned(mir.clone());
return Ok(CachedMir::Owned(mir.clone()));
}
let cs = &self.tcx.sess.cstore;
let mir = cs.maybe_get_item_mir(self.tcx, def_id).unwrap_or_else(|| {
panic!("no mir for `{}`", self.tcx.item_path_str(def_id));
});
match cs.maybe_get_item_mir(self.tcx, def_id) {
Some(mir) => {
let cached = Rc::new(mir);
mir_cache.insert(def_id, cached.clone());
CachedMir::Owned(cached)
Ok(CachedMir::Owned(cached))
},
None => Err(EvalError::NoMirFor(self.tcx.item_path_str(def_id))),
}
}
}

View file

@ -125,8 +125,8 @@ impl<'a, 'b, 'tcx> ConstantExtractor<'a, 'b, 'tcx> {
if self.ecx.statics.contains_key(&cid) {
return;
}
let mir = self.ecx.load_mir(def_id);
self.try(|this| {
let mir = this.ecx.load_mir(def_id)?;
let ptr = this.ecx.alloc_ret_ptr(mir.return_ty, substs)?;
this.ecx.statics.insert(cid.clone(), ptr);
let cleanup = if immutable && !mir.return_ty.type_contents(this.ecx.tcx).interior_unsafe() {

View file

@ -184,7 +184,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
(def_id, substs)
};
let mir = self.load_mir(resolved_def_id);
let mir = self.load_mir(resolved_def_id)?;
let (return_ptr, return_to_block) = match destination {
Some((ptr, block)) => (Some(ptr), StackPopCleanup::Goto(block)),
None => (None, StackPopCleanup::None),