diff options
| author | Jakob Degen <jakob.e.degen@gmail.com> | 2023-01-16 15:01:16 -0800 |
|---|---|---|
| committer | Jakob Degen <jakob.e.degen@gmail.com> | 2023-01-16 15:01:16 -0800 |
| commit | 4bc963eba67e61507d2069edf10cfec1d7f8ec0a (patch) | |
| tree | 4fe9e8c46bc9fc5b01a732d57d4e97414b6a12b0 /compiler/rustc_const_eval/src/transform/validate.rs | |
| parent | ec3d9934103ae33d2116bb5791b38921902c8539 (diff) | |
| download | rust-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.rs | 15 |
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); |
