mirror of https://github.com/rust-lang/rust.git
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:
parent
733e95444f
commit
97c58ed66c
|
@ -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`.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue