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:
parent
69a63737fa
commit
70b6a74c3c
5 changed files with 36 additions and 15 deletions
|
@ -14,7 +14,7 @@ use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
use rustc_target::abi::{self, Abi};
|
use rustc_target::abi::{self, Abi};
|
||||||
|
|
||||||
use super::{CompileTimeEvalContext, CompileTimeInterpreter};
|
use super::{CanAccessStatics, CompileTimeEvalContext, CompileTimeInterpreter};
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
use crate::interpret::eval_nullary_intrinsic;
|
use crate::interpret::eval_nullary_intrinsic;
|
||||||
use crate::interpret::{
|
use crate::interpret::{
|
||||||
|
@ -93,7 +93,7 @@ pub(super) fn mk_eval_cx<'mir, 'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
root_span: Span,
|
root_span: Span,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
can_access_statics: bool,
|
can_access_statics: CanAccessStatics,
|
||||||
) -> CompileTimeEvalContext<'mir, 'tcx> {
|
) -> CompileTimeEvalContext<'mir, 'tcx> {
|
||||||
debug!("mk_eval_cx: {:?}", param_env);
|
debug!("mk_eval_cx: {:?}", param_env);
|
||||||
InterpCx::new(
|
InterpCx::new(
|
||||||
|
@ -207,7 +207,7 @@ pub(crate) fn turn_into_const_value<'tcx>(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.def_span(key.value.instance.def_id()),
|
tcx.def_span(key.value.instance.def_id()),
|
||||||
key.param_env,
|
key.param_env,
|
||||||
/*can_access_statics:*/ is_static,
|
CanAccessStatics::from(is_static),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mplace = ecx.raw_const_to_mplace(constant).expect(
|
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
|
// 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.
|
// they do not have to behave "as if" they were evaluated at runtime.
|
||||||
CompileTimeInterpreter::new(
|
CompileTimeInterpreter::new(
|
||||||
/*can_access_statics:*/ is_static,
|
CanAccessStatics::from(is_static),
|
||||||
if tcx.sess.opts.unstable_opts.extra_const_ub_checks {
|
if tcx.sess.opts.unstable_opts.extra_const_ub_checks {
|
||||||
CheckAlignment::Error
|
CheckAlignment::Error
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -57,7 +57,7 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
|
||||||
/// * Interning makes everything outside of statics immutable.
|
/// * Interning makes everything outside of statics immutable.
|
||||||
/// * Pointers to allocations inside of statics can never leak outside, to a non-static global.
|
/// * Pointers to allocations inside of statics can never leak outside, to a non-static global.
|
||||||
/// This boolean here controls the second part.
|
/// 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.
|
/// Whether to check alignment during evaluation.
|
||||||
pub(super) check_alignment: CheckAlignment,
|
pub(super) check_alignment: CheckAlignment,
|
||||||
|
@ -83,8 +83,23 @@ impl CheckAlignment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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> {
|
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 {
|
CompileTimeInterpreter {
|
||||||
num_evaluated_steps: 0,
|
num_evaluated_steps: 0,
|
||||||
stack: Vec::new(),
|
stack: Vec::new(),
|
||||||
|
@ -699,7 +714,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Read access. These are usually allowed, with some exceptions.
|
// 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).
|
// Machine configuration allows us read from anything (e.g., `static` initializer).
|
||||||
Ok(())
|
Ok(())
|
||||||
} else if static_def_id.is_some() {
|
} else if static_def_id.is_some() {
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub(crate) fn const_caller_location(
|
||||||
(file, line, col): (Symbol, u32, u32),
|
(file, line, col): (Symbol, u32, u32),
|
||||||
) -> ConstValue<'_> {
|
) -> ConstValue<'_> {
|
||||||
trace!("const_caller_location: {}:{}:{}", file, line, col);
|
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);
|
let loc_place = ecx.alloc_caller_location(file, line, col);
|
||||||
if intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &loc_place).is_err() {
|
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`
|
// FIXME Need to provide a span to `eval_to_valtree`
|
||||||
let ecx = mk_eval_cx(
|
let ecx = mk_eval_cx(
|
||||||
tcx, DUMMY_SP, param_env,
|
tcx,
|
||||||
|
DUMMY_SP,
|
||||||
|
param_env,
|
||||||
// It is absolutely crucial for soundness that
|
// It is absolutely crucial for soundness that
|
||||||
// we do not read from static items or other mutable memory.
|
// we do not read from static items or other mutable memory.
|
||||||
false,
|
CanAccessStatics::No,
|
||||||
);
|
);
|
||||||
let place = ecx.raw_const_to_mplace(const_alloc).unwrap();
|
let place = ecx.raw_const_to_mplace(const_alloc).unwrap();
|
||||||
debug!(?place);
|
debug!(?place);
|
||||||
|
@ -91,7 +93,7 @@ pub(crate) fn try_destructure_mir_constant<'tcx>(
|
||||||
val: mir::ConstantKind<'tcx>,
|
val: mir::ConstantKind<'tcx>,
|
||||||
) -> InterpResult<'tcx, mir::DestructuredConstant<'tcx>> {
|
) -> InterpResult<'tcx, mir::DestructuredConstant<'tcx>> {
|
||||||
trace!("destructure_mir_constant: {:?}", val);
|
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)?;
|
let op = ecx.eval_mir_constant(&val, None, None)?;
|
||||||
|
|
||||||
// We go to `usize` as we cannot allocate anything bigger anyway.
|
// We go to `usize` as we cannot allocate anything bigger anyway.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use super::eval_queries::{mk_eval_cx, op_to_const};
|
use super::eval_queries::{mk_eval_cx, op_to_const};
|
||||||
use super::machine::CompileTimeEvalContext;
|
use super::machine::CompileTimeEvalContext;
|
||||||
use super::{ValTreeCreationError, ValTreeCreationResult, VALTREE_MAX_NODES};
|
use super::{ValTreeCreationError, ValTreeCreationResult, VALTREE_MAX_NODES};
|
||||||
|
use crate::const_eval::CanAccessStatics;
|
||||||
use crate::interpret::{
|
use crate::interpret::{
|
||||||
intern_const_alloc_recursive, ConstValue, ImmTy, Immediate, InternKind, MemPlaceMeta,
|
intern_const_alloc_recursive, ConstValue, ImmTy, Immediate, InternKind, MemPlaceMeta,
|
||||||
MemoryKind, PlaceTy, Scalar,
|
MemoryKind, PlaceTy, Scalar,
|
||||||
|
@ -263,7 +264,11 @@ pub fn valtree_to_const_value<'tcx>(
|
||||||
// FIXME Does this need an example?
|
// FIXME Does this need an example?
|
||||||
|
|
||||||
let (param_env, ty) = param_env_ty.into_parts();
|
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() {
|
match ty.kind() {
|
||||||
ty::FnDef(..) => {
|
ty::FnDef(..) => {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use rustc_middle::ty::layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout, Val
|
||||||
use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Ty, TyCtxt};
|
use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Ty, TyCtxt};
|
||||||
use rustc_target::abi::{Abi, FieldsShape, Scalar, Variants};
|
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};
|
use crate::interpret::{InterpCx, MemoryKind, OpTy};
|
||||||
|
|
||||||
/// Determines if this type permits "raw" initialization by just transmuting some memory into an
|
/// 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>,
|
tcx: TyCtxt<'tcx>,
|
||||||
kind: ValidityRequirement,
|
kind: ValidityRequirement,
|
||||||
) -> Result<bool, LayoutError<'tcx>> {
|
) -> Result<bool, LayoutError<'tcx>> {
|
||||||
let machine =
|
let machine = CompileTimeInterpreter::new(CanAccessStatics::No, CheckAlignment::Error);
|
||||||
CompileTimeInterpreter::new(/*can_access_statics:*/ false, CheckAlignment::Error);
|
|
||||||
|
|
||||||
let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);
|
let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue