]> git.lizzy.rs Git - rust.git/commitdiff
Second field of ScalarPair can be undef in some cases
authorOliver Schneider <github35764891676564198441@oli-obk.de>
Thu, 2 Aug 2018 11:16:53 +0000 (13:16 +0200)
committerOliver Schneider <github35764891676564198441@oli-obk.de>
Thu, 2 Aug 2018 11:16:53 +0000 (13:16 +0200)
src/librustc/mir/interpret/value.rs
src/librustc_codegen_llvm/mir/operand.rs
src/librustc_mir/hair/pattern/mod.rs
src/librustc_mir/interpret/const_eval.rs
src/librustc_mir/monomorphize/collector.rs
src/test/compile-fail/const-err4.rs

index c9bb48d27568a87fa1195374ba32b9676cbf8fa7..71e3ac48d5bc1dcc5d4e2b5b7515df2602676208 100644 (file)
@@ -18,7 +18,9 @@ pub enum ConstValue<'tcx> {
     /// Used only for types with layout::abi::Scalar ABI and ZSTs
     Scalar(Scalar),
     /// Used only for types with layout::abi::ScalarPair
-    ScalarPair(Scalar, Scalar),
+    ///
+    /// The second field may be undef in case of `Option<usize>::None`
+    ScalarPair(Scalar, ScalarMaybeUndef),
     /// Used only for the remaining cases. An allocation + offset into the allocation
     ByRef(&'tcx Allocation, Size),
 }
@@ -28,10 +30,7 @@ impl<'tcx> ConstValue<'tcx> {
     pub fn from_byval_value(val: Value) -> EvalResult<'static, Self> {
         Ok(match val {
             Value::ByRef(..) => bug!(),
-            Value::ScalarPair(a, b) => ConstValue::ScalarPair(
-                a.unwrap_or_err()?,
-                b.unwrap_or_err()?,
-            ),
+            Value::ScalarPair(a, b) => ConstValue::ScalarPair(a.unwrap_or_err()?, b),
             Value::Scalar(val) => ConstValue::Scalar(val.unwrap_or_err()?),
         })
     }
@@ -41,7 +40,7 @@ pub fn to_byval_value(&self) -> Option<Value> {
         match *self {
             ConstValue::Unevaluated(..) |
             ConstValue::ByRef(..) => None,
-            ConstValue::ScalarPair(a, b) => Some(Value::ScalarPair(a.into(), b.into())),
+            ConstValue::ScalarPair(a, b) => Some(Value::ScalarPair(a.into(), b)),
             ConstValue::Scalar(val) => Some(Value::Scalar(val.into())),
         }
     }
index 1296f5e4b144efd703fce8891ae3c580dbfe7d3e..f8166ee6491472afcb6275a28ca2882193b377f6 100644 (file)
@@ -10,7 +10,7 @@
 
 use rustc::mir::interpret::ConstEvalErr;
 use rustc::mir;
-use rustc::mir::interpret::ConstValue;
+use rustc::mir::interpret::{ConstValue, ScalarMaybeUndef};
 use rustc::ty;
 use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
 use rustc_data_structures::indexed_vec::Idx;
@@ -110,12 +110,16 @@ pub fn from_const(bx: &Builder<'a, 'll, 'tcx>,
                     a_scalar,
                     layout.scalar_pair_element_llvm_type(bx.cx, 0, true),
                 );
