about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2019-08-25 13:57:46 +0200
committerRalf Jung <post@ralfj.de>2019-08-25 14:09:32 +0200
commit92e75c0f88a5cc09642285fe61a4c1be14fe314d (patch)
tree03ff814e85b39918b5b78a69242d64ae7591430f
parent783469ca09005d135c3204a55069707d1cd705a9 (diff)
downloadrust-92e75c0f88a5cc09642285fe61a4c1be14fe314d.tar.gz
rust-92e75c0f88a5cc09642285fe61a4c1be14fe314d.zip
factor wide ptr metadata checking into separate method
also fat -> wide
-rw-r--r--src/librustc_mir/interpret/validity.rs75
-rw-r--r--src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr12
2 files changed, 48 insertions, 39 deletions
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 82d6d7db01c..f358a21f4af 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -11,7 +11,7 @@ use std::hash::Hash;
 
 use super::{
     GlobalAlloc, InterpResult,
-    OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy,
+    Scalar, OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy,
 };
 
 macro_rules! throw_validation_failure {
@@ -250,6 +250,44 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
         self.path.truncate(path_len);
         Ok(())
     }
+
+    fn check_wide_ptr_meta(
+        &mut self,
+        meta: Option<Scalar<M::PointerTag>>,
+        pointee: TyLayout<'tcx>,
+    ) -> InterpResult<'tcx> {
+        let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(pointee.ty, self.ecx.param_env);
+        match tail.sty {
+            ty::Dynamic(..) => {
+                let vtable = meta.unwrap();
+                try_validation!(
+                    self.ecx.memory.check_ptr_access(
+                        vtable,
+                        3*self.ecx.tcx.data_layout.pointer_size, // drop, size, align
+                        self.ecx.tcx.data_layout.pointer_align.abi,
+                    ),
+                    "dangling or unaligned vtable pointer in wide pointer or too small vtable",
+                    self.path
+                );
+                try_validation!(self.ecx.read_drop_type_from_vtable(vtable),
+                    "invalid drop fn in vtable", self.path);
+                try_validation!(self.ecx.read_size_and_align_from_vtable(vtable),
+                    "invalid size or align in vtable", self.path);
+                // FIXME: More checks for the vtable.
+            }
+            ty::Slice(..) | ty::Str => {
+                try_validation!(meta.unwrap().to_usize(self.ecx),
+                    "non-integer slice length in wide pointer", self.path);
+            }
+            ty::Foreign(..) => {
+                // Unsized, but not wide.
+            }
+            _ =>
+                bug!("Unexpected unsized type tail: {:?}", tail),
+        }
+
+        Ok(())
+    }
 }
 
 impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
@@ -353,44 +391,15 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                 }
             }
             _ if ty.is_box() || ty.is_region_ptr() => {
-                // Handle fat pointers.
+                // Handle wide pointers.
                 // Check metadata early, for better diagnostics
                 let ptr = try_validation!(value.to_scalar_ptr(),
                     "undefined address in pointer", self.path);
                 let meta = try_validation!(value.to_meta(),
-                    "uninitialized data in fat pointer metadata", self.path);
+                    "uninitialized data in wide pointer metadata", self.path);
                 let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
                 if layout.is_unsized() {
-                    let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(layout.ty,
-                                                                          self.ecx.param_env);
-                    match tail.sty {
-                        ty::Dynamic(..) => {
-                            let vtable = meta.unwrap();
-                            try_validation!(
-                                self.ecx.memory.check_ptr_access(
-                                    vtable,
-                                    3*self.ecx.tcx.data_layout.pointer_size, // drop, size, align
-                                    self.ecx.tcx.data_layout.pointer_align.abi,
-                                ),
-                                "dangling or unaligned vtable pointer or too small vtable",
-                                self.path
-                            );
-                            try_validation!(self.ecx.read_drop_type_from_vtable(vtable),
-                                "invalid drop fn in vtable", self.path);
-                            try_validation!(self.ecx.read_size_and_align_from_vtable(vtable),
-                                "invalid size or align in vtable", self.path);
-                            // FIXME: More checks for the vtable.
-                        }
-                        ty::Slice(..) | ty::Str => {
-                            try_validation!(meta.unwrap().to_usize(self.ecx),
-                                "non-integer slice length in fat pointer", self.path);
-                        }
-                        ty::Foreign(..) => {
-                            // Unsized, but not fat.
-                        }
-                        _ =>
-                            bug!("Unexpected unsized type tail: {:?}", tail),
-                    }
+                    self.check_wide_ptr_meta(meta, layout)?;
                 }
                 // Make sure this is dereferencable and all.
                 let (size, align) = self.ecx.size_and_align_of(meta, layout)?
diff --git a/src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr b/src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr
index aac32ecc5b7..54c33006d2b 100644
--- a/src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr
+++ b/src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr
@@ -10,7 +10,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/union-ub-fat-ptr.rs:81:1
    |
 LL | const C: &str = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.str};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
@@ -18,7 +18,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/union-ub-fat-ptr.rs:84:1
    |
 LL | const C2: &MyStr = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.my_str};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
@@ -34,7 +34,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/union-ub-fat-ptr.rs:93:1
    |
 LL | const C3: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.slice};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
@@ -42,7 +42,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/union-ub-fat-ptr.rs:97:1
    |
 LL | const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer or too small vtable
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
@@ -50,7 +50,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/union-ub-fat-ptr.rs:100:1
    |
 LL | const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer or too small vtable
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
@@ -58,7 +58,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/union-ub-fat-ptr.rs:103:1
    |
 LL | const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer or too small vtable
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior