Second field of ScalarPair can be undef in some cases
This commit is contained in:
parent
c8e30c4295
commit
37e18e7a30
6 changed files with 28 additions and 18 deletions
|
@ -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 @@ impl<'tcx> ConstValue<'tcx> {
|
|||
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())),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 @@ impl OperandRef<'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) => {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -193,7 +193,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor;
|
|||
|
||||
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),
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue