arphaman created this revision.
arphaman added a reviewer: erik.pilkington.
Herald added subscribers: cfe-commits, dexonsmith, jkorous.

This patch extends r350768 and allows the use of methods marked as 
`unavailable` that are declared in a parent class/category from within the 
`@implementation` of the class where the method is marked as `unavailable`.
This allows users to call `init` that's marked as `unavailable` even if they 
don't define it.


Repository:
  rC Clang

https://reviews.llvm.org/D56816

Files:
  lib/Sema/SemaDeclAttr.cpp
  test/SemaObjC/call-unavailable-init-in-self.m


Index: test/SemaObjC/call-unavailable-init-in-self.m
===================================================================
--- test/SemaObjC/call-unavailable-init-in-self.m
+++ test/SemaObjC/call-unavailable-init-in-self.m
@@ -5,6 +5,14 @@
 + (instancetype)new;
 + (instancetype)alloc;
 
+- (void)declaredInSuper;
+
+@end
+
+@interface NSObject (Category)
+
+- (void)declaredInSuperCategory;
+
 @end
 
 @interface Sub: NSObject
@@ -13,6 +21,9 @@
 
 - (void)notImplemented __attribute__((unavailable)); // expected-note 
{{'notImplemented' has been explicitly marked unavailable here}}
 
+- (void)declaredInSuper __attribute__((unavailable));
+- (void)declaredInSuperCategory __attribute__((unavailable));
+
 @end
 
 @implementation Sub
@@ -37,6 +48,13 @@
   [self notImplemented]; // expected-error {{'notImplemented' is unavailable}}
 }
 
+- (void)allowSuperCallUsingSelf {
+  [self declaredInSuper];
+  [[Sub alloc] declaredInSuper];
+  [self declaredInSuperCategory];
+  [[Sub alloc] declaredInSuperCategory];
+}
+
 @end
 
 @interface SubClassContext: Sub
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -7371,7 +7371,11 @@
       if (const auto *MD = dyn_cast<ObjCMethodDecl>(OffendingDecl)) {
         if (const auto *Impl = dyn_cast<ObjCImplDecl>(C)) {
           if (MD->getClassInterface() == Impl->getClassInterface() &&
-              MD->isDefined())
+              (MD->isDefined() ||
+               (MD->getClassInterface() &&
+                MD->getClassInterface()->getSuperClass() &&
+                MD->getClassInterface()->getSuperClass()->lookupMethod(
+                    MD->getSelector(), MD->isInstanceMethod()))))
             return true;
         }
       }


Index: test/SemaObjC/call-unavailable-init-in-self.m
===================================================================
--- test/SemaObjC/call-unavailable-init-in-self.m
+++ test/SemaObjC/call-unavailable-init-in-self.m
@@ -5,6 +5,14 @@
 + (instancetype)new;
 + (instancetype)alloc;
 
+- (void)declaredInSuper;
+
+@end
+
+@interface NSObject (Category)
+
+- (void)declaredInSuperCategory;
+
 @end
 
 @interface Sub: NSObject
@@ -13,6 +21,9 @@
 
 - (void)notImplemented __attribute__((unavailable)); // expected-note {{'notImplemented' has been explicitly marked unavailable here}}
 
+- (void)declaredInSuper __attribute__((unavailable));
+- (void)declaredInSuperCategory __attribute__((unavailable));
+
 @end
 
 @implementation Sub
@@ -37,6 +48,13 @@
   [self notImplemented]; // expected-error {{'notImplemented' is unavailable}}
 }
 
+- (void)allowSuperCallUsingSelf {
+  [self declaredInSuper];
+  [[Sub alloc] declaredInSuper];
+  [self declaredInSuperCategory];
+  [[Sub alloc] declaredInSuperCategory];
+}
+
 @end
 
 @interface SubClassContext: Sub
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -7371,7 +7371,11 @@
       if (const auto *MD = dyn_cast<ObjCMethodDecl>(OffendingDecl)) {
         if (const auto *Impl = dyn_cast<ObjCImplDecl>(C)) {
           if (MD->getClassInterface() == Impl->getClassInterface() &&
-              MD->isDefined())
+              (MD->isDefined() ||
+               (MD->getClassInterface() &&
+                MD->getClassInterface()->getSuperClass() &&
+                MD->getClassInterface()->getSuperClass()->lookupMethod(
+                    MD->getSelector(), MD->isInstanceMethod()))))
             return true;
         }
       }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to