Skip to content

Commit b368b0d

Browse files
authored
Merge pull request swiftlang#27874 from slavapestov/subclass-scope-final-method-fix-5.1
SIL: Final methods need a subclass scope if they override something [5.1]
2 parents 71d6f49 + 54e0ff5 commit b368b0d

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

lib/SIL/SILDeclRef.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -984,12 +984,13 @@ SubclassScope SILDeclRef::getSubclassScope() const {
984984
if (isDefaultArgGenerator())
985985
return SubclassScope::NotApplicable;
986986

987-
// Only non-final methods in non-final classes go in the vtable.
987+
// Only methods in non-final classes go in the vtable.
988988
auto *classType = context->getSelfClassDecl();
989989
if (!classType || classType->isFinal())
990990
return SubclassScope::NotApplicable;
991991

992-
if (decl->isFinal())
992+
// Final methods only go in the vtable if they override something.
993+
if (decl->isFinal() && !decl->getOverriddenDecl())
993994
return SubclassScope::NotApplicable;
994995

995996
assert(decl->getEffectiveAccess() <= classType->getEffectiveAccess() &&

test/IRGen/method_linkage.swift

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,24 @@ class Base {
3131
// RESILIENT: define hidden swiftcc void @"$s14method_linkage4Base{{.*}}5other0
3232
fileprivate func other() {
3333
}
34+
35+
// CHECK: define hidden swiftcc void @"$s14method_linkage4BaseC4prop{{.*}}LLytvg
36+
// RESILIENT: define hidden swiftcc void @"$s14method_linkage4BaseC4prop{{.*}}LLytvg
37+
fileprivate var prop: () {
38+
return ()
39+
}
3440
}
3541
class Derived : Base {
36-
// CHECK: define internal swiftcc void @"$s14method_linkage7Derived{{.*}}3foo0
37-
// RESILIENT: define internal swiftcc void @"$s14method_linkage7Derived{{.*}}3foo0
42+
// CHECK: define hidden swiftcc void @"$s14method_linkage7Derived{{.*}}3foo0
43+
// RESILIENT: define hidden swiftcc void @"$s14method_linkage7Derived{{.*}}3foo0
3844
fileprivate final override func foo() {
3945
}
46+
47+
// CHECK: define hidden swiftcc void @"$s14method_linkage7DerivedC4prop{{.*}}LLytvg
48+
// RESILIENT: define hidden swiftcc void @"$s14method_linkage7DerivedC4prop{{.*}}LLytvg
49+
fileprivate final override var prop: () {
50+
return ()
51+
}
4052
}
4153

4254
extension Base {
@@ -92,6 +104,20 @@ open class OpenClass {
92104
// RESILIENT: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s14method_linkage9OpenClassC5pquuxyyF"
93105
public final func pquux() {
94106
}
107+
108+
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s14method_linkage9OpenClassC4prop{{.*}}LLytvg
109+
// RESILIENT: define hidden swiftcc void @"$s14method_linkage9OpenClassC4prop{{.*}}LLytvg
110+
fileprivate var prop: () {
111+
return ()
112+
}
113+
}
114+
115+
open class OpenSubclass : OpenClass {
116+
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s14method_linkage12OpenSubclassC4prop{{.*}}LLytvg
117+
// RESILIENT: define hidden swiftcc void @"$s14method_linkage12OpenSubclassC4prop{{.*}}LLytvg
118+
fileprivate final override var prop: () {
119+
return ()
120+
}
95121
}
96122

97123
// Just in case anyone wants to delete unused methods...
@@ -100,4 +126,5 @@ func callit(b: Base) {
100126
b.bar()
101127
b.other()
102128
b.extfunc()
129+
_ = b.prop
103130
}

0 commit comments

Comments
 (0)