diff options
| author | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2017-12-07 20:06:55 +0200 |
|---|---|---|
| committer | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2017-12-10 17:46:31 +0200 |
| commit | 97c58ed66ca20e849db0dc3942fb9735819909fd (patch) | |
| tree | ed52564723bdc03c84732c5c0f046b3b8446fac1 | |
| parent | 733e95444fea30235c18076736d26b0f57adda9e (diff) | |
| download | rust-97c58ed66ca20e849db0dc3942fb9735819909fd.tar.gz rust-97c58ed66ca20e849db0dc3942fb9735819909fd.zip | |
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.
| -rw-r--r-- | src/librustc_mir/dataflow/impls/borrows.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/dataflow/impls/mod.rs | 27 | ||||
| -rw-r--r-- | src/librustc_mir/dataflow/impls/storage_liveness.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/dataflow/mod.rs | 15 |
4 files changed, 23 insertions, 23 deletions
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index c27cb43eff7..b3299b943ba 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -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`. diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs index db8ca0628c4..033d2a3212f 100644 --- a/src/librustc_mir/dataflow/impls/mod.rs +++ b/src/librustc_mir/dataflow/impls/mod.rs @@ -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) { diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs index fe6cd660b1e..9e5a7168378 100644 --- a/src/librustc_mir/dataflow/impls/storage_liveness.rs +++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs @@ -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 } diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index c331380566b..2136b41e462 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -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. |
