Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add enum for can_access_statics boolean #113011

Merged
merged 1 commit into from
Jun 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions compiler/rustc_const_eval/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_middle::ty::{self, TyCtxt};
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::{
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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 {
Expand Down
21 changes: 18 additions & 3 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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> {
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(),
Expand Down Expand Up @@ -699,7 +714,7 @@ 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 {
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() {
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_const_eval/src/const_eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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.
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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(..) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use rustc_middle::ty::layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout, Val
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
Expand Down Expand Up @@ -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);

Expand Down