Don't ICE in subslice pattern const-eval

This commit is contained in:
Matthew Jasper 2019-12-20 23:11:41 +00:00
parent 12307b3b08
commit d490c34086
2 changed files with 25 additions and 4 deletions

View File

@ -444,13 +444,27 @@ pub fn operand_projection(
Field(field, _) => self.operand_field(base, field.index() as u64)?,
Downcast(_, variant) => self.operand_downcast(base, variant)?,
Deref => self.deref_operand(base)?.into(),
Subslice { .. } | ConstantIndex { .. } | Index(_) => if base.layout.is_zst() {
ConstantIndex { .. } | Index(_) if base.layout.is_zst() => {
OpTy {
op: Operand::Immediate(Scalar::zst().into()),
// the actual index doesn't matter, so we just pick a convenient one like 0
layout: base.layout.field(self, 0)?,
}
} else {
}
Subslice { from, to, from_end } if base.layout.is_zst() => {
let elem_ty = if let ty::Array(elem_ty, _) = base.layout.ty.kind {
elem_ty
} else {
bug!("slices shouldn't be zero-sized");
};
assert!(!from_end, "arrays shouldn't be subsliced from the end");
OpTy {
op: Operand::Immediate(Scalar::zst().into()),
layout: self.layout_of(self.tcx.mk_array(elem_ty, (to - from) as u64))?,
}
}
Subslice { .. } | ConstantIndex { .. } | Index(_) => {
// The rest should only occur as mplace, we do not use Immediates for types
// allowing such operations. This matches place_projection forcing an allocation.
let mplace = base.assert_mem_place();

View File

@ -455,7 +455,10 @@ pub fn mplace_subslice(
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
let len = base.len(self)?; // also asserts that we have a type where this makes sense
let actual_to = if from_end {
assert!(from <= len - to);
if from + to > len {
// This can only be reached in ConstProp and non-rustc-MIR.
throw_ub!(BoundsCheckFailed { len: len as u64, index: from as u64 + to as u64 });
}
len - to
} else {
to
@ -523,7 +526,11 @@ pub fn mplace_projection(
from_end,
} => {
let n = base.len(self)?;
assert!(n >= min_length as u64);
if n < min_length as u64 {
// This can only be reached in ConstProp and non-rustc-MIR.
throw_ub!(BoundsCheckFailed { len: min_length as u64, index: n as u64 });
}
assert!(offset < min_length);
let index = if from_end {
n - u64::from(offset)