Skip to content

Commit 37e18e7

Browse files
committed
Second field of ScalarPair can be undef in some cases
1 parent c8e30c4 commit 37e18e7

File tree

6 files changed

+28
-18
lines changed

6 files changed

+28
-18
lines changed

src/librustc/mir/interpret/value.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ pub enum ConstValue<'tcx> {
1818
/// Used only for types with layout::abi::Scalar ABI and ZSTs
1919
Scalar(Scalar),
2020
/// Used only for types with layout::abi::ScalarPair
21-
ScalarPair(Scalar, Scalar),
21+
///
22+
/// The second field may be undef in case of `Option<usize>::None`
23+
ScalarPair(Scalar, ScalarMaybeUndef),
2224
/// Used only for the remaining cases. An allocation + offset into the allocation
2325
ByRef(&'tcx Allocation, Size),
2426
}
@@ -28,10 +30,7 @@ impl<'tcx> ConstValue<'tcx> {
2830
pub fn from_byval_value(val: Value) -> EvalResult<'static, Self> {
2931
Ok(match val {
3032
Value::ByRef(..) => bug!(),
31-
Value::ScalarPair(a, b) => ConstValue::ScalarPair(
32-
a.unwrap_or_err()?,
33-
b.unwrap_or_err()?,
34-
),
33+
Value::ScalarPair(a, b) => ConstValue::ScalarPair(a.unwrap_or_err()?, b),
3534
Value::Scalar(val) => ConstValue::Scalar(val.unwrap_or_err()?),
3635
})
3736
}
@@ -41,7 +40,7 @@ impl<'tcx> ConstValue<'tcx> {
4140
match *self {
4241
ConstValue::Unevaluated(..) |
4342
ConstValue::ByRef(..) => None,
44-
ConstValue::ScalarPair(a, b) => Some(Value::ScalarPair(a.into(), b.into())),
43+
ConstValue::ScalarPair(a, b) => Some(Value::ScalarPair(a.into(), b)),
4544
ConstValue::Scalar(val) => Some(Value::Scalar(val.into())),
4645
}
4746
}

src/librustc_codegen_llvm/mir/operand.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use rustc::mir::interpret::ConstEvalErr;
1212
use rustc::mir;
13-
use rustc::mir::interpret::ConstValue;
13+
use rustc::mir::interpret::{ConstValue, ScalarMaybeUndef};
1414
use rustc::ty;
1515
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
1616
use rustc_data_structures::indexed_vec::Idx;
@@ -110,12 +110,16 @@ impl OperandRef<'ll, 'tcx> {
110110
a_scalar,
111111
layout.scalar_pair_element_llvm_type(bx.cx, 0, true),
112112
);
113-
let b_llval = scalar_to_llvm(
114-
bx.cx,
115-
b,
116-
b_scalar,
117-
layout.scalar_pair_element_llvm_type(bx.cx, 1, true),
118-
);
113+
let b_layout = layout.scalar_pair_element_llvm_type(bx.cx, 1, true);
114+
let b_llval = match b {
115+
ScalarMaybeUndef::Scalar(b) => scalar_to_llvm(
116+
bx.cx,
117+
b,
118+
b_scalar,
119+
b_layout,
120+
),
121+
ScalarMaybeUndef::Undef => C_undef(b_layout),
122+
};
119123
OperandValue::Pair(a_llval, b_llval)
120124
},
121125
ConstValue::ByRef(alloc, offset) => {

src/librustc_mir/hair/pattern/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,13 @@ pub fn compare_const_vals<'a, 'tcx>(
11021102
len_b,
11031103
),
11041104
) if ptr_a.offset.bytes() == 0 && ptr_b.offset.bytes() == 0 => {
1105+
let len_a = len_a.unwrap_or_err().ok();
1106+
let len_b = len_b.unwrap_or_err().ok();
1107+
if len_a.is_none() || len_b.is_none() {
1108+
tcx.sess.struct_err("str slice len is undef").delay_as_bug();
1109+
}
1110+
let len_a = len_a?;
1111+
let len_b = len_b?;
11051112
if let Ok(len_a) = len_a.to_bits(tcx.data_layout.pointer_size) {
11061113
if let Ok(len_b) = len_b.to_bits(tcx.data_layout.pointer_size) {
11071114
if len_a == len_b {

src/librustc_mir/interpret/const_eval.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub fn value_to_const_value<'tcx>(
8787
}
8888
let val = match val {
8989
Value::Scalar(val) => ConstValue::Scalar(val.unwrap_or_err()?),
90-
Value::ScalarPair(a, b) => ConstValue::ScalarPair(a.unwrap_or_err()?, b.unwrap_or_err()?),
90+
Value::ScalarPair(a, b) => ConstValue::ScalarPair(a.unwrap_or_err()?, b),
9191
Value::ByRef(ptr, align) => {
9292
let ptr = ptr.to_ptr().unwrap();
9393
let alloc = ecx.memory.get(ptr.alloc_id)?;

src/librustc_mir/monomorphize/collector.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor;
193193

194194
use rustc::hir::map as hir_map;
195195
use rustc::hir::def_id::DefId;
196-
use rustc::mir::interpret::{AllocId, ConstValue};
196+
use rustc::mir::interpret::{AllocId, ConstValue, ScalarMaybeUndef};
197197
use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
198198
use rustc::ty::subst::Substs;
199199
use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind};
@@ -1264,11 +1264,11 @@ fn collect_const<'a, 'tcx>(
12641264
};
12651265
match val {
12661266
ConstValue::Unevaluated(..) => bug!("const eval yielded unevaluated const"),
1267-
ConstValue::ScalarPair(Scalar::Ptr(a), Scalar::Ptr(b)) => {
1267+
ConstValue::ScalarPair(Scalar::Ptr(a), ScalarMaybeUndef::Scalar(Scalar::Ptr(b))) => {
12681268
collect_miri(tcx, a.alloc_id, output);
12691269
collect_miri(tcx, b.alloc_id, output);
12701270
}
1271-
ConstValue::ScalarPair(_, Scalar::Ptr(ptr)) |
1271+
ConstValue::ScalarPair(_, ScalarMaybeUndef::Scalar(Scalar::Ptr(ptr))) |
12721272
ConstValue::ScalarPair(Scalar::Ptr(ptr), _) |
12731273
ConstValue::Scalar(Scalar::Ptr(ptr)) =>
12741274
collect_miri(tcx, ptr.alloc_id, output),

src/test/compile-fail/const-err4.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ union Foo {
1616

1717
enum Bar {
1818
Boo = [unsafe { Foo { b: () }.a }; 4][3],
19-
//~^ ERROR constant evaluation of enum discriminant resulted in non-integer
19+
//~^ ERROR could not evaluate enum discriminant
2020
}
2121

2222
fn main() {

0 commit comments

Comments
 (0)