about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <ariel.byd@gmail.com>2017-12-07 20:06:55 +0200
committerAriel Ben-Yehuda <ariel.byd@gmail.com>2017-12-10 17:46:31 +0200
commit97c58ed66ca20e849db0dc3942fb9735819909fd (patch)
treeed52564723bdc03c84732c5c0f046b3b8446fac1
parent733e95444fea30235c18076736d26b0f57adda9e (diff)
downloadrust-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.rs2
-rw-r--r--src/librustc_mir/dataflow/impls/mod.rs27
-rw-r--r--src/librustc_mir/dataflow/impls/storage_liveness.rs2
-rw-r--r--src/librustc_mir/dataflow/mod.rs15
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.