Skip to content

Commit

Permalink
avoid passing the gen/kill bits to start_block_effects
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
arielb1 committed Dec 10, 2017
1 parent 733e954 commit 97c58ed
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/librustc_mir/dataflow/impls/borrows.rs
Expand Up @@ -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`.
Expand Down
27 changes: 15 additions & 12 deletions src/librustc_mir/dataflow/impls/mod.rs
Expand Up @@ -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);
});
}

Expand Down Expand Up @@ -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);
});
}

Expand Down Expand Up @@ -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);
});
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/dataflow/impls/storage_liveness.rs
Expand Up @@ -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
}

Expand Down
15 changes: 6 additions & 9 deletions src/librustc_mir/dataflow/mod.rs
Expand Up @@ -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() {
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 97c58ed

Please sign in to comment.