diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2016-03-22 16:19:44 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2016-03-23 16:42:53 -0400 |
| commit | f976e222e97fdcb8ab66634c8910ce524f6804c9 (patch) | |
| tree | 32f69e6cf5cf4e25511b7b1ca979b2bc3e38c36b | |
| parent | a61c1759c7297f09955409fffaa162c7a21f89a7 (diff) | |
| download | rust-f976e222e97fdcb8ab66634c8910ce524f6804c9.tar.gz rust-f976e222e97fdcb8ab66634c8910ce524f6804c9.zip | |
fix bug in `simplify_cfg` with inf. loops
| -rw-r--r-- | src/librustc_mir/transform/simplify_cfg.rs | 26 |
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); |
