avoid passing the gen/kill bits to `start_block_effects`

If the gen/kill bits are set there, the effects of `start_block_effects`
will not be seen when using `FlowAtLocation` etc. to go over the MIR.

EverInitializedLvals is the only pass that got this wrong, but this
fixes the footgun for everyone.
This commit is contained in:
Ariel Ben-Yehuda 2017-12-07 20:06:55 +02:00
parent 733e95444f
commit 97c58ed66c
4 changed files with 23 additions and 23 deletions

View File

@ -213,7 +213,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
fn bits_per_block(&self) -> usize {
self.borrows.len()
}
fn start_block_effect(&self, _sets: &mut BlockSets<BorrowIndex>) {
fn start_block_effect(&self, _sets: &mut IdxSet<BorrowIndex>) {
// no borrows of code region_scopes have been taken prior to
// function execution, so this method has no effect on
// `_sets`.

View File

@ -331,13 +331,12 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'gcx, 'tcx> {
self.move_data().move_paths.len()
}
fn start_block_effect(&self, sets: &mut BlockSets<MovePathIndex>)
{
fn start_block_effect(&self, entry_set: &mut IdxSet<MovePathIndex>) {
drop_flag_effects_for_function_entry(
self.tcx, self.mir, self.mdpe,
|path, s| {
assert!(s == DropFlagState::Present);
sets.on_entry.add(&path);
entry_set.add(&path);
});
}
@ -384,15 +383,15 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
}
// sets on_entry bits for Arg places
fn start_block_effect(&self, sets: &mut BlockSets<MovePathIndex>) {
fn start_block_effect(&self, entry_set: &mut IdxSet<MovePathIndex>) {
// set all bits to 1 (uninit) before gathering counterevidence
for e in sets.on_entry.words_mut() { *e = !0; }
for e in entry_set.words_mut() { *e = !0; }
drop_flag_effects_for_function_entry(
self.tcx, self.mir, self.mdpe,
|path, s| {
assert!(s == DropFlagState::Present);
sets.on_entry.remove(&path);
entry_set.remove(&path);
});
}
@ -439,14 +438,14 @@ impl<'a, 'gcx, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'gcx, 'tcx
}
// sets on_entry bits for Arg places
fn start_block_effect(&self, sets: &mut BlockSets<MovePathIndex>) {
for e in sets.on_entry.words_mut() { *e = 0; }
fn start_block_effect(&self, entry_set: &mut IdxSet<MovePathIndex>) {
for e in entry_set.words_mut() { *e = 0; }
drop_flag_effects_for_function_entry(
self.tcx, self.mir, self.mdpe,
|path, s| {
assert!(s == DropFlagState::Present);
sets.on_entry.add(&path);
entry_set.add(&path);
});
}
@ -492,10 +491,11 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MovingOutStatements<'a, 'gcx, 'tcx> {
self.move_data().moves.len()
}
fn start_block_effect(&self, _sets: &mut BlockSets<MoveOutIndex>) {
fn start_block_effect(&self, _sets: &mut IdxSet<MoveOutIndex>) {
// no move-statements have been executed prior to function
// execution, so this method has no effect on `_sets`.
}
fn statement_effect(&self,
sets: &mut BlockSets<MoveOutIndex>,
location: Location) {
@ -568,9 +568,12 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
self.move_data().inits.len()
}
fn start_block_effect(&self, sets: &mut BlockSets<InitIndex>) {
sets.gen_all((0..self.mir.arg_count).map(InitIndex::new));
fn start_block_effect(&self, entry_set: &mut IdxSet<InitIndex>) {
for arg_init in 0..self.mir.arg_count {
entry_set.add(&InitIndex::new(arg_init));
}
}
fn statement_effect(&self,
sets: &mut BlockSets<InitIndex>,
location: Location) {

View File

@ -36,7 +36,7 @@ impl<'a, 'tcx> BitDenotation for MaybeStorageLive<'a, 'tcx> {
self.mir.local_decls.len()
}
fn start_block_effect(&self, _sets: &mut BlockSets<Local>) {
fn start_block_effect(&self, _sets: &mut IdxSet<Local>) {
// Nothing is live on function entry
}

View File

@ -171,7 +171,7 @@ impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation
{
let sets = &mut self.flow_state.sets.for_block(mir::START_BLOCK.index());
self.flow_state.operator.start_block_effect(sets);
self.flow_state.operator.start_block_effect(&mut sets.on_entry);
}
for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
@ -556,16 +556,13 @@ pub trait BitDenotation: DataflowOperator {
/// Size of each bitvector allocated for each block in the analysis.
fn bits_per_block(&self) -> usize;
/// Mutates the block-sets (the flow sets for the given
/// basic block) according to the effects that have been
/// established *prior* to entering the start block.
/// Mutates the entry set according to the effects that
/// have been established *prior* to entering the start
/// block. This can't access the gen/kill sets, because
/// these won't be accounted for correctly.
///
/// (For example, establishing the call arguments.)
///
/// (Typically this should only modify `sets.on_entry`, since the
/// gen and kill sets should reflect the effects of *executing*
/// the start block itself.)
fn start_block_effect(&self, sets: &mut BlockSets<Self::Idx>);
fn start_block_effect(&self, entry_set: &mut IdxSet<Self::Idx>);
/// Mutates the block-sets (the flow sets for the given
/// basic block) according to the effects of evaluating statement.