mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Infer 'dynamic' for overrides of imported methods
Fixes <rdar://problem/31104529>.
This commit is contained in:
@@ -2522,7 +2522,8 @@ static Optional<ObjCReason> shouldMarkAsObjC(TypeChecker &TC,
|
|||||||
///
|
///
|
||||||
/// This occurs when
|
/// This occurs when
|
||||||
/// - it is implied by an attribute like @NSManaged
|
/// - 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
|
/// FIXME: The latter reason is a hack. We should figure out how to safely
|
||||||
/// put extension methods into the class vtable.
|
/// put extension methods into the class vtable.
|
||||||
@@ -2535,11 +2536,15 @@ static void inferDynamic(ASTContext &ctx, ValueDecl *D) {
|
|||||||
if (!D->isObjC() || D->hasClangNode())
|
if (!D->isObjC() || D->hasClangNode())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bool overridesImportedMethod =
|
||||||
|
(D->getOverriddenDecl() &&
|
||||||
|
D->getOverriddenDecl()->hasClangNode());
|
||||||
|
|
||||||
// Only introduce 'dynamic' on declarations...
|
// Only introduce 'dynamic' on declarations...
|
||||||
bool isNSManaged = D->getAttrs().hasAttribute<NSManagedAttr>();
|
bool isNSManaged = D->getAttrs().hasAttribute<NSManagedAttr>();
|
||||||
if (!isa<ExtensionDecl>(D->getDeclContext())) {
|
if (!isa<ExtensionDecl>(D->getDeclContext())) {
|
||||||
// ...and in classes on decls marked @NSManaged.
|
// ...and in classes on decls marked @NSManaged.
|
||||||
if (!isNSManaged)
|
if (!isNSManaged && !overridesImportedMethod)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -445,9 +445,9 @@ extension Hoozit {
|
|||||||
// Calling objc methods of subclass should go through native entry points
|
// Calling objc methods of subclass should go through native entry points
|
||||||
func useHoozit(_ h: Hoozit) {
|
func useHoozit(_ h: Hoozit) {
|
||||||
// sil @_T011objc_thunks9useHoozityAA0D0C1h_tF
|
// sil @_T011objc_thunks9useHoozityAA0D0C1h_tF
|
||||||
// In the class decl, gets dynamically dispatched
|
// In the class decl, overrides importd method, 'dynamic' was inferred
|
||||||
h.fork()
|
h.fork()
|
||||||
// CHECK: class_method {{%.*}} : {{.*}}, #Hoozit.fork!1 :
|
// CHECK: class_method [volatile] {{%.*}} : {{.*}}, #Hoozit.fork!1.foreign
|
||||||
|
|
||||||
// In an extension, 'dynamic' was inferred.
|
// In an extension, 'dynamic' was inferred.
|
||||||
h.foof()
|
h.foof()
|
||||||
|
|||||||
@@ -88,11 +88,12 @@ class Hoozit : Gizmo {
|
|||||||
// Entries only exist for native Swift methods
|
// Entries only exist for native Swift methods
|
||||||
|
|
||||||
// CHECK: sil_vtable Hoozit {
|
// CHECK: sil_vtable Hoozit {
|
||||||
// CHECK: #Hoozit.frob!1: {{.*}} : _T07vtables6HoozitC4frob{{[_0-9a-zA-Z]*}}F
|
// CHECK-NEXT: #Hoozit.anse!1: {{.*}} : _T07vtables6HoozitC4anse{{[_0-9a-zA-Z]*}}F
|
||||||
// CHECK: #Hoozit.funge!1: {{.*}} : _T07vtables6HoozitC5funge{{[_0-9a-zA-Z]*}}F
|
// CHECK-NEXT: #Hoozit.incorrige!1: {{.*}} : _T07vtables6HoozitC9incorrige{{[_0-9a-zA-Z]*}}F
|
||||||
// CHECK: #Hoozit.anse!1: {{.*}} : _T07vtables6HoozitC4anse{{[_0-9a-zA-Z]*}}F
|
// CHECK-NEXT: #Hoozit.init!initializer.1: (Hoozit.Type) -> () -> Hoozit! : _T07vtables6HoozitCSQyACGycfc
|
||||||
// CHECK: #Hoozit.incorrige!1: {{.*}} : _T07vtables6HoozitC9incorrige{{[_0-9a-zA-Z]*}}F
|
// CHECK-NEXT: #Hoozit.init!initializer.1: (Hoozit.Type) -> (Int) -> Hoozit! : _T07vtables6HoozitCSQyACGSi7bellsOn_tcfc
|
||||||
// CHECK: }
|
// CHECK-NEXT: #Hoozit.deinit!deallocator: _T07vtables6HoozitCfD
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
|
||||||
class Wotsit : Hoozit {
|
class Wotsit : Hoozit {
|
||||||
override func funge() {}
|
override func funge() {}
|
||||||
@@ -100,11 +101,12 @@ class Wotsit : Hoozit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK: sil_vtable Wotsit {
|
// CHECK: sil_vtable Wotsit {
|
||||||
// CHECK: #Hoozit.frob!1: {{.*}} : _T07vtables6HoozitC4frob{{[_0-9a-zA-Z]*}}F
|
// CHECK-NEXT: #Hoozit.anse!1: {{.*}} : _T07vtables6HoozitC4anse{{[_0-9a-zA-Z]*}}F
|
||||||
// CHECK: #Hoozit.funge!1: {{.*}} : _T07vtables6WotsitC5funge{{[_0-9a-zA-Z]*}}F
|
// CHECK-NEXT: #Hoozit.incorrige!1: {{.*}} : _T07vtables6WotsitC9incorrige{{[_0-9a-zA-Z]*}}F
|
||||||
// CHECK: #Hoozit.anse!1: {{.*}} : _T07vtables6HoozitC4anse{{[_0-9a-zA-Z]*}}F
|
// CHECK-NEXT: #Hoozit.init!initializer.1: (Hoozit.Type) -> () -> Hoozit! : _T07vtables6WotsitCSQyACGycfc
|
||||||
// CHECK: #Hoozit.incorrige!1: {{.*}} : _T07vtables6WotsitC9incorrige{{[_0-9a-zA-Z]*}}F
|
// CHECK-NEXT: #Hoozit.init!initializer.1: (Hoozit.Type) -> (Int) -> Hoozit! : _T07vtables6WotsitCSQyACGSi7bellsOn_tcfc
|
||||||
// CHECK: }
|
// CHECK-NEXT: #Wotsit.deinit!deallocator: _T07vtables6WotsitCfD
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
|
||||||
// <rdar://problem/15282548>
|
// <rdar://problem/15282548>
|
||||||
// CHECK: sil_vtable Base {
|
// CHECK: sil_vtable Base {
|
||||||
|
|||||||
Reference in New Issue
Block a user