Skip to content
Permalink
Browse files

Fix an ICE happening due code assuming that `MPlaceTy` cannot have in…

…teger addresses
  • Loading branch information
oli-obk committed Dec 21, 2019
1 parent 5b770b0 commit 4a5c35bc4490ecf5b06d311917ac64be63673d3c
Showing with 25 additions and 19 deletions.
  1. +2 −16 src/librustc_mir/const_eval/eval_queries.rs
  2. +23 −3 src/librustc_mir/interpret/place.rs
@@ -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 }),
}
}

0 comments on commit 4a5c35b

Please sign in to comment.
You can’t perform that action at this time.