Skip to content

Commit 653b6ec

Browse files
committed
fix a crash/hang in SimplifyCFG.
Jump threading in an unreachable CFG region can lead to a crash (in an assert compiler) or hang (in an no-assert compiler) in `ValueBase::replaceAllUsesWith`. Unfortunately I couldn't come up with an isolated SIL test case. rdar://92267349
1 parent 0c78790 commit 653b6ec

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1319,8 +1319,14 @@ TrampolineDest::TrampolineDest(SILBasicBlock *sourceBB,
13191319
return;
13201320
}
13211321
}
1322+
SILBasicBlock *destBlock = targetBranch->getDestBB();
13221323
newSourceBranchArgs.reserve(targetBranch->getArgs().size());
13231324
for (SILValue branchArg : targetBranch->getArgs()) {
1325+
if (branchArg->getParentBlock() == destBlock) {
1326+
// This can happen if the involved blocks are part of an unreachable CFG
1327+
// cycle (dominance is not meaningful in such a case).
1328+
return;
1329+
}
13241330
if (branchArg->getParentBlock() == targetBB) {
13251331
auto *phi = dyn_cast<SILPhiArgument>(branchArg);
13261332
if (!phi || !phi->isPhi()) {
@@ -1331,7 +1337,7 @@ TrampolineDest::TrampolineDest(SILBasicBlock *sourceBB,
13311337
newSourceBranchArgs.push_back(branchArg);
13321338
}
13331339
// Setting destBB constructs a valid TrampolineDest.
1334-
destBB = targetBranch->getDestBB();
1340+
destBB = destBlock;
13351341
}
13361342

13371343
#ifndef NDEBUG
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-swift-frontend -O %s -emit-sil -o /dev/null
2+
3+
public class X {}
4+
5+
public func testit(_ s: [X]) -> X? {
6+
var r: X?
7+
for e in s {
8+
if r == nil {
9+
r = e
10+
} else if e !== r {
11+
return nil
12+
}
13+
}
14+
return r
15+
}
16+

0 commit comments

Comments
 (0)