Skip to content

Commit 789ada5

Browse files
authored
Merge pull request #34346 from CodaFi/override-overdrive
Disregard Overridden Candidates in Infinite Recursion Check
2 parents a757d7b + baa45a1 commit 789ada5

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

lib/SILOptimizer/Mandatory/DiagnoseInfiniteRecursion.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,15 @@ static bool hasRecursiveCallInPath(SILBasicBlock &Block,
5252

5353
if (FullApplySite FAI = FullApplySite::isa(&I)) {
5454
// Don't touch dynamic dispatch.
55-
if (isa<ObjCMethodInst>(FAI.getCallee()))
55+
const auto callee = FAI.getCallee();
56+
if (isa<SuperMethodInst>(callee) ||
57+
isa<ObjCSuperMethodInst>(callee) ||
58+
isa<ObjCMethodInst>(callee)) {
5659
continue;
60+
}
5761

5862
auto &M = FAI.getModule();
59-
if (auto *CMI = dyn_cast<ClassMethodInst>(FAI.getCallee())) {
63+
if (auto *CMI = dyn_cast<ClassMethodInst>(callee)) {
6064
auto ClassType = CMI->getOperand()->getType().getASTType();
6165

6266
// FIXME: If we're not inside the module context of the method,
@@ -71,14 +75,26 @@ static bool hasRecursiveCallInPath(SILBasicBlock &Block,
7175
continue;
7276
}
7377

78+
if (!calleesAreStaticallyKnowable(FAI.getModule(), CMI->getMember())) {
79+
continue;
80+
}
81+
82+
// The "statically knowable" check just means that we have all the
83+
// callee candidates available for analysis. We still need to check
84+
// if the current function has a known override point.
85+
auto *method = CMI->getMember().getAbstractFunctionDecl();
86+
if (method->isOverridden()) {
87+
continue;
88+
}
89+
7490
auto *F = getTargetClassMethod(M, CD, CMI);
7591
if (F == Target)
7692
return true;
7793

7894
continue;
7995
}
8096

81-
if (auto *WMI = dyn_cast<WitnessMethodInst>(FAI.getCallee())) {
97+
if (auto *WMI = dyn_cast<WitnessMethodInst>(callee)) {
8298
SILFunction *F;
8399
SILWitnessTable *WT;
84100

test/SILOptimizer/infinite_recursion.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-swift-frontend -emit-sil -primary-file %s -o /dev/null -verify
2-
// RUN: %target-swift-frontend -emit-sil -primary-file %s -o /dev/null -verify
1+
// RUN: %target-swift-frontend -emit-sil %s -o /dev/null -verify
2+
// RUN: %target-swift-frontend -emit-sil %s -o /dev/null -verify
33

44
func a() { // expected-warning {{all paths through this function will call itself}}
55
a()
@@ -123,7 +123,7 @@ class S {
123123
return a()
124124
}
125125

126-
func b() { // expected-warning {{all paths through this function will call itself}}
126+
func b() { // No warning - has a known override.
127127
var i = 0
128128
repeat {
129129
i += 1
@@ -171,3 +171,14 @@ func factorial(_ n : UInt) -> UInt { // expected-warning {{all paths through thi
171171
func tr(_ key: String) -> String { // expected-warning {{all paths through this function will call itself}}
172172
return tr(key) ?? key // expected-warning {{left side of nil coalescing operator '??' has non-optional type}}
173173
}
174+
175+
class Node {
176+
var parent: Node?
177+
var rootNode: RootNode {
178+
return parent!.rootNode // No warning - has an override.
179+
}
180+
}
181+
182+
class RootNode: Node {
183+
override var rootNode: RootNode { return self }
184+
}

0 commit comments

Comments
 (0)