diff options
| author | Ralf Jung <post@ralfj.de> | 2018-11-02 10:01:22 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2018-11-05 09:40:05 +0100 |
| commit | 996a42557e2816cd577120f464c52b865ef8a924 (patch) | |
| tree | 0851fc311c1b222b428be1d4192c60a4192bf920 /src/librustc_mir/interpret | |
| parent | c2677211f65758f19d7051d6f24a34ce0ec44119 (diff) | |
| download | rust-996a42557e2816cd577120f464c52b865ef8a924.tar.gz rust-996a42557e2816cd577120f464c52b865ef8a924.zip | |
the visitor can already load the value for visit_primitive
Diffstat (limited to 'src/librustc_mir/interpret')
| -rw-r--r-- | src/librustc_mir/interpret/validity.rs | 19 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/visitor.rs | 14 |
2 files changed, 18 insertions, 15 deletions
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index c303d2a1e67..5ba15f4bb99 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -20,7 +20,7 @@ use rustc::mir::interpret::{ }; use super::{ - OpTy, MPlaceTy, Machine, EvalContext, ValueVisitor + OpTy, MPlaceTy, ImmTy, Machine, EvalContext, ValueVisitor }; macro_rules! validation_failure { @@ -213,7 +213,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx> { trace!("visit_value: {:?}, {:?}", *op, op.layout); - // Translate enum discriminant errors to something nicer. + // Translate some possible errors to something nicer. match self.walk_value(op) { Ok(()) => Ok(()), Err(err) => match err.kind { @@ -221,16 +221,17 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> validation_failure!( val, self.path, "a valid enum discriminant" ), + EvalErrorKind::ReadPointerAsBytes => + validation_failure!( + "a pointer", self.path, "plain bytes" + ), _ => Err(err), } } } - fn visit_primitive(&mut self, op: OpTy<'tcx, M::PointerTag>) - -> EvalResult<'tcx> + fn visit_primitive(&mut self, value: ImmTy<'tcx, M::PointerTag>) -> EvalResult<'tcx> { - let value = try_validation!(self.ecx.read_immediate(op), - "uninitialized or unrepresentable data", self.path); // Go over all the primitive types let ty = value.layout.ty; match ty.sty { @@ -379,8 +380,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Ok(()) } - fn visit_uninhabited(&mut self, _op: OpTy<'tcx, M::PointerTag>) - -> EvalResult<'tcx> + fn visit_uninhabited(&mut self) -> EvalResult<'tcx> { validation_failure!("a value of an uninhabited type", self.path) } @@ -390,8 +390,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> op: OpTy<'tcx, M::PointerTag>, layout: &layout::Scalar, ) -> EvalResult<'tcx> { - let value = try_validation!(self.ecx.read_scalar(op), - "uninitialized or unrepresentable data", self.path); + let value = self.ecx.read_scalar(op)?; // Determine the allowed range let (lo, hi) = layout.valid_range.clone().into_inner(); // `max_hi` is as big as the size fits diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs index 7ae747a7357..3211601400a 100644 --- a/src/librustc_mir/interpret/visitor.rs +++ b/src/librustc_mir/interpret/visitor.rs @@ -8,7 +8,7 @@ use rustc::mir::interpret::{ }; use super::{ - Machine, EvalContext, MPlaceTy, PlaceTy, OpTy, + Machine, EvalContext, MPlaceTy, PlaceTy, OpTy, ImmTy, }; // A thing that we can project into, and that has a layout. @@ -205,9 +205,11 @@ pub trait ValueVisitor<'a, 'mir, 'tcx: 'mir+'a, M: Machine<'a, 'mir, 'tcx>>: Siz /// Called whenever we reach a value with uninhabited layout. /// Recursing to fields will continue after this! #[inline(always)] - fn visit_uninhabited(&mut self, _v: Self::V) -> EvalResult<'tcx> + fn visit_uninhabited(&mut self) -> EvalResult<'tcx> { Ok(()) } /// Called whenever we reach a value with scalar layout. + /// We do NOT provide a `ScalarMaybeUndef` here to avoid accessing memory + /// if the visitor is not even interested in scalars. /// Recursing to fields will continue after this! #[inline(always)] fn visit_scalar(&mut self, _v: Self::V, _layout: &layout::Scalar) -> EvalResult<'tcx> @@ -215,7 +217,7 @@ pub trait ValueVisitor<'a, 'mir, 'tcx: 'mir+'a, M: Machine<'a, 'mir, 'tcx>>: Siz /// Called whenever we reach a value of primitive type. There can be no recursion /// below such a value. #[inline(always)] - fn visit_primitive(&mut self, _v: Self::V) -> EvalResult<'tcx> + fn visit_primitive(&mut self, _val: ImmTy<'tcx, M::PointerTag>) -> EvalResult<'tcx> { Ok(()) } // Default recursors. Not meant to be overloaded. @@ -275,7 +277,7 @@ pub trait ValueVisitor<'a, 'mir, 'tcx: 'mir+'a, M: Machine<'a, 'mir, 'tcx>>: Siz // MyNewtype and then the scalar in there). match v.layout().abi { layout::Abi::Uninhabited => { - self.visit_uninhabited(v)?; + self.visit_uninhabited()?; } layout::Abi::Scalar(ref layout) => { self.visit_scalar(v, layout)?; @@ -295,7 +297,9 @@ pub trait ValueVisitor<'a, 'mir, 'tcx: 'mir+'a, M: Machine<'a, 'mir, 'tcx>>: Siz _ => v.layout().ty.builtin_deref(true).is_some(), }; if primitive { - return self.visit_primitive(v); + let op = v.to_op(self.ecx())?; + let val = self.ecx().read_immediate(op)?; + return self.visit_primitive(val); } // Proceed into the fields. |
