about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2016-03-22 16:19:44 -0400
committerNiko Matsakis <niko@alum.mit.edu>2016-03-23 16:42:53 -0400
commitf976e222e97fdcb8ab66634c8910ce524f6804c9 (patch)
tree32f69e6cf5cf4e25511b7b1ca979b2bc3e38c36b
parenta61c1759c7297f09955409fffaa162c7a21f89a7 (diff)
downloadrust-f976e222e97fdcb8ab66634c8910ce524f6804c9.tar.gz
rust-f976e222e97fdcb8ab66634c8910ce524f6804c9.zip
fix bug in `simplify_cfg` with inf. loops
-rw-r--r--src/librustc_mir/transform/simplify_cfg.rs26
1 files changed, 18 insertions, 8 deletions
diff --git a/src/librustc_mir/transform/simplify_cfg.rs b/src/librustc_mir/transform/simplify_cfg.rs
index d1f9a5bd259..21b1d022fda 100644
--- a/src/librustc_mir/transform/simplify_cfg.rs
+++ b/src/librustc_mir/transform/simplify_cfg.rs
@@ -12,6 +12,7 @@ use rustc::middle::const_eval::ConstVal;
 use rustc::middle::ty::TyCtxt;
 use rustc::mir::repr::*;
 use rustc::mir::transform::{MirPass, Pass};
+use pretty;
 use syntax::ast::NodeId;
 
 use super::remove_dead_blocks::RemoveDeadBlocks;
@@ -30,16 +31,22 @@ impl SimplifyCfg {
             let mut seen: Vec<BasicBlock> = Vec::with_capacity(8);
 
             while mir.basic_block_data(target).statements.is_empty() {
-                debug!("final_target: target={:?}", target);
-                match mir.basic_block_data(target).terminator().kind {
-                    TerminatorKind::Goto { target: next } => {
-                        if seen.contains(&next) {
-                            return None;
+                // NB -- terminator may have been swapped with `None`
+                // below, in which case we have a cycle and just want
+                // to stop
+                if let Some(ref terminator) = mir.basic_block_data(target).terminator {
+                    match terminator.kind {
+                        TerminatorKind::Goto { target: next } => {
+                            if seen.contains(&next) {
+                                return None;
+                            }
+                            seen.push(next);
+                            target = next;
                         }
-                        seen.push(next);
-                        target = next;
+                        _ => break
                     }
-                    _ => break
+                } else {
+                    break
                 }
             }
 
@@ -106,8 +113,11 @@ impl SimplifyCfg {
 
 impl<'tcx> MirPass<'tcx> for SimplifyCfg {
     fn run_pass(&mut self, tcx: &TyCtxt<'tcx>, id: NodeId, mir: &mut Mir<'tcx>) {
+        let mut counter = 0;
         let mut changed = true;
         while changed {
+            pretty::dump_mir(tcx, "simplify_cfg", &counter, id, mir, None);
+            counter += 1;
             changed = self.simplify_branches(mir);
             changed |= self.remove_goto_chains(mir);
             RemoveDeadBlocks.run_pass(tcx, id, mir);