Skip to content

Commit 5549ffd

Browse files
committed
Prepare const eval machine for supporting a "no static accesses at all" mode.
1 parent be68ad3 commit 5549ffd

File tree

5 files changed

+47
-33
lines changed

5 files changed

+47
-33
lines changed

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_span::def_id::LocalDefId;
1717
use rustc_span::{Span, DUMMY_SP};
1818
use rustc_target::abi::{self, Abi};
1919

20-
use super::{CanAccessMutGlobal, CompileTimeInterpCx, CompileTimeMachine};
20+
use super::{CompileTimeInterpCx, CompileTimeMachine, GlobalAccessPermissions};
2121
use crate::const_eval::CheckAlignment;
2222
use crate::errors::ConstEvalError;
2323
use crate::errors::{self, DanglingPtrInFinal};
@@ -138,7 +138,7 @@ pub(crate) fn mk_eval_cx_to_read_const_val<'tcx>(
138138
tcx: TyCtxt<'tcx>,
139139
root_span: Span,
140140
param_env: ty::ParamEnv<'tcx>,
141-
can_access_mut_global: CanAccessMutGlobal,
141+
can_access_mut_global: GlobalAccessPermissions,
142142
) -> CompileTimeInterpCx<'tcx> {
143143
debug!("mk_eval_cx: {:?}", param_env);
144144
InterpCx::new(
@@ -157,7 +157,8 @@ pub fn mk_eval_cx_for_const_val<'tcx>(
157157
val: mir::ConstValue<'tcx>,
158158
ty: Ty<'tcx>,
159159
) -> Option<(CompileTimeInterpCx<'tcx>, OpTy<'tcx>)> {
160-
let ecx = mk_eval_cx_to_read_const_val(tcx.tcx, tcx.span, param_env, CanAccessMutGlobal::No);
160+
let ecx =
161+
mk_eval_cx_to_read_const_val(tcx.tcx, tcx.span, param_env, GlobalAccessPermissions::Static);
161162
let op = ecx.const_val_to_op(val, ty, None).ok()?;
162163
Some((ecx, op))
163164
}
@@ -261,7 +262,7 @@ pub(crate) fn turn_into_const_value<'tcx>(
261262
tcx,
262263
tcx.def_span(key.value.instance.def_id()),
263264
key.param_env,
264-
CanAccessMutGlobal::from(is_static),
265+
GlobalAccessPermissions::from(is_static),
265266
);
266267

