Skip to content

Commit ad10379

Browse files
authored
Merge pull request #22990 from slavapestov/ctor-subclass-scope-5.0
SIL: Fix subclass scope calculation for constructors [5.0]
2 parents 7fde0a1 + 8187ce5 commit ad10379

File tree

3 files changed

+32
-13
lines changed

3 files changed

+32
-13
lines changed

lib/SIL/SILDeclRef.cpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -892,47 +892,62 @@ SubclassScope SILDeclRef::getSubclassScope() const {
892892
if (!hasDecl())
893893
return SubclassScope::NotApplicable;
894894

895+
auto *decl = getDecl();
896+
897+
if (!isa<AbstractFunctionDecl>(decl))
898+
return SubclassScope::NotApplicable;
899+
895900
// If this declaration is a function which goes into a vtable, then it's
896901
// symbol must be as visible as its class, because derived classes have to put
897902
// all less visible methods of the base class into their vtables.
898903

899-
if (auto *CD = dyn_cast<ConstructorDecl>(getDecl()))
900-
if (!CD->isRequired())
904+
if (auto *CD = dyn_cast<ConstructorDecl>(decl)) {
905+
// Initializing entry points do not appear in the vtable.
906+
if (kind == SILDeclRef::Kind::Initializer)
901907
return SubclassScope::NotApplicable;
902-
903-
auto *FD = dyn_cast<FuncDecl>(getDecl());
904-
if (!FD)
908+
// Non-required convenience inits do not apper in the vtable.
909+
if (!CD->isRequired() && !CD->isDesignatedInit())
910+
return SubclassScope::NotApplicable;
911+
} else if (isa<DestructorDecl>(decl)) {
912+
// Detructors do not appear in the vtable.
905913
return SubclassScope::NotApplicable;
914+
} else {
915+
assert(isa<FuncDecl>(decl));
916+
}
906917

907-
DeclContext *context = FD->getDeclContext();
918+
DeclContext *context = decl->getDeclContext();
908919

909-
// Methods from extensions don't go into vtables (yet).
920+
// Methods from extensions don't go in the vtable.
910921
if (isa<ExtensionDecl>(context))
911922
return SubclassScope::NotApplicable;
912923

913924
// Various forms of thunks don't either.
914925
if (isThunk() || isForeign)
915926
return SubclassScope::NotApplicable;
916927

917-
// Default arg generators are not visible.
928+
// Default arg generators don't go in the vtable.
918929
if (isDefaultArgGenerator())
919930
return SubclassScope::NotApplicable;
920931

932+
// Only non-final methods in non-final classes go in the vtable.
921933
auto *classType = context->getSelfClassDecl();
922934
if (!classType || classType->isFinal())
923935
return SubclassScope::NotApplicable;
924936

925-
if (FD->isFinal())
937+
if (decl->isFinal())
926938
return SubclassScope::NotApplicable;
927939

928-
assert(FD->getEffectiveAccess() <= classType->getEffectiveAccess() &&
940+
assert(decl->getEffectiveAccess() <= classType->getEffectiveAccess() &&
929941
"class must be as visible as its members");
930942

931943
// FIXME: This is too narrow. Any class with resilient metadata should
932944
// probably have this, at least for method overrides that don't add new
933945
// vtable entries.
934-
if (classType->isResilient())
946+
if (classType->isResilient()) {
947+
if (isa<ConstructorDecl>(decl))
948+
return SubclassScope::NotApplicable;
935949
return SubclassScope::Resilient;
950+
}
936951

937952
switch (classType->getEffectiveAccess()) {
938953
case AccessLevel::Private:

test/IRGen/Inputs/vtable_symbol_linkage_base.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ open class Base {
1111
internal var internalVar: Int = 30
1212
}
1313

14+
open class Middle : Base {
15+
public init(x: Int) {}
16+
}
1417

1518
public struct Namespace {
1619
open class Nested {

test/IRGen/vtable_symbol_linkage.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010

1111
import BaseModule
1212

13-
public class Derived : Base {
14-
}
13+
public class Derived : Base {}
14+
15+
public class MostDerived : Middle {}
1516

1617
public class DerivedNested : Namespace.Nested {}
1718
public class DerivedExtNested : Namespace.ExtNested {}

0 commit comments

Comments
 (0)