Fix an ICE happening due code assuming that MPlaceTy cannot have integer addresses
This commit is contained in:
parent
5b770b080f
commit
4a5c35bc44
2 changed files with 25 additions and 19 deletions
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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 }),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue