Sema: Infer 'dynamic' for overrides of imported methods

Fixes <rdar://problem/31104529>.
This commit is contained in:
Slava Pestov
2017-05-04 23:53:11 -07:00
parent cc707c76e1
commit bcbd1d28fe
3 changed files with 21 additions and 14 deletions

View File

@@ -2522,7 +2522,8 @@ static Optional<ObjCReason> shouldMarkAsObjC(TypeChecker &TC,
///
/// This occurs when
/// - it is implied by an attribute like @NSManaged
/// - we need to dynamically dispatch to a method in an extension.
/// - when we have an override of an imported method
/// - we need to dynamically dispatch to a method in an extension
///
/// FIXME: The latter reason is a hack. We should figure out how to safely
/// put extension methods into the class vtable.
@@ -2535,11 +2536,15 @@ static void inferDynamic(ASTContext &ctx, ValueDecl *D) {
if (!D->isObjC() || D->hasClangNode())
return;
bool overridesImportedMethod =
(D->getOverriddenDecl() &&
D->getOverriddenDecl()->hasClangNode());
// Only introduce 'dynamic' on declarations...
bool isNSManaged = D->getAttrs().hasAttribute<NSManagedAttr>();
if (!isa<ExtensionDecl>(D->getDeclContext())) {
// ...and in classes on decls marked @NSManaged.
if (!isNSManaged)
if (!isNSManaged && !overridesImportedMethod)
return;
}

View File

@@ -445,9 +445,9 @@ extension Hoozit {
// Calling objc methods of subclass should go through native entry points
func useHoozit(_ h: Hoozit) {
// sil @_T011objc_thunks9useHoozityAA0D0C1h_tF
// In the class decl, gets dynamically dispatched
// In the class decl, overrides importd method, 'dynamic' was inferred
h.fork()
// CHECK: class_method {{%.*}} : {{.*}}, #Hoozit.fork!1 :
// CHECK: class_method [volatile] {{%.*}} : {{.*}}, #Hoozit.fork!1.foreign
// In an extension, 'dynamic' was inferred.
h.foof()

View File

@@ -88,11 +88,12 @@ class Hoozit : Gizmo {
// Entries only exist for native Swift methods
// CHECK: sil_vtable Hoozit {
// CHECK: #Hoozit.frob!1: {{.*}} : _T07vtables6HoozitC4frob{{[_0-9a-zA-Z]*}}F
// CHECK: #Hoozit.funge!1: {{.*}} : _T07vtables6HoozitC5funge{{[_0-9a-zA-Z]*}}F
// CHECK: #Hoozit.anse!1: {{.*}} : _T07vtables6HoozitC4anse{{[_0-9a-zA-Z]*}}F
// CHECK: #Hoozit.incorrige!1: {{.*}} : _T07vtables6HoozitC9incorrige{{[_0-9a-zA-Z]*}}F
// CHECK: }
// CHECK-NEXT: #Hoozit.anse!1: {{.*}} : _T07vtables6HoozitC4anse{{[_0-9a-zA-Z]*}}F
// CHECK-NEXT: #Hoozit.incorrige!1: {{.*}} : _T07vtables6HoozitC9incorrige{{[_0-9a-zA-Z]*}}F
// CHECK-NEXT: #Hoozit.init!initializer.1: (Hoozit.Type) -> () -> Hoozit! : _T07vtables6HoozitCSQyACGycfc
// CHECK-NEXT: #Hoozit.init!initializer.1: (Hoozit.Type) -> (Int) -> Hoozit! : _T07vtables6HoozitCSQyACGSi7bellsOn_tcfc
// CHECK-NEXT: #Hoozit.deinit!deallocator: _T07vtables6HoozitCfD
// CHECK-NEXT: }
class Wotsit : Hoozit {
override func funge() {}
@@ -100,11 +101,12 @@ class Wotsit : Hoozit {
}
// CHECK: sil_vtable Wotsit {
// CHECK: #Hoozit.frob!1: {{.*}} : _T07vtables6HoozitC4frob{{[_0-9a-zA-Z]*}}F
// CHECK: #Hoozit.funge!1: {{.*}} : _T07vtables6WotsitC5funge{{[_0-9a-zA-Z]*}}F
// CHECK: #Hoozit.anse!1: {{.*}} : _T07vtables6HoozitC4anse{{[_0-9a-zA-Z]*}}F
// CHECK: #Hoozit.incorrige!1: {{.*}} : _T07vtables6WotsitC9incorrige{{[_0-9a-zA-Z]*}}F
// CHECK: }
// CHECK-NEXT: #Hoozit.anse!1: {{.*}} : _T07vtables6HoozitC4anse{{[_0-9a-zA-Z]*}}F
// CHECK-NEXT: #Hoozit.incorrige!1: {{.*}} : _T07vtables6WotsitC9incorrige{{[_0-9a-zA-Z]*}}F
// CHECK-NEXT: #Hoozit.init!initializer.1: (Hoozit.Type) -> () -> Hoozit! : _T07vtables6WotsitCSQyACGycfc
// CHECK-NEXT: #Hoozit.init!initializer.1: (Hoozit.Type) -> (Int) -> Hoozit! : _T07vtables6WotsitCSQyACGSi7bellsOn_tcfc
// CHECK-NEXT: #Wotsit.deinit!deallocator: _T07vtables6WotsitCfD
// CHECK-NEXT: }
// <rdar://problem/15282548>
// CHECK: sil_vtable Base {