Skip to content

Commit

Permalink
Allow reading non-mutable statics in const prop
Browse files Browse the repository at this point in the history
  • Loading branch information
wesleywiser committed Sep 28, 2019
1 parent dcc6c28 commit 3e9bab2
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 11 deletions.
7 changes: 3 additions & 4 deletions src/librustc_mir/interpret/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,9 @@ pub trait Machine<'mir, 'tcx>: Sized {
frame.locals[local].access()
}

/// Called before a `StaticKind::Static` value is read.
fn before_eval_static(
_ecx: &InterpCx<'mir, 'tcx, Self>,
_place_static: &mir::Static<'tcx>,
/// Called before a `StaticKind::Static` value is accessed.
fn before_access_static(
_allocation: &Allocation,
) -> InterpResult<'tcx> {
Ok(())
}
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_mir/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
// Make sure we use the ID of the resolved memory, not the lazy one!
let id = raw_const.alloc_id;
let allocation = tcx.alloc_map.lock().unwrap_memory(id);

M::before_access_static(allocation)?;
Cow::Borrowed(allocation)
}
}
Expand Down
2 changes: 0 additions & 2 deletions src/librustc_mir/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -601,8 +601,6 @@ where
}

StaticKind::Static => {
M::before_eval_static(self, place_static)?;

let ty = place_static.ty;
assert!(!ty.needs_subst());
let layout = self.layout_of(ty)?;
Expand Down
16 changes: 11 additions & 5 deletions src/librustc_mir/transform/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc::hir::def::DefKind;
use rustc::hir::def_id::DefId;
use rustc::mir::{
AggregateKind, Constant, Location, Place, PlaceBase, Body, Operand, Rvalue,
Local, NullOp, UnOp, StatementKind, Statement, LocalKind, Static,
Local, NullOp, UnOp, StatementKind, Statement, LocalKind,
TerminatorKind, Terminator, ClearCrossCrate, SourceInfo, BinOp,
SourceScope, SourceScopeLocalData, LocalDecl, BasicBlock,
};
Expand All @@ -17,6 +17,7 @@ use rustc::mir::visit::{
};
use rustc::mir::interpret::{Scalar, InterpResult, PanicInfo};
use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
use syntax::ast::Mutability;
use syntax_pos::{Span, DUMMY_SP};
use rustc::ty::subst::InternalSubsts;
use rustc_data_structures::fx::FxHashMap;
Expand Down Expand Up @@ -229,11 +230,16 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
l.access()
}

fn before_eval_static(
_ecx: &InterpCx<'mir, 'tcx, Self>,
_place_static: &Static<'tcx>,
fn before_access_static(
allocation: &Allocation<Self::PointerTag, Self::AllocExtra>,
) -> InterpResult<'tcx> {
throw_unsup_format!("can't eval statics in ConstProp");
// if the static allocation is mutable or if it has relocations (it may be legal to mutate
// the memory behind that in the future), then we can't const prop it
if allocation.mutability == Mutability::Mutable || allocation.relocations().len() > 0 {
throw_unsup_format!("can't eval mutable statics in ConstProp");
}

Ok(())
}

fn before_terminator(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
Expand Down
27 changes: 27 additions & 0 deletions src/test/mir-opt/const_prop/read_immutable_static.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
static FOO: u8 = 2;

fn main() {
let x = FOO + FOO;
}

// END RUST SOURCE
// START rustc.main.ConstProp.before.mir
// bb0: {
// ...
// _2 = (FOO: u8);
// ...
// _3 = (FOO: u8);
// _1 = Add(move _2, move _3);
// ...
// }
// END rustc.main.ConstProp.before.mir
// START rustc.main.ConstProp.after.mir
// bb0: {
// ...
// _2 = const 2u8;
// ...
// _3 = const 2u8;
// _1 = Add(move _2, move _3);
// ...
// }
// END rustc.main.ConstProp.after.mir

0 comments on commit 3e9bab2

Please sign in to comment.