about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/transform/validate.rs
diff options
context:
space:
mode:
authorJakob Degen <jakob.e.degen@gmail.com>2023-01-16 15:01:16 -0800
committerJakob Degen <jakob.e.degen@gmail.com>2023-01-16 15:01:16 -0800
commit4bc963eba67e61507d2069edf10cfec1d7f8ec0a (patch)
tree4fe9e8c46bc9fc5b01a732d57d4e97414b6a12b0 /compiler/rustc_const_eval/src/transform/validate.rs
parentec3d9934103ae33d2116bb5791b38921902c8539 (diff)
downloadrust-4bc963eba67e61507d2069edf10cfec1d7f8ec0a.tar.gz
rust-4bc963eba67e61507d2069edf10cfec1d7f8ec0a.zip
Avoid trivial checks on cleanup control flow in MIR validator
Diffstat (limited to 'compiler/rustc_const_eval/src/transform/validate.rs')
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs15
1 files changed, 11 insertions, 4 deletions
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index b4f1ab62267..dd168a9ac3c 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -64,6 +64,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
             tcx,
             param_env,
             mir_phase,
+            unwind_edge_count: 0,
             reachable_blocks: traversal::reachable_as_bitset(body),
             storage_liveness,
             place_cache: Vec::new(),
@@ -80,6 +81,7 @@ struct TypeChecker<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     param_env: ParamEnv<'tcx>,
     mir_phase: MirPhase,
+    unwind_edge_count: usize,
     reachable_blocks: BitSet<BasicBlock>,
     storage_liveness: ResultsCursor<'a, 'tcx, MaybeStorageLive<'static>>,
     place_cache: Vec<PlaceRef<'tcx>>,
@@ -104,7 +106,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         );
     }
 
-    fn check_edge(&self, location: Location, bb: BasicBlock, edge_kind: EdgeKind) {
+    fn check_edge(&mut self, location: Location, bb: BasicBlock, edge_kind: EdgeKind) {
         if bb == START_BLOCK {
             self.fail(location, "start block must not have predecessors")
         }
@@ -113,10 +115,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             match (src.is_cleanup, bb.is_cleanup, edge_kind) {
                 // Non-cleanup blocks can jump to non-cleanup blocks along non-unwind edges
                 (false, false, EdgeKind::Normal)
-                // Non-cleanup blocks can jump to cleanup blocks along unwind edges
-                | (false, true, EdgeKind::Unwind)
                 // Cleanup blocks can jump to cleanup blocks along non-unwind edges
                 | (true, true, EdgeKind::Normal) => {}
+                // Non-cleanup blocks can jump to cleanup blocks along unwind edges
+                (false, true, EdgeKind::Unwind) => {
+                    self.unwind_edge_count += 1;
+                }
                 // All other jumps are invalid
                 _ => {
                     self.fail(
@@ -137,6 +141,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     }
 
     fn check_cleanup_control_flow(&self) {
+        if self.unwind_edge_count <= 1 {
+            return;
+        }
         let doms = self.body.basic_blocks.dominators();
         let mut post_contract_node = FxHashMap::default();
         // Reusing the allocation across invocations of the closure
@@ -196,7 +203,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             stack.clear();
             stack.insert(bb);
             loop {
-                let Some(parent )= parent[bb].take() else {
+                let Some(parent)= parent[bb].take() else {
                     break
                 };
                 let no_cycle = stack.insert(parent);