Skip to content

Commit 4f4ed60

Browse files
authored
Merge pull request swiftlang#31151 from eeckstein/fix-devirtualizer
Devirtualizer: fix a miscompile due to handling of cast instructions.
2 parents 87d3b4d + 131aede commit 4f4ed60

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

lib/SILOptimizer/Utils/Devirtualize.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,8 +1147,15 @@ swift::tryDevirtualizeApply(ApplySite applySite, ClassHierarchyAnalysis *cha,
11471147

11481148
// Try to check if the exact dynamic type of the instance is statically
11491149
// known.
1150-
if (auto instance = getInstanceWithExactDynamicType(cmi->getOperand(), cha))
1151-
return tryDevirtualizeClassMethod(fas, instance, cd, ore);
1150+
if (auto instance = getInstanceWithExactDynamicType(cmi->getOperand(), cha)) {
1151+
// Update the classDecl, because we are stripping casts more aggressively
1152+
// in getInstanceWithExactDynamicType than in stripUpCasts.
1153+
CanType classType = getSelfInstanceType(instance->getType().getASTType());
1154+
// This should never be null - make the check just to be on the safe side.
1155+
if (ClassDecl *cd = classType.getClassOrBoundGenericClass())
1156+
return tryDevirtualizeClassMethod(fas, instance, cd, ore);
1157+
return {ApplySite(), false};
1158+
}
11521159

11531160
if (auto exactTy = getExactDynamicType(cmi->getOperand(), cha)) {
11541161
if (exactTy == cmi->getOperand()->getType())
@@ -1207,8 +1214,11 @@ bool swift::canDevirtualizeApply(FullApplySite applySite,
12071214

12081215
// Try to check if the exact dynamic type of the instance is statically
12091216
// known.
1210-
if (auto instance = getInstanceWithExactDynamicType(cmi->getOperand(), cha))
1211-
return canDevirtualizeClassMethod(applySite, cd);
1217+
if (auto instance = getInstanceWithExactDynamicType(cmi->getOperand(), cha)) {
1218+
CanType classType = getSelfInstanceType(instance->getType().getASTType());
1219+
ClassDecl *cd = classType.getClassOrBoundGenericClass();
1220+
return cd && canDevirtualizeClassMethod(applySite, cd);
1221+
}
12121222

12131223
if (auto exactTy = getExactDynamicType(cmi->getOperand(), cha)) {
12141224
if (exactTy == cmi->getOperand()->getType())
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift -O -module-name=test %s -o %t/a.out
3+
// RUN: %target-run %t/a.out | %FileCheck %s
4+
// REQUIRES: executable_test
5+
6+
class Base {
7+
required init() { }
8+
9+
class func instance() -> Base {
10+
return self.init()
11+
}
12+
}
13+
14+
class Middle: Base {
15+
override class func instance() -> Middle {
16+
return self.init()
17+
}
18+
}
19+
20+
class Derived: Middle {
21+
required init() {
22+
super.init()
23+
print("init Derived")
24+
}
25+
}
26+
27+
struct Maker<C: Base> {
28+
@inline(never)
29+
static func create() -> Base {
30+
return C.instance()
31+
}
32+
}
33+
34+
// CHECK: init Derived
35+
// CHECK: test.Derived
36+
print(Maker<Derived>.create())
37+

0 commit comments

Comments
 (0)