fix const_prop ICE

This commit is contained in:
Ralf Jung 2020-03-22 09:23:19 +01:00
parent 58a56cc8c0
commit 7a73b879cb
5 changed files with 15 additions and 8 deletions

View File

@ -34,11 +34,9 @@ impl fmt::Display for ConstEvalErrKind {
write!(f, "\"{}\" needs an rfc before being allowed inside constants", msg)
}
ConstAccessesStatic => write!(f, "constant accesses static"),
ModifiedGlobal => write!(
f,
"modifying a static's initial value from another static's \
initializer"
),
ModifiedGlobal => {
write!(f, "modifying a static's initial value from another static's initializer")
}
AssertFailure(ref msg) => write!(f, "{:?}", msg),
Panic { msg, line, col, file } => {
write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col)

View File

@ -358,6 +358,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
} else if is_write {
Err(ConstEvalErrKind::ModifiedGlobal.into())
} else if memory_extra.can_access_statics || def_id.is_none() {
// `def_id.is_none()` indicates this is not a static, but a const or so.
Ok(())
} else {
Err(ConstEvalErrKind::ConstAccessesStatic.into())

View File

@ -209,6 +209,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
}
/// Called before a global allocation is accessed.
/// `def_id` is `Some` if this is the "lazy" allocation of a static.
#[inline]
fn before_access_global(
_memory_extra: &Self::MemoryExtra,

View File

@ -416,7 +416,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
) -> InterpResult<'tcx, Cow<'tcx, Allocation<M::PointerTag, M::AllocExtra>>> {
let alloc = tcx.alloc_map.lock().get(id);
let (alloc, def_id) = match alloc {
Some(GlobalAlloc::Memory(mem)) => (mem, None),
Some(GlobalAlloc::Memory(mem)) => {
// Memory of a constant or promoted or anonymous memory referenced by a static.
(mem, None)
}
Some(GlobalAlloc::Function(..)) => throw_ub!(DerefFunctionPointer(id)),
None => throw_ub!(PointerUseAfterFree(id)),
Some(GlobalAlloc::Static(def_id)) => {

View File

@ -274,7 +274,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
_memory_extra: &(),
_alloc_id: AllocId,
allocation: &Allocation<Self::PointerTag, Self::AllocExtra>,
_def_id: Option<DefId>,
def_id: Option<DefId>,
is_write: bool,
) -> InterpResult<'tcx> {
if is_write {
@ -282,7 +282,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
}
// If the static allocation is mutable or if it has relocations (it may be legal to mutate
// the memory behind that in the future), then we can't const prop it.
if allocation.mutability == Mutability::Mut || allocation.relocations().len() > 0 {
// FIXME: we only check statics here (that have a `DefId`), not other mutable allocations.
// Why that?
if def_id.is_some()
&& (allocation.mutability == Mutability::Mut || allocation.relocations().len() > 0)
{
throw_machine_stop_str!("can't eval mutable statics in ConstProp");
}