267268
let mplace = ecx.raw_const_to_mplace(constant).expect(
@@ -383,7 +384,7 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
383384
// they do not have to behave "as if" they were evaluated at runtime.
384385
// For consts however we want to ensure they behave "as if" they were evaluated at runtime,
385386
// so we have to reject reading mutable global memory.
386-
CompileTimeMachine::new(CanAccessMutGlobal::from(is_static), CheckAlignment::Error),
387+
CompileTimeMachine::new(GlobalAccessPermissions::from(is_static), CheckAlignment::Error),
387388
);
388389
let res = ecx.load_mir(cid.instance.def, cid.promoted);
389390
res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, body)).map_err(|error| {

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub struct CompileTimeMachine<'tcx> {
5858
/// Pattern matching on consts with references would be unsound if those references
5959
/// could point to anything mutable. Therefore, when evaluating consts and when constructing valtrees,
6060
/// we ensure that only immutable global memory can be accessed.
61-
pub(super) can_access_mut_global: CanAccessMutGlobal,
61+
pub(super) global_access_permissions: GlobalAccessPermissions,
6262

6363
/// Whether to check alignment during evaluation.
6464
pub(super) check_alignment: CheckAlignment,
@@ -79,26 +79,28 @@ pub enum CheckAlignment {
7979
}
8080

8181
#[derive(Copy, Clone, PartialEq)]
82-
pub(crate) enum CanAccessMutGlobal {
83-
No,
84-
Yes,
82+
pub(crate) enum GlobalAccessPermissions {
83+
/// Allowed to read from immutable statics
84+
Static,
85+
/// Allowed to read from mutable statics
86+
StaticMut,
8587
}
8688

87-
impl From<bool> for CanAccessMutGlobal {
89+
impl From<bool> for GlobalAccessPermissions {
8890
fn from(value: bool) -> Self {
89-
if value { Self::Yes } else { Self::No }
91+
if value { Self::StaticMut } else { Self::Static }
9092
}
9193
}
9294

9395
impl<'tcx> CompileTimeMachine<'tcx> {
9496
pub(crate) fn new(
95-
can_access_mut_global: CanAccessMutGlobal,
97+
global_access_permissions: GlobalAccessPermissions,
9698
check_alignment: CheckAlignment,
9799
) -> Self {
98100
CompileTimeMachine {
99101
num_evaluated_steps: 0,
100102
stack: Vec::new(),
101-
can_access_mut_global,
103+
global_access_permissions,
102104
check_alignment,
103105
static_root_ids: None,
104106
}
@@ -696,17 +698,18 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
696698
}
697699
} else {
698700
// Read access. These are usually allowed, with some exceptions.
699-
if machine.can_access_mut_global == CanAccessMutGlobal::Yes {
701+
match machine.global_access_permissions {
700702
// Machine configuration allows us read from anything (e.g., `static` initializer).
701-
Ok(())
702-
} else if alloc.mutability == Mutability::Mut {
703-
// Machine configuration does not allow us to read statics (e.g., `const`
704-
// initializer).
705-
Err(ConstEvalErrKind::ConstAccessesMutGlobal.into())
706-
} else {
707-
// Immutable global, this read is fine.
708-
assert_eq!(alloc.mutability, Mutability::Not);
709-
Ok(())
703+
GlobalAccessPermissions::StaticMut => Ok(()),
704+
GlobalAccessPermissions::Static => match alloc.mutability {
705+
Mutability::Mut => {
706+
// Machine configuration does not allow us to read statics (e.g., `const`
707+
// initializer).
708+
Err(ConstEvalErrKind::ConstAccessesMutGlobal.into())
709+
}
710+
// Immutable global, this read is fine.
711+
Mutability::Not => Ok(()),
712+
},
710713
}
711714
}
712715
}

compiler/rustc_const_eval/src/const_eval/valtrees.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use tracing::{debug, instrument, trace};
1111
use super::eval_queries::{mk_eval_cx_to_read_const_val, op_to_const};
1212
use super::machine::CompileTimeInterpCx;
1313
use super::{ValTreeCreationError, ValTreeCreationResult, VALTREE_MAX_NODES};
14-
use crate::const_eval::CanAccessMutGlobal;
14+
use crate::const_eval::GlobalAccessPermissions;
1515
use crate::errors::MaxNumNodesInConstErr;
1616
use crate::interpret::MPlaceTy;
1717
use crate::interpret::{
@@ -242,7 +242,7 @@ pub(crate) fn eval_to_valtree<'tcx>(
242242
param_env,
243243
// It is absolutely crucial for soundness that
244244
// we do not read from mutable memory.
245-
CanAccessMutGlobal::No,
245+
GlobalAccessPermissions::Static,
246246
);
247247
let place = ecx.raw_const_to_mplace(const_alloc).unwrap();
248248
debug!(?place);
@@ -301,8 +301,12 @@ pub fn valtree_to_const_value<'tcx>(
301301
}
302302
ty::Pat(ty, _) => valtree_to_const_value(tcx, param_env.and(ty), valtree),
303303
ty::Ref(_, inner_ty, _) => {
304-
let mut ecx =
305-
mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, param_env, CanAccessMutGlobal::No);
304+
let mut ecx = mk_eval_cx_to_read_const_val(
305+
tcx,
306+
DUMMY_SP,
307+
param_env,
308+
GlobalAccessPermissions::Static,
309+
);
306310
let imm = valtree_to_ref(&mut ecx, valtree, inner_ty);
307311
let imm = ImmTy::from_immediate(imm, tcx.layout_of(param_env_ty).unwrap());
308312
op_to_const(&ecx, &imm.into(), /* for diagnostics */ false)
@@ -329,8 +333,12 @@ pub fn valtree_to_const_value<'tcx>(
329333
bug!("could not find non-ZST field during in {layout:#?}");
330334
}
331335

332-
let mut ecx =
333-
mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, param_env, CanAccessMutGlobal::No);
336+
let mut ecx = mk_eval_cx_to_read_const_val(
337+
tcx,
338+
DUMMY_SP,
339+
param_env,
340+
GlobalAccessPermissions::Static,
341+
);
334342

335343
// Need to create a place for this valtree.
336344
let place = create_valtree_place(&mut ecx, layout, valtree);

compiler/rustc_const_eval/src/util/caller_location.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use rustc_middle::ty::{self, Mutability};
77
use rustc_span::symbol::Symbol;
88
use tracing::trace;
99

10-
use crate::const_eval::{mk_eval_cx_to_read_const_val, CanAccessMutGlobal, CompileTimeInterpCx};
10+
use crate::const_eval::{
11+
mk_eval_cx_to_read_const_val, CompileTimeInterpCx, GlobalAccessPermissions,
12+
};
1113
use crate::interpret::*;
1214

1315
/// Allocate a `const core::panic::Location` with the provided filename and line/column numbers.
@@ -62,7 +64,7 @@ pub(crate) fn const_caller_location_provider(
6264
tcx.tcx,
6365
tcx.span,
6466
ty::ParamEnv::reveal_all(),
65-
CanAccessMutGlobal::No,
67+
GlobalAccessPermissions::Static,
6668
);
6769

6870
let loc_place = alloc_caller_location(&mut ecx, file, line, col);

compiler/rustc_const_eval/src/util/check_validity_requirement.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_middle::ty::layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout, Val
33
use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Ty, TyCtxt};
44
use rustc_target::abi::{Abi, FieldsShape, Scalar, Variants};
55

6-
use crate::const_eval::{CanAccessMutGlobal, CheckAlignment, CompileTimeMachine};
6+
use crate::const_eval::{CheckAlignment, CompileTimeMachine, GlobalAccessPermissions};
77
use crate::interpret::{InterpCx, MemoryKind, OpTy};
88

99
/// Determines if this type permits "raw" initialization by just transmuting some memory into an
@@ -45,7 +45,7 @@ fn might_permit_raw_init_strict<'tcx>(
4545
tcx: TyCtxt<'tcx>,
4646
kind: ValidityRequirement,
4747
) -> Result<bool, &'tcx LayoutError<'tcx>> {
48-
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);
48+
let machine = CompileTimeMachine::new(GlobalAccessPermissions::Static, CheckAlignment::Error);
4949

5050
let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);
5151

0 commit comments

Comments
 (0)