unstably allow constants to refer to statics and read from immutable statics
This commit is contained in:
@@ -51,13 +51,10 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
|
||||
/// The virtual call stack.
|
||||
pub(super) stack: Vec<Frame<'mir, 'tcx>>,
|
||||
|
||||
/// We need to make sure consts never point to anything mutable, even recursively. That is
|
||||
/// relied on for pattern matching on consts with references.
|
||||
/// To achieve this, two pieces have to work together:
|
||||
/// * Interning makes everything outside of statics immutable.
|
||||
/// * Pointers to allocations inside of statics can never leak outside, to a non-static global.
|
||||
/// This boolean here controls the second part.
|
||||
pub(super) can_access_statics: CanAccessStatics,
|
||||
/// Pattern matching on consts with references would be unsound if those references
|
||||
/// could point to anything mutable. Therefore, when evaluating consts and when constructing valtrees,
|
||||
/// we ensure that only immutable global memory can be accessed.
|
||||
pub(super) can_access_mut_global: CanAccessMutGlobal,
|
||||
|
||||
/// Whether to check alignment during evaluation.
|
||||
pub(super) check_alignment: CheckAlignment,
|
||||
@@ -73,12 +70,12 @@ pub enum CheckAlignment {
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub(crate) enum CanAccessStatics {
|
||||
pub(crate) enum CanAccessMutGlobal {
|
||||
No,
|
||||
Yes,
|
||||
}
|
||||
|
||||
impl From<bool> for CanAccessStatics {
|
||||
impl From<bool> for CanAccessMutGlobal {
|
||||
fn from(value: bool) -> Self {
|
||||
if value { Self::Yes } else { Self::No }
|
||||
}
|
||||
@@ -86,13 +83,13 @@ impl From<bool> for CanAccessStatics {
|
||||
|
||||
impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
|
||||
pub(crate) fn new(
|
||||
can_access_statics: CanAccessStatics,
|
||||
can_access_mut_global: CanAccessMutGlobal,
|
||||
check_alignment: CheckAlignment,
|
||||
) -> Self {
|
||||
CompileTimeInterpreter {
|
||||
num_evaluated_steps: 0,
|
||||
stack: Vec::new(),
|
||||
can_access_statics,
|
||||
can_access_mut_global,
|
||||
check_alignment,
|
||||
}
|
||||
}
|
||||
@@ -680,7 +677,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||
machine: &Self,
|
||||
alloc_id: AllocId,
|
||||
alloc: ConstAllocation<'tcx>,
|
||||
static_def_id: Option<DefId>,
|
||||
_static_def_id: Option<DefId>,
|
||||
is_write: bool,
|
||||
) -> InterpResult<'tcx> {
|
||||
let alloc = alloc.inner();
|
||||
@@ -692,22 +689,15 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||
}
|
||||
} else {
|
||||
// Read access. These are usually allowed, with some exceptions.
|
||||
if machine.can_access_statics == CanAccessStatics::Yes {
|
||||
if machine.can_access_mut_global == CanAccessMutGlobal::Yes {
|
||||
// Machine configuration allows us read from anything (e.g., `static` initializer).
|
||||
Ok(())
|
||||
} else if static_def_id.is_some() {
|
||||
// Machine configuration does not allow us to read statics
|
||||
// (e.g., `const` initializer).
|
||||
// See const_eval::machine::MemoryExtra::can_access_statics for why
|
||||
// this check is so important: if we could read statics, we could read pointers
|
||||
// to mutable allocations *inside* statics. These allocations are not themselves
|
||||
// statics, so pointers to them can get around the check in `validity.rs`.
|
||||
Err(ConstEvalErrKind::ConstAccessesStatic.into())
|
||||
} else if alloc.mutability == Mutability::Mut {
|
||||
// Machine configuration does not allow us to read statics (e.g., `const`
|
||||
// initializer).
|
||||
Err(ConstEvalErrKind::ConstAccessesMutGlobal.into())
|
||||
} else {
|
||||
// Immutable global, this read is fine.
|
||||
// But make sure we never accept a read from something mutable, that would be
|
||||
// unsound. The reason is that as the content of this allocation may be different
|
||||
// now and at run-time, so if we permit reading now we might return the wrong value.
|
||||
assert_eq!(alloc.mutability, Mutability::Not);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user