1
Fork 0

Use new dataflow framework for rustc_peek tests

This commit is contained in:
Dylan MacKenzie 2020-01-20 15:16:24 -08:00
parent f639607f63
commit 42d19a4e18
2 changed files with 30 additions and 42 deletions

View file

@ -9,11 +9,9 @@ use rustc::ty::{self, Ty, TyCtxt};
use rustc_hir::def_id::DefId;
use rustc_index::bit_set::BitSet;
use crate::dataflow::generic::{Analysis, Results, ResultsCursor};
use crate::dataflow::move_paths::{HasMoveData, MoveData};
use crate::dataflow::move_paths::{LookupResult, MovePathIndex};
use crate::dataflow::BitDenotation;
use crate::dataflow::DataflowResults;
use crate::dataflow::DataflowResultsCursor;
use crate::dataflow::IndirectlyMutableLocals;
use crate::dataflow::MoveDataParamEnv;
use crate::dataflow::{do_dataflow, DebugFormatted};
@ -21,12 +19,12 @@ use crate::dataflow::{
DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces,
};
use crate::dataflow::has_rustc_mir_with;
pub struct SanityCheck;
impl<'tcx> MirPass<'tcx> for SanityCheck {
fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) {
use crate::dataflow::has_rustc_mir_with;
let def_id = src.def_id();
if !tcx.has_attr(def_id, sym::rustc_mir) {
debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
@ -40,34 +38,17 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
let move_data = MoveData::gather_moves(body, tcx, param_env).unwrap();
let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
let dead_unwinds = BitSet::new_empty(body.basic_blocks().len());
let flow_inits = do_dataflow(
tcx,
body,
def_id,
&attributes,
&dead_unwinds,
MaybeInitializedPlaces::new(tcx, body, &mdpe),
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
);
let flow_uninits = do_dataflow(
tcx,
body,
def_id,
&attributes,
&dead_unwinds,
MaybeUninitializedPlaces::new(tcx, body, &mdpe),
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
);
let flow_def_inits = do_dataflow(
tcx,
body,
def_id,
&attributes,
&dead_unwinds,
DefinitelyInitializedPlaces::new(tcx, body, &mdpe),
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
);
let flow_indirectly_mut = do_dataflow(
let flow_inits = MaybeInitializedPlaces::new(tcx, body, &mdpe)
.into_engine(tcx, body, def_id)
.iterate_to_fixpoint();
let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &mdpe)
.into_engine(tcx, body, def_id)
.iterate_to_fixpoint();
let flow_def_inits = DefinitelyInitializedPlaces::new(tcx, body, &mdpe)
.into_engine(tcx, body, def_id)
.iterate_to_fixpoint();
let _flow_indirectly_mut = do_dataflow(
tcx,
body,
def_id,
@ -86,9 +67,12 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
if has_rustc_mir_with(&attributes, sym::rustc_peek_definite_init).is_some() {
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_def_inits);
}
// FIXME: Uncomment these as analyses are migrated to the new framework
/*
if has_rustc_mir_with(&attributes, sym::rustc_peek_indirectly_mutable).is_some() {
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_indirectly_mut);
}
*/
if has_rustc_mir_with(&attributes, sym::stop_after_dataflow).is_some() {
tcx.sess.fatal("stop_after_dataflow ended compilation");
}
@ -111,18 +95,18 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
/// (If there are any calls to `rustc_peek` that do not match the
/// expression form above, then that emits an error as well, but those
/// errors are not intended to be used for unit tests.)
pub fn sanity_check_via_rustc_peek<'tcx, O>(
pub fn sanity_check_via_rustc_peek<'tcx, A>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
def_id: DefId,
_attributes: &[ast::Attribute],
results: &DataflowResults<'tcx, O>,
results: &Results<'tcx, A>,
) where
O: RustcPeekAt<'tcx>,
A: RustcPeekAt<'tcx>,
{
debug!("sanity_check_via_rustc_peek def_id: {:?}", def_id);
let mut cursor = DataflowResultsCursor::new(results, body);
let mut cursor = ResultsCursor::new(body, results);
let peek_calls = body.basic_blocks().iter_enumerated().filter_map(|(bb, block_data)| {
PeekCall::from_terminator(tcx, block_data.terminator()).map(|call| (bb, block_data, call))
@ -153,9 +137,9 @@ pub fn sanity_check_via_rustc_peek<'tcx, O>(
| (PeekCallKind::ByVal, mir::Rvalue::Use(mir::Operand::Move(place)))
| (PeekCallKind::ByVal, mir::Rvalue::Use(mir::Operand::Copy(place))) => {
let loc = Location { block: bb, statement_index };
cursor.seek(loc);
cursor.seek_before(loc);
let state = cursor.get();
results.operator().peek_at(tcx, place, state, call);
results.analysis.peek_at(tcx, place, state, call);
}
_ => {
@ -255,7 +239,7 @@ impl PeekCall {
}
}
pub trait RustcPeekAt<'tcx>: BitDenotation<'tcx> {
pub trait RustcPeekAt<'tcx>: Analysis<'tcx> {
fn peek_at(
&self,
tcx: TyCtxt<'tcx>,
@ -265,9 +249,9 @@ pub trait RustcPeekAt<'tcx>: BitDenotation<'tcx> {
);
}
impl<'tcx, O> RustcPeekAt<'tcx> for O
impl<'tcx, A> RustcPeekAt<'tcx> for A
where
O: BitDenotation<'tcx, Idx = MovePathIndex> + HasMoveData<'tcx>,
A: Analysis<'tcx, Idx = MovePathIndex> + HasMoveData<'tcx>,
{
fn peek_at(
&self,
@ -292,6 +276,7 @@ where
}
}
/* FIXME: Add this back once `IndirectlyMutableLocals` uses the new dataflow framework.
impl<'tcx> RustcPeekAt<'tcx> for IndirectlyMutableLocals<'_, 'tcx> {
fn peek_at(
&self,
@ -313,3 +298,4 @@ impl<'tcx> RustcPeekAt<'tcx> for IndirectlyMutableLocals<'_, 'tcx> {
}
}
}
*/

View file

@ -1,5 +1,7 @@
// compile-flags: -Zunleash-the-miri-inside-of-you
// ignore-test Temporarily ignored while this analysis is migrated to the new framework.
#![feature(core_intrinsics, rustc_attrs, const_raw_ptr_deref)]
use std::cell::UnsafeCell;