Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4bc963e

Browse files
committedJan 16, 2023
Avoid trivial checks on cleanup control flow in MIR validator
1 parent ec3d993 commit 4bc963e

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed
 

‎compiler/rustc_const_eval/src/transform/validate.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
6464
tcx,
6565
param_env,
6666
mir_phase,
67+
unwind_edge_count: 0,
6768
reachable_blocks: traversal::reachable_as_bitset(body),
6869
storage_liveness,
6970
place_cache: Vec::new(),
@@ -80,6 +81,7 @@ struct TypeChecker<'a, 'tcx> {
8081
tcx: TyCtxt<'tcx>,
8182
param_env: ParamEnv<'tcx>,
8283
mir_phase: MirPhase,
84+
unwind_edge_count: usize,
8385
reachable_blocks: BitSet<BasicBlock>,
8486
storage_liveness: ResultsCursor<'a, 'tcx, MaybeStorageLive<'static>>,
8587
place_cache: Vec<PlaceRef<'tcx>>,
@@ -104,7 +106,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
104106
);
105107
}
106108

107-
fn check_edge(&self, location: Location, bb: BasicBlock, edge_kind: EdgeKind) {
109+
fn check_edge(&mut self, location: Location, bb: BasicBlock, edge_kind: EdgeKind) {
108110
if bb == START_BLOCK {
109111
self.fail(location, "start block must not have predecessors")
110112
}
@@ -113,10 +115,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
113115
match (src.is_cleanup, bb.is_cleanup, edge_kind) {
114116
// Non-cleanup blocks can jump to non-cleanup blocks along non-unwind edges
115117
(false, false, EdgeKind::Normal)
116-
// Non-cleanup blocks can jump to cleanup blocks along unwind edges
117-
| (false, true, EdgeKind::Unwind)
118118
// Cleanup blocks can jump to cleanup blocks along non-unwind edges
119119
| (true, true, EdgeKind::Normal) => {}
120+
// Non-cleanup blocks can jump to cleanup blocks along unwind edges
121+
(false, true, EdgeKind::Unwind) => {
122+
self.unwind_edge_count += 1;
123+
}
120124
// All other jumps are invalid
121125
_ => {
122126
self.fail(
@@ -137,6 +141,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
137141
}
138142

139143
fn check_cleanup_control_flow(&self) {
144+
if self.unwind_edge_count <= 1 {
145+
return;
146+
}
140147
let doms = self.body.basic_blocks.dominators();
141148
let mut post_contract_node = FxHashMap::default();
142149
// Reusing the allocation across invocations of the closure
@@ -196,7 +203,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
196203
stack.clear();
197204
stack.insert(bb);
198205
loop {
199-
let Some(parent )= parent[bb].take() else {
206+
let Some(parent)= parent[bb].take() else {
200207
break
201208
};
202209
let no_cycle = stack.insert(parent);

0 commit comments

Comments
 (0)
Please sign in to comment.