about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTomasz Miąsko <tomasz.miasko@gmail.com>2020-09-16 00:00:00 +0000
committerTomasz Miąsko <tomasz.miasko@gmail.com>2020-09-16 00:00:00 +0000
commitff1a9e406bfccefedb6c4f2cabc0c4d59ac947d4 (patch)
tree064dd0eb23cbda5866929ed0b4f07e784220d4cd
parent90b1f5ae59291dd69d72fad41a22277df19dc953 (diff)
downloadrust-ff1a9e406bfccefedb6c4f2cabc0c4d59ac947d4.tar.gz
rust-ff1a9e406bfccefedb6c4f2cabc0c4d59ac947d4.zip
Fix underflow when calculating the number of no-op jumps folded
When removing unwinds to no-op blocks and folding jumps to no-op blocks,
remove the unwind target first. Otherwise we cannot determine if target
has been already folded or not.

Previous implementation incorrectly assumed that all resume targets had
been folded already, occasionally resulting in an underflow:

remove_noop_landing_pads: removed 18446744073709551613 jumps and 3 landing pads
-rw-r--r--compiler/rustc_mir/src/transform/remove_noop_landing_pads.rs19
1 files changed, 10 insertions, 9 deletions
diff --git a/compiler/rustc_mir/src/transform/remove_noop_landing_pads.rs b/compiler/rustc_mir/src/transform/remove_noop_landing_pads.rs
index 0bad1e5037a..4079f0110e2 100644
--- a/compiler/rustc_mir/src/transform/remove_noop_landing_pads.rs
+++ b/compiler/rustc_mir/src/transform/remove_noop_landing_pads.rs
@@ -102,6 +102,16 @@ impl RemoveNoopLandingPads {
         let postorder: Vec<_> = traversal::postorder(body).map(|(bb, _)| bb).collect();
         for bb in postorder {
             debug!("  processing {:?}", bb);
+            if let Some(unwind) = body[bb].terminator_mut().unwind_mut() {
+                if let Some(unwind_bb) = *unwind {
+                    if nop_landing_pads.contains(unwind_bb) {
+                        debug!("    removing noop landing pad");
+                        landing_pads_removed += 1;
+                        *unwind = None;
+                    }
+                }
+            }
+
             for target in body[bb].terminator_mut().successors_mut() {
                 if *target != resume_block && nop_landing_pads.contains(*target) {
                     debug!("    folding noop jump to {:?} to resume block", target);
@@ -110,15 +120,6 @@ impl RemoveNoopLandingPads {
                 }
             }
 
-            if let Some(unwind) = body[bb].terminator_mut().unwind_mut() {
-                if *unwind == Some(resume_block) {
-                    debug!("    removing noop landing pad");
-                    jumps_folded -= 1;
-                    landing_pads_removed += 1;
-                    *unwind = None;
-                }
-            }
-
             let is_nop_landing_pad = self.is_nop_landing_pad(bb, body, &nop_landing_pads);
             if is_nop_landing_pad {
                 nop_landing_pads.insert(bb);