Skip to content

Commit 4a5c35b

Browse files
committed
Fix an ICE happening due code assuming that MPlaceTy cannot have integer addresses
1 parent 5b770b0 commit 4a5c35b

File tree

2 files changed

+25
-19
lines changed

2 files changed

+25
-19
lines changed

src/librustc_mir/const_eval/eval_queries.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -118,25 +118,11 @@ pub(super) fn op_to_const<'tcx>(
118118
op.try_as_mplace(ecx)
119119
};
120120
let val = match immediate {
121-
Ok(mplace) => {
122-
let ptr = mplace.ptr.assert_ptr();
123-
let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
124-
ConstValue::ByRef { alloc, offset: ptr.offset }
125-
}
121+
Ok(mplace) => mplace.to_const_value(ecx.tcx.tcx),
126122
// see comment on `let try_as_immediate` above
127123
Err(ImmTy { imm: Immediate::Scalar(x), .. }) => match x {
128124
ScalarMaybeUndef::Scalar(s) => ConstValue::Scalar(s),
129-
ScalarMaybeUndef::Undef => {
130-
// When coming out of "normal CTFE", we'll always have an `Indirect` operand as
131-
// argument and we will not need this. The only way we can already have an
132-
// `Immediate` is when we are called from `const_field`, and that `Immediate`
133-
// comes from a constant so it can happen have `Undef`, because the indirect
134-
// memory that was read had undefined bytes.
135-
let mplace = op.assert_mem_place(ecx);
136-
let ptr = mplace.ptr.assert_ptr();
137-
let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
138-
ConstValue::ByRef { alloc, offset: ptr.offset }
139-
}
125+
ScalarMaybeUndef::Undef => op.assert_mem_place(ecx).to_const_value(ecx.tcx.tcx),
140126
},
141127
Err(ImmTy { imm: Immediate::ScalarPair(a, b), .. }) => {
142128
let (data, start) = match a.not_undef().unwrap() {

src/librustc_mir/interpret/place.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ use std::convert::TryFrom;
66
use std::hash::Hash;
77

88
use rustc::mir;
9-
use rustc::mir::interpret::truncate;
9+
use rustc::mir::interpret::{truncate, ConstValue};
1010
use rustc::ty::layout::{
1111
self, Align, HasDataLayout, LayoutOf, PrimitiveExt, Size, TyLayout, VariantIdx,
1212
};
1313
use rustc::ty::TypeFoldable;
1414
use rustc::ty::{self, Ty};
15+
use rustc::ty::{self, Ty, TyCtxt};
1516
use rustc_macros::HashStable;
1617

1718
use super::{
@@ -195,15 +196,34 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> {
195196
_ => bug!("vtable not supported on type {:?}", self.layout.ty),
196197
}
197198
}
199+
200+
#[inline(always)]
201+
pub fn to_const_value(self, tcx: TyCtxt<'tcx>) -> ConstValue<'tcx> {
202+
match self.mplace.ptr {
203+
Scalar::Ptr(ptr) => {
204+
let alloc = tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
205+
ConstValue::ByRef { alloc, offset: ptr.offset }
206+
}
207+
Scalar::Raw { data, .. } => {
208+
assert_eq!(data, self.layout.align.abi.bytes().into());
209+
ConstValue::Scalar(Scalar::zst())
210+
}
211+
}
212+
}
198213
}
199214

200215
// These are defined here because they produce a place.
201216
impl<'tcx, Tag: ::std::fmt::Debug + Copy> OpTy<'tcx, Tag> {
202217
#[inline(always)]
203-
pub fn try_as_mplace(self, cx: &impl HasDataLayout) -> Result<MPlaceTy<'tcx, Tag>, ImmTy<'tcx, Tag>> {
218+
pub fn try_as_mplace(
219+
self,
220+
cx: &impl HasDataLayout,
221+
) -> Result<MPlaceTy<'tcx, Tag>, ImmTy<'tcx, Tag>> {
204222
match *self {
205223
Operand::Indirect(mplace) => Ok(MPlaceTy { mplace, layout: self.layout }),
206-
Operand::Immediate(_) if self.layout.is_zst() => Ok(MPlaceTy::dangling(self.layout, cx)),
224+
Operand::Immediate(_) if self.layout.is_zst() => {
225+
Ok(MPlaceTy::dangling(self.layout, cx))
226+
}
207227
Operand::Immediate(imm) => Err(ImmTy { imm, layout: self.layout }),
208228
}
209229
}

0 commit comments

Comments
 (0)