about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-04-24 18:04:51 +0000
committerbors <bors@rust-lang.org>2018-04-24 18:04:51 +0000
commitf5203d1073a774e01ae0c57ebb561648a8fd9910 (patch)
treeaccb47a2343d06b9ba84227196e175784d1861c6
parent38e251ba37231f3471a20a13f503b191ed25a499 (diff)
parent3084c066e408f7a2921b02a16f115bb4833c71de (diff)
downloadrust-f5203d1073a774e01ae0c57ebb561648a8fd9910.tar.gz
rust-f5203d1073a774e01ae0c57ebb561648a8fd9910.zip
Auto merge of #49933 - oli-obk:miri_rustup, r=eddyb
Fix the miri tool

r? @eddyb

cc @bjorn3

fixes #49777
-rw-r--r--src/Cargo.lock15
-rwxr-xr-xsrc/ci/docker/x86_64-gnu-tools/checktools.sh2
-rw-r--r--src/librustc_mir/hair/pattern/mod.rs35
-rw-r--r--src/librustc_mir/interpret/const_eval.rs8
-rw-r--r--src/librustc_mir/interpret/eval_context.rs87
-rw-r--r--src/librustc_mir/interpret/memory.rs9
-rw-r--r--src/librustc_mir/interpret/mod.rs2
-rw-r--r--src/librustc_mir/interpret/terminator/mod.rs4
m---------src/tools/miri36
9 files changed, 97 insertions, 101 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index d60a8689f3d..5fd8334e8ed 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -224,16 +224,6 @@ dependencies = [
 
 [[package]]
 name = "cargo_metadata"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "cargo_metadata"
 version = "0.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -1188,9 +1178,11 @@ name = "miri"
 version = "0.1.0"
 dependencies = [
  "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiletest_rs 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2923,7 +2915,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
 "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32"
 "checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87"
-"checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b"
 "checksum cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebd6272a2ca4fd39dbabbd6611eb03df45c2259b3b80b39a9ff8fbdcf42a4b3"
 "checksum cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8b9d2900f78631a5876dc5d6c9033ede027253efcd33dd36b1309fc6cab97ee0"
 "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh
index da89aa9423b..3fed0175371 100755
--- a/src/ci/docker/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh
@@ -67,7 +67,7 @@ verify_status rust-by-example src/doc/rust-by-example
 verify_status rls src/tool/rls
 verify_status rustfmt src/tool/rustfmt
 verify_status clippy-driver src/tool/clippy
-#verify_status miri src/tool/miri
+verify_status miri src/tool/miri
 
 if [ "$RUST_RELEASE_CHANNEL" = nightly -a -n "${TOOLSTATE_REPO_ACCESS_TOKEN+is_set}" ]; then
     . "$(dirname $0)/repo.sh"
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 9f17af8b16f..c2da8c11d87 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -16,7 +16,7 @@ mod check_match;
 pub use self::check_match::check_crate;
 pub(crate) use self::check_match::check_match;
 
-use interpret::{const_val_field, const_discr, self};
+use interpret::{const_val_field, const_variant_index, self};
 
 use rustc::middle::const_val::ConstVal;
 use rustc::mir::{Field, BorrowKind, Mutability};
@@ -835,38 +835,9 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
             ty::TyAdt(adt_def, substs) if adt_def.is_enum() => {
                 match cv.val {
                     ConstVal::Value(val) => {
-                        let discr_val = const_discr(
+                        let variant_index = const_variant_index(
                             self.tcx, self.param_env, instance, val, cv.ty
-                        ).expect("const_discr failed");
-                        let layout = self
-                            .tcx
-                            .layout_of(self.param_env.and(cv.ty))
-                            .expect("layout of enum not available");
-                        let variant_index = match layout.variants {
-                            ty::layout::Variants::Single { index } => index,
-                            ty::layout::Variants::Tagged { ref discr, .. } => {
-                                // raw discriminants for enums are isize or bigger during
-                                // their computation, but later shrunk to the smallest possible
-                                // representation
-                                let size = discr.value.size(self.tcx).bits();
-                                let amt = 128 - size;
-                                adt_def
-                                    .discriminants(self.tcx)
-                                    .position(|var| ((var.val << amt) >> amt) == discr_val)
-                                    .unwrap_or_else(|| {
-                                        bug!("discriminant {} not found in {:#?}",
-                                            discr_val,
-                                            adt_def
-                                                .discriminants(self.tcx)
-                                                .collect::<Vec<_>>(),
-                                            );
-                                    })
-                            }
-                            ty::layout::Variants::NicheFilling { .. } => {
-                                assert_eq!(discr_val as usize as u128, discr_val);
-                                discr_val as usize
-                            },
-                        };
+                        ).expect("const_variant_index failed");
                         let subpatterns = adt_subpatterns(
                             adt_def.variants[variant_index].fields.len(),
                             Some(variant_index),
diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs
index 6fa68eb6ff1..a25331f7279 100644
--- a/src/librustc_mir/interpret/const_eval.rs
+++ b/src/librustc_mir/interpret/const_eval.rs
@@ -400,14 +400,14 @@ pub fn const_val_field<'a, 'tcx>(
     }
 }
 
-pub fn const_discr<'a, 'tcx>(
+pub fn const_variant_index<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     instance: ty::Instance<'tcx>,
     value: Value,
     ty: Ty<'tcx>,
-) -> EvalResult<'tcx, u128> {
-    trace!("const_discr: {:?}, {:?}, {:?}", instance, value, ty);
+) -> EvalResult<'tcx, usize> {
+    trace!("const_variant_index: {:?}, {:?}, {:?}", instance, value, ty);
     let mut ecx = mk_eval_cx(tcx, instance, param_env).unwrap();
     let (ptr, align) = match value {
         Value::ByValPair(..) | Value::ByVal(_) => {
@@ -421,7 +421,7 @@ pub fn const_discr<'a, 'tcx>(
         Value::ByRef(ptr, align) => (ptr, align),
     };
     let place = Place::from_primval_ptr(ptr, align);
-    ecx.read_discriminant_value(place, ty)
+    ecx.read_discriminant_as_variant_index(place, ty)
 }
 
 pub fn const_eval_provider<'a, 'tcx>(
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index a5ddd50ae10..b98ab218de5 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -743,28 +743,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
 
             Discriminant(ref place) => {
                 let ty = self.place_ty(place);
-                let layout = self.layout_of(ty)?;
                 let place = self.eval_place(place)?;
                 let discr_val = self.read_discriminant_value(place, ty)?;
-                match layout.variants {
-                    layout::Variants::Single { index } => {
-                        assert_eq!(discr_val, index as u128);
-                    }
-                    layout::Variants::Tagged { .. } |
-                    layout::Variants::NicheFilling { .. } => {
-                        if let ty::TyAdt(adt_def, _) = ty.sty {
-                            trace!("Read discriminant {}, valid discriminants {:?}", discr_val, adt_def.discriminants(*self.tcx).collect::<Vec<_>>());
-                            if adt_def.discriminants(*self.tcx).all(|v| {
-                                discr_val != v.val
-                            })
-                            {
-                                return err!(InvalidDiscriminant);
-                            }
-                        } else {
-                            bug!("rustc only generates Rvalue::Discriminant for enums");
-                        }
-                    }
-                }
                 self.write_primval(dest, PrimVal::Bytes(discr_val), dest_ty)?;
             }
         }
@@ -837,13 +817,39 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
         }
     }
 
+    /// reads a tag and produces the corresponding variant index
+    pub fn read_discriminant_as_variant_index(
+        &mut self,
+        place: Place,
+        ty: Ty<'tcx>,
+    ) -> EvalResult<'tcx, usize> {
+        let layout = self.layout_of(ty)?;
+        match layout.variants {
+            ty::layout::Variants::Single { index } => Ok(index),
+            ty::layout::Variants::Tagged { .. } => {
+                let discr_val = self.read_discriminant_value(place, ty)?;
+                ty
+                    .ty_adt_def()
+                    .expect("tagged layout for non adt")
+                    .discriminants(self.tcx.tcx)
+                    .position(|var| var.val == discr_val)
+                    .ok_or_else(|| EvalErrorKind::InvalidDiscriminant.into())
+            }
+            ty::layout::Variants::NicheFilling { .. } => {
+                let discr_val = self.read_discriminant_value(place, ty)?;
+                assert_eq!(discr_val as usize as u128, discr_val);
+                Ok(discr_val as usize)
+            },
+        }
+    }
+
     pub fn read_discriminant_value(
         &mut self,
         place: Place,
         ty: Ty<'tcx>,
     ) -> EvalResult<'tcx, u128> {
         let layout = self.layout_of(ty)?;
-        //trace!("read_discriminant_value {:#?}", layout);
+        trace!("read_discriminant_value {:#?}", layout);
 
         match layout.variants {
             layout::Variants::Single { index } => {
@@ -854,13 +860,34 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
         }
 
         let (discr_place, discr) = self.place_field(place, mir::Field::new(0), layout)?;
+        trace!("discr place: {:?}, {:?}", discr_place, discr);
         let raw_discr = self.value_to_primval(ValTy {
             value: self.read_place(discr_place)?,
             ty: discr.ty
         })?;
         let discr_val = match layout.variants {
             layout::Variants::Single { .. } => bug!(),
-            layout::Variants::Tagged { .. } => raw_discr.to_bytes()?,
+            // FIXME: should we catch invalid discriminants here?
+            layout::Variants::Tagged { .. } => {
+                if discr.ty.is_signed() {
+                    let i = raw_discr.to_bytes()? as i128;
+                    // going from layout tag type to typeck discriminant type
+                    // requires first sign extending with the layout discriminant
+                    let amt = 128 - discr.size.bits();
+                    let sexted = (i << amt) >> amt;
+                    // and then zeroing with the typeck discriminant type
+                    let discr_ty = ty
+                        .ty_adt_def().expect("tagged layout corresponds to adt")
+                        .repr
+                        .discr_type();
+                    let discr_ty = layout::Integer::from_attr(self.tcx.tcx, discr_ty);
+                    let amt = 128 - discr_ty.size().bits();
+                    let truncatee = sexted as u128;
+                    (truncatee << amt) >> amt
+                } else {
+                    raw_discr.to_bytes()?
+                }
+            },
             layout::Variants::NicheFilling {
                 dataful_variant,
                 ref niche_variants,
@@ -910,11 +937,18 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
                                layout::Abi::Uninhabited);
                 }
             }
-            layout::Variants::Tagged { .. } => {
+            layout::Variants::Tagged { ref discr, .. } => {
                 let discr_val = dest_ty.ty_adt_def().unwrap()
                     .discriminant_for_variant(*self.tcx, variant_index)
                     .val;
 
+                // raw discriminants for enums are isize or bigger during
+                // their computation, but the in-memory tag is the smallest possible
+                // representation
+                let size = discr.value.size(self.tcx.tcx).bits();
+                let amt = 128 - size;
+                let discr_val = (discr_val << amt) >> amt;
+
                 let (discr_dest, discr) = self.place_field(dest, mir::Field::new(0), layout)?;
                 self.write_primval(discr_dest, PrimVal::Bytes(discr_val), discr.ty)?;
             }
@@ -1145,19 +1179,18 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
                     _ if primval.is_undef() => false,
                     _ => bug!("write_value_to_ptr: invalid ByVal layout: {:#?}", layout)
                 };
-                self.memory.write_primval(dest.to_ptr()?, dest_align, primval, layout.size.bytes(), signed)
+                self.memory.write_primval(dest, dest_align, primval, layout.size.bytes(), signed)
             }
             Value::ByValPair(a_val, b_val) => {
-                let ptr = dest.to_ptr()?;
                 trace!("write_value_to_ptr valpair: {:#?}", layout);
                 let (a, b) = match layout.abi {
                     layout::Abi::ScalarPair(ref a, ref b) => (&a.value, &b.value),
                     _ => bug!("write_value_to_ptr: invalid ByValPair layout: {:#?}", layout)
                 };
                 let (a_size, b_size) = (a.size(&self), b.size(&self));
-                let a_ptr = ptr;
+                let a_ptr = dest;
                 let b_offset = a_size.abi_align(b.align(&self));
-                let b_ptr = ptr.offset(b_offset.bytes(), &self)?.into();
+                let b_ptr = dest.offset(b_offset.bytes(), &self)?.into();
                 // TODO: What about signedess?
                 self.memory.write_primval(a_ptr, dest_align, a_val, a_size.bytes(), false)?;
                 self.memory.write_primval(b_ptr, dest_align, b_val, b_size.bytes(), false)
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index dcf97f61545..5e156e9271f 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -691,7 +691,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
         self.read_primval(ptr, ptr_align, self.pointer_size())
     }
 
-    pub fn write_primval(&mut self, ptr: MemoryPointer, ptr_align: Align, val: PrimVal, size: u64, signed: bool) -> EvalResult<'tcx> {
+    pub fn write_primval(&mut self, ptr: Pointer, ptr_align: Align, val: PrimVal, size: u64, signed: bool) -> EvalResult<'tcx> {
         let endianness = self.endianness();
 
         let bytes = match val {
@@ -703,11 +703,14 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
             PrimVal::Bytes(bytes) => bytes,
 
             PrimVal::Undef => {
-                self.mark_definedness(PrimVal::Ptr(ptr).into(), size, false)?;
+                self.check_align(ptr.into(), ptr_align)?;
+                self.mark_definedness(ptr, size, false)?;
                 return Ok(());
             }
         };
 
+        let ptr = ptr.to_ptr()?;
+
         {
             let align = self.int_align(size);
             let dst = self.get_bytes_mut(ptr, size, ptr_align.min(align))?;
@@ -734,7 +737,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
 
     pub fn write_ptr_sized_unsigned(&mut self, ptr: MemoryPointer, ptr_align: Align, val: PrimVal) -> EvalResult<'tcx> {
         let ptr_size = self.pointer_size();
-        self.write_primval(ptr, ptr_align, val, ptr_size, false)
+        self.write_primval(ptr.into(), ptr_align, val, ptr_size, false)
     }
 
     fn int_align(&self, size: u64) -> Align {
diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs
index e0e05d6ae60..1eb131810bd 100644
--- a/src/librustc_mir/interpret/mod.rs
+++ b/src/librustc_mir/interpret/mod.rs
@@ -25,7 +25,7 @@ pub use self::const_eval::{
     CompileTimeEvaluator,
     const_eval_provider,
     const_val_field,
-    const_discr,
+    const_variant_index,
 };
 
 pub use self::machine::Machine;
diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs
index 851fac532e3..3360e5b72a7 100644
--- a/src/librustc_mir/interpret/terminator/mod.rs
+++ b/src/librustc_mir/interpret/terminator/mod.rs
@@ -37,7 +37,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
                 ref targets,
                 ..
             } => {
-                // FIXME(CTFE): forbid branching
                 let discr_val = self.eval_operand(discr)?;
                 let discr_prim = self.value_to_primval(discr_val)?;
 
@@ -45,8 +44,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
                 let mut target_block = targets[targets.len() - 1];
 
                 for (index, &const_int) in values.iter().enumerate() {
-                    let prim = PrimVal::Bytes(const_int);
-                    if discr_prim.to_bytes()? == prim.to_bytes()? {
+                    if discr_prim.to_bytes()? == const_int {
                         target_block = targets[index];
                         break;
                     }
diff --git a/src/tools/miri b/src/tools/miri
-Subproject d4712ca37500f26bbcbf97edcb27820717f769f
+Subproject f48fed70d4447445b586a35c4ae88683542ffc7