Add enum for can_access_statics boolean

`/*can_access_statics:*/ false` is one of the ways to do this, but not
the one I like.
This commit is contained in:
Nilstrieb 2023-06-24 20:40:40 +00:00
parent 69a63737fa
commit 70b6a74c3c
5 changed files with 36 additions and 15 deletions

View File

@ -14,7 +14,7 @@
use rustc_span::source_map::Span;
use rustc_target::abi::{self, Abi};
use super::{CompileTimeEvalContext, CompileTimeInterpreter};
use super::{CanAccessStatics, CompileTimeEvalContext, CompileTimeInterpreter};
use crate::errors;
use crate::interpret::eval_nullary_intrinsic;
use crate::interpret::{
@ -93,7 +93,7 @@ pub(super) fn mk_eval_cx<'mir, 'tcx>(
tcx: TyCtxt<'tcx>,
root_span: Span,
param_env: ty::ParamEnv<'tcx>,
can_access_statics: bool,
can_access_statics: CanAccessStatics,
) -> CompileTimeEvalContext<'mir, 'tcx> {
debug!("mk_eval_cx: {:?}", param_env);
InterpCx::new(
@ -207,7 +207,7 @@ pub(crate) fn turn_into_const_value<'tcx>(
tcx,
tcx.def_span(key.value.instance.def_id()),
key.param_env,
/*can_access_statics:*/ is_static,
CanAccessStatics::from(is_static),
);
let mplace = ecx.raw_const_to_mplace(constant).expect(
@ -309,7 +309,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
// Statics (and promoteds inside statics) may access other statics, because unlike consts
// they do not have to behave "as if" they were evaluated at runtime.
CompileTimeInterpreter::new(
/*can_access_statics:*/ is_static,
CanAccessStatics::from(is_static),
if tcx.sess.opts.unstable_opts.extra_const_ub_checks {
CheckAlignment::Error
} else {

View File

@ -57,7 +57,7 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
/// * 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: bool,
pub(super) can_access_statics: CanAccessStatics,
/// Whether to check alignment during evaluation.
pub(super) check_alignment: CheckAlignment,
@ -83,8 +83,23 @@ pub fn should_check(&self) -> bool {
}
}
#[derive(Copy, Clone, PartialEq)]
pub(crate) enum CanAccessStatics {
No,
Yes,
}
impl From<bool> for CanAccessStatics {
fn from(value: bool) -> Self {
if value { Self::Yes } else { Self::No }
}
}
impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
pub(crate) fn new(can_access_statics: bool, check_alignment: CheckAlignment) -> Self {
pub(crate) fn new(
can_access_statics: CanAccessStatics,
check_alignment: CheckAlignment,
) -> Self {
CompileTimeInterpreter {
num_evaluated_steps: 0,
stack: Vec::new(),
@ -699,7 +714,7 @@ fn before_access_global(
}
} else {
// Read access. These are usually allowed, with some exceptions.
if machine.can_access_statics {
if machine.can_access_statics == CanAccessStatics::Yes {
// Machine configuration allows us read from anything (e.g., `static` initializer).
Ok(())
} else if static_def_id.is_some() {

View File

@ -26,7 +26,7 @@ pub(crate) fn const_caller_location(
(file, line, col): (Symbol, u32, u32),
) -> ConstValue<'_> {
trace!("const_caller_location: {}:{}:{}", file, line, col);
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, ty::ParamEnv::reveal_all(), false);
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, ty::ParamEnv::reveal_all(), CanAccessStatics::No);
let loc_place = ecx.alloc_caller_location(file, line, col);
if intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &loc_place).is_err() {
@ -55,10 +55,12 @@ pub(crate) fn eval_to_valtree<'tcx>(
// FIXME Need to provide a span to `eval_to_valtree`
let ecx = mk_eval_cx(
tcx, DUMMY_SP, param_env,
tcx,
DUMMY_SP,
param_env,
// It is absolutely crucial for soundness that
// we do not read from static items or other mutable memory.
false,
CanAccessStatics::No,
);
let place = ecx.raw_const_to_mplace(const_alloc).unwrap();
debug!(?place);
@ -91,7 +93,7 @@ pub(crate) fn try_destructure_mir_constant<'tcx>(
val: mir::ConstantKind<'tcx>,
) -> InterpResult<'tcx, mir::DestructuredConstant<'tcx>> {
trace!("destructure_mir_constant: {:?}", val);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No);
let op = ecx.eval_mir_constant(&val, None, None)?;
// We go to `usize` as we cannot allocate anything bigger anyway.

View File

@ -1,6 +1,7 @@
use super::eval_queries::{mk_eval_cx, op_to_const};
use super::machine::CompileTimeEvalContext;
use super::{ValTreeCreationError, ValTreeCreationResult, VALTREE_MAX_NODES};
use crate::const_eval::CanAccessStatics;
use crate::interpret::{
intern_const_alloc_recursive, ConstValue, ImmTy, Immediate, InternKind, MemPlaceMeta,
MemoryKind, PlaceTy, Scalar,
@ -263,7 +264,11 @@ pub fn valtree_to_const_value<'tcx>(
// FIXME Does this need an example?
let (param_env, ty) = param_env_ty.into_parts();
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
let mut ecx: crate::interpret::InterpCx<
'_,
'_,
crate::const_eval::CompileTimeInterpreter<'_, '_>,
> = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No);
match ty.kind() {
ty::FnDef(..) => {

View File

@ -2,7 +2,7 @@
use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Ty, TyCtxt};
use rustc_target::abi::{Abi, FieldsShape, Scalar, Variants};
use crate::const_eval::{CheckAlignment, CompileTimeInterpreter};
use crate::const_eval::{CanAccessStatics, CheckAlignment, CompileTimeInterpreter};
use crate::interpret::{InterpCx, MemoryKind, OpTy};
/// Determines if this type permits "raw" initialization by just transmuting some memory into an
@ -44,8 +44,7 @@ fn might_permit_raw_init_strict<'tcx>(
tcx: TyCtxt<'tcx>,
kind: ValidityRequirement,
) -> Result<bool, LayoutError<'tcx>> {
let machine =
CompileTimeInterpreter::new(/*can_access_statics:*/ false, CheckAlignment::Error);
let machine = CompileTimeInterpreter::new(CanAccessStatics::No, CheckAlignment::Error);
let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);