Reading undef local/globals gets PrimVal::Undef.

This fixes #95.
This commit is contained in:
Scott Olson 2016-12-17 03:36:22 -08:00
parent 6b7c68bec2
commit 459a27d6bd
3 changed files with 18 additions and 15 deletions

View File

@ -774,7 +774,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
substs: substs,
promoted: None,
};
self.read_lvalue(Lvalue::Global(cid))?
self.read_lvalue(Lvalue::Global(cid))
}
}
@ -784,7 +784,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
substs: self.substs(),
promoted: Some(index),
};
self.read_lvalue(Lvalue::Global(cid))?
self.read_lvalue(Lvalue::Global(cid))
}
};

View File

@ -1,12 +1,13 @@
use rustc::hir::def_id::DefId;
use rustc::mir;
use rustc::ty::{self, Ty};
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty};
use rustc_data_structures::indexed_vec::Idx;
use error::{EvalError, EvalResult};
use error::EvalResult;
use eval_context::{EvalContext};
use memory::Pointer;
use eval_context::{EvalContext, Value};
use value::{PrimVal, Value};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Lvalue<'tcx> {
@ -117,23 +118,25 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
}
}
let lvalue = self.eval_lvalue(lvalue)?;
self.read_lvalue(lvalue)
Ok(self.read_lvalue(lvalue))
}
pub fn read_lvalue(&self, lvalue: Lvalue<'tcx>) -> EvalResult<'tcx, Value> {
pub fn read_lvalue(&self, lvalue: Lvalue<'tcx>) -> Value {
match lvalue {
Lvalue::Ptr { ptr, extra } => {
assert_eq!(extra, LvalueExtra::None);
Ok(Value::ByRef(ptr))
Value::ByRef(ptr)
}
Lvalue::Local { frame, local } => {
self.stack[frame].get_local(local).ok_or(EvalError::ReadUndefBytes)
self.stack[frame].get_local(local).unwrap_or(Value::ByVal(PrimVal::Undef))
}
Lvalue::Global(cid) => {
self.globals
.get(&cid)
.expect("global not cached")
.data
.unwrap_or(Value::ByVal(PrimVal::Undef))
}
Lvalue::Global(cid) => self.globals
.get(&cid)
.expect("global not cached")
.data
.ok_or(EvalError::ReadUndefBytes),
}
}

View File

@ -585,7 +585,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
match ty.sty {
// special case `Box` to deallocate the inner allocation
ty::TyBox(contents_ty) => {
let val = self.read_lvalue(lval)?;
let val = self.read_lvalue(lval);
// we are going through the read_value path, because that already does all the
// checks for the trait object types. We'd only be repeating ourselves here.
let val = self.follow_by_ref_value(val, ty)?;