Skip to content

Commit a5036a9

Browse files
committed
Fix generic specialization that can result in noreturn apply without unreachable
rdar://50393169
1 parent d912e33 commit a5036a9

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

include/swift/SIL/TypeSubstCloner.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,13 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
193193
Helper.getArguments(), Inst->isNonThrowing(),
194194
GenericSpecializationInformation::create(
195195
Inst, getBuilder()));
196+
// Specialization can return noreturn applies that were not identified as
197+
// such before.
198+
if (N->isCalleeNoReturn() &&
199+
!isa<UnreachableInst>(*std::next(SILBasicBlock::iterator(Inst)))) {
200+
noReturnApplies.push_back(N);
201+
}
202+
196203
recordClonedInstruction(Inst, N);
197204
}
198205

@@ -381,6 +388,9 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
381388
SILFunction &Original;
382389
/// True, if used for inlining.
383390
bool Inlining;
391+
// Generic specialization can create noreturn applications that where
392+
// previously not identifiable as such.
393+
SmallVector<ApplyInst *, 16> noReturnApplies;
384394
};
385395

386396
} // end namespace swift

include/swift/SILOptimizer/Utils/GenericCloner.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ class GenericCloner
7474
return SC.getCloned();
7575
}
7676

77+
void fixUp(SILFunction *calleeFunction);
78+
7779
protected:
7880
void visitTerminator(SILBasicBlock *BB);
7981

lib/SILOptimizer/Utils/GenericCloner.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,12 @@ const SILDebugScope *GenericCloner::remapScope(const SILDebugScope *DS) {
191191
RemappedScopeCache.insert({DS, RemappedScope});
192192
return RemappedScope;
193193
}
194+
195+
void GenericCloner::fixUp(SILFunction *f) {
196+
for (auto *apply : noReturnApplies) {
197+
auto applyBlock = apply->getParent();
198+
applyBlock->split(std::next(SILBasicBlock::iterator(apply)));
199+
getBuilder().setInsertionPoint(applyBlock);
200+
getBuilder().createUnreachable(apply->getLoc());
201+
}
202+
}

0 commit comments

Comments
 (0)