-                let b_llval = scalar_to_llvm(
-                    bx.cx,
-                    b,
-                    b_scalar,
-                    layout.scalar_pair_element_llvm_type(bx.cx, 1, true),
-                );
+                let b_layout = layout.scalar_pair_element_llvm_type(bx.cx, 1, true);
+                let b_llval = match b {
+                    ScalarMaybeUndef::Scalar(b) => scalar_to_llvm(
+                        bx.cx,
+                        b,
+                        b_scalar,
+                        b_layout,
+                    ),
+                    ScalarMaybeUndef::Undef => C_undef(b_layout),
+                };
                 OperandValue::Pair(a_llval, b_llval)
             },
             ConstValue::ByRef(alloc, offset) => {
index a60513116b2ebb5fde2c4df2f4e17818d2401f63..d614131c526837623dbcae21965fb572b157206b 100644 (file)
@@ -1102,6 +1102,13 @@ pub fn compare_const_vals<'a, 'tcx>(
                         len_b,
                     ),
                 ) if ptr_a.offset.bytes() == 0 && ptr_b.offset.bytes() == 0 => {
+                    let len_a = len_a.unwrap_or_err().ok();
+                    let len_b = len_b.unwrap_or_err().ok();
+                    if len_a.is_none() || len_b.is_none() {
+                        tcx.sess.struct_err("str slice len is undef").delay_as_bug();
+                    }
+                    let len_a = len_a?;
+                    let len_b = len_b?;
                     if let Ok(len_a) = len_a.to_bits(tcx.data_layout.pointer_size) {
                         if let Ok(len_b) = len_b.to_bits(tcx.data_layout.pointer_size) {
                             if len_a == len_b {
index 121812e8713849987694b161ce98d755d42b8a0b..9d66a0b396b640fe7d3498aa75dc7b9caedb9bc2 100644 (file)
@@ -87,7 +87,7 @@ pub fn value_to_const_value<'tcx>(
     }
     let val = match val {
         Value::Scalar(val) => ConstValue::Scalar(val.unwrap_or_err()?),
-        Value::ScalarPair(a, b) => ConstValue::ScalarPair(a.unwrap_or_err()?, b.unwrap_or_err()?),
+        Value::ScalarPair(a, b) => ConstValue::ScalarPair(a.unwrap_or_err()?, b),
         Value::ByRef(ptr, align) => {
             let ptr = ptr.to_ptr().unwrap();
             let alloc = ecx.memory.get(ptr.alloc_id)?;
index 5f05783b15ccedca6a87c605a8e0facb095297f8..bd90b308fabe80e2ac9fc5263e2bf86d2d7194ca 100644 (file)
 
 use rustc::hir::map as hir_map;
 use rustc::hir::def_id::DefId;
-use rustc::mir::interpret::{AllocId, ConstValue};
+use rustc::mir::interpret::{AllocId, ConstValue, ScalarMaybeUndef};
 use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind};
@@ -1264,11 +1264,11 @@ fn collect_const<'a, 'tcx>(
     };
     match val {
         ConstValue::Unevaluated(..) => bug!("const eval yielded unevaluated const"),
-        ConstValue::ScalarPair(Scalar::Ptr(a), Scalar::Ptr(b)) => {
+        ConstValue::ScalarPair(Scalar::Ptr(a), ScalarMaybeUndef::Scalar(Scalar::Ptr(b))) => {
             collect_miri(tcx, a.alloc_id, output);
             collect_miri(tcx, b.alloc_id, output);
         }
-        ConstValue::ScalarPair(_, Scalar::Ptr(ptr)) |
+        ConstValue::ScalarPair(_, ScalarMaybeUndef::Scalar(Scalar::Ptr(ptr))) |
         ConstValue::ScalarPair(Scalar::Ptr(ptr), _) |
         ConstValue::Scalar(Scalar::Ptr(ptr)) =>
             collect_miri(tcx, ptr.alloc_id, output),
index 09ebf1681c5e04540f1e2114ee38b26af06f68a4..10376d5780908d6ed1f16050b09d2823450f10f8 100644 (file)
@@ -16,7 +16,7 @@ union Foo {
 
 enum Bar {
     Boo = [unsafe { Foo { b: () }.a }; 4][3],
-    //~^ ERROR constant evaluation of enum discriminant resulted in non-integer
+    //~^ ERROR could not evaluate enum discriminant
 }
 
 fn main() {