about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2019-12-22 00:35:56 +0100
committerOliver Scherer <github35764891676564198441@oli-obk.de>2020-01-07 15:41:48 +0100
commit4a5c35bc4490ecf5b06d311917ac64be63673d3c (patch)
tree6f6e0cdb2503bbbe07b56f00b2b3488430f82353
parent5b770b080fab5a64875ffb10deff9e6d14950fc0 (diff)
downloadrust-4a5c35bc4490ecf5b06d311917ac64be63673d3c.tar.gz
rust-4a5c35bc4490ecf5b06d311917ac64be63673d3c.zip
Fix an ICE happening due code assuming that `MPlaceTy` cannot have integer addresses
-rw-r--r--src/librustc_mir/const_eval/eval_queries.rs18
-rw-r--r--src/librustc_mir/interpret/place.rs26
2 files changed, 25 insertions, 19 deletions
diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs
index 8c41f7d1e61..f28517c6672 100644
--- a/src/librustc_mir/const_eval/eval_queries.rs
+++ b/src/librustc_mir/const_eval/eval_queries.rs
@@ -118,25 +118,11 @@ pub(super) fn op_to_const<'tcx>(
         op.try_as_mplace(ecx)
     };
     let val = match immediate {
-        Ok(mplace) => {
-            let ptr = mplace.ptr.assert_ptr();
-            let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
-            ConstValue::ByRef { alloc, offset: ptr.offset }
-        }
+        Ok(mplace) => mplace.to_const_value(ecx.tcx.tcx),
         // see comment on `let try_as_immediate` above
         Err(ImmTy { imm: Immediate::Scalar(x), .. }) => match x {
             ScalarMaybeUndef::Scalar(s) => ConstValue::Scalar(s),
-            ScalarMaybeUndef::Undef => {
-                // When coming out of "normal CTFE", we'll always have an `Indirect` operand as
-                // argument and we will not need this. The only way we can already have an
-                // `Immediate` is when we are called from `const_field`, and that `Immediate`
-                // comes from a constant so it can happen have `Undef`, because the indirect
-                // memory that was read had undefined bytes.
-                let mplace = op.assert_mem_place(ecx);
-                let ptr = mplace.ptr.assert_ptr();
-                let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
-                ConstValue::ByRef { alloc, offset: ptr.offset }
-            }
+            ScalarMaybeUndef::Undef => op.assert_mem_place(ecx).to_const_value(ecx.tcx.tcx),
         },
         Err(ImmTy { imm: Immediate::ScalarPair(a, b), .. }) => {
             let (data, start) = match a.not_undef().unwrap() {
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 7fbe691f183..54a692c66e3 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -6,12 +6,13 @@ use std::convert::TryFrom;
 use std::hash::Hash;
 
 use rustc::mir;
-use rustc::mir::interpret::truncate;
+use rustc::mir::interpret::{truncate, ConstValue};
 use rustc::ty::layout::{
     self, Align, HasDataLayout, LayoutOf, PrimitiveExt, Size, TyLayout, VariantIdx,
 };
 use rustc::ty::TypeFoldable;
 use rustc::ty::{self, Ty};
+use rustc::ty::{self, Ty, TyCtxt};
 use rustc_macros::HashStable;
 
 use super::{
@@ -195,15 +196,34 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> {
             _ => bug!("vtable not supported on type {:?}", self.layout.ty),
         }
     }
+
+    #[inline(always)]
+    pub fn to_const_value(self, tcx: TyCtxt<'tcx>) -> ConstValue<'tcx> {
+        match self.mplace.ptr {
+            Scalar::Ptr(ptr) => {
+                let alloc = tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
+                ConstValue::ByRef { alloc, offset: ptr.offset }
+            }
+            Scalar::Raw { data, .. } => {
+                assert_eq!(data, self.layout.align.abi.bytes().into());
+                ConstValue::Scalar(Scalar::zst())
+            }
+        }
+    }
 }
 
 // These are defined here because they produce a place.
 impl<'tcx, Tag: ::std::fmt::Debug + Copy> OpTy<'tcx, Tag> {
     #[inline(always)]
-    pub fn try_as_mplace(self, cx: &impl HasDataLayout) -> Result<MPlaceTy<'tcx, Tag>, ImmTy<'tcx, Tag>> {
+    pub fn try_as_mplace(
+        self,
+        cx: &impl HasDataLayout,
+    ) -> Result<MPlaceTy<'tcx, Tag>, ImmTy<'tcx, Tag>> {
         match *self {
             Operand::Indirect(mplace) => Ok(MPlaceTy { mplace, layout: self.layout }),
-            Operand::Immediate(_) if self.layout.is_zst() => Ok(MPlaceTy::dangling(self.layout, cx)),
+            Operand::Immediate(_) if self.layout.is_zst() => {
+                Ok(MPlaceTy::dangling(self.layout, cx))
+            }
             Operand::Immediate(imm) => Err(ImmTy { imm, layout: self.layout }),
         }
     }