about summary refs log tree commit diff
path: root/src/librustc_mir/interpret
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2018-11-02 10:01:22 +0100
committerRalf Jung <post@ralfj.de>2018-11-05 09:40:05 +0100
commit996a42557e2816cd577120f464c52b865ef8a924 (patch)
tree0851fc311c1b222b428be1d4192c60a4192bf920 /src/librustc_mir/interpret
parentc2677211f65758f19d7051d6f24a34ce0ec44119 (diff)
downloadrust-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.rs19
-rw-r--r--src/librustc_mir/interpret/visitor.rs14
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.