r297862 - [ObjC][Sema] Avoid warning about a call to an instance method on an
Alex Lorenz via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 15 10:16:41 PDT 2017
Author: arphaman
Date: Wed Mar 15 12:16:41 2017
New Revision: 297862
URL: http://llvm.org/viewvc/llvm-project?rev=297862&view=rev
Log:
[ObjC][Sema] Avoid warning about a call to an instance method on an
instance of a qualified Class object when that instance method comes from
a protocol that's implemented by NSObject
Instance methods from a root class like NSObject are also class methods because
the metaclass of root class derives from that root class. Therefore, we can
avoid the warning for instances of qualified Class objects that point to classes
that derive from NSObject. Note that we actually don't know if a Class instance
points to a class that derives from NSObject at compile-time, so we have to
make a reasonable assumption that the majority of instances will do so.
rdar://22812517
Modified:
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/test/SemaObjC/class-message-protocol-lookup.m
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=297862&r1=297861&r2=297862&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Wed Mar 15 12:16:41 2017
@@ -2556,6 +2556,24 @@ ExprResult Sema::BuildInstanceMessageImp
/*isImplicit=*/true);
}
+static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M) {
+ if (!S.NSAPIObj)
+ return false;
+ const auto *Protocol = dyn_cast<ObjCProtocolDecl>(M->getDeclContext());
+ if (!Protocol)
+ return false;
+ const IdentifierInfo *II = S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject);
+ if (const auto *RootClass = dyn_cast_or_null<ObjCInterfaceDecl>(
+ S.LookupSingleName(S.TUScope, II, Protocol->getLocStart(),
+ Sema::LookupOrdinaryName))) {
+ for (const ObjCProtocolDecl *P : RootClass->all_referenced_protocols()) {
+ if (P->getCanonicalDecl() == Protocol->getCanonicalDecl())
+ return true;
+ }
+ }
+ return false;
+}
+
/// \brief Build an Objective-C instance message expression.
///
/// This routine takes care of both normal instance messages and
@@ -2731,7 +2749,7 @@ ExprResult Sema::BuildInstanceMessage(Ex
if (!Method) {
Method = LookupMethodInQualifiedType(Sel, QClassTy, true);
// warn if instance method found for a Class message.
- if (Method) {
+ if (Method && !isMethodDeclaredInRootProtocol(*this, Method)) {
Diag(SelLoc, diag::warn_instance_method_on_class_found)
<< Method->getSelector() << Sel;
Diag(Method->getLocation(), diag::note_method_declared_at)
Modified: cfe/trunk/test/SemaObjC/class-message-protocol-lookup.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/class-message-protocol-lookup.m?rev=297862&r1=297861&r2=297862&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/class-message-protocol-lookup.m (original)
+++ cfe/trunk/test/SemaObjC/class-message-protocol-lookup.m Wed Mar 15 12:16:41 2017
@@ -32,3 +32,30 @@ int main ()
Class<Test2Protocol> c2 = [c2 alloc]; // ok
return 0;
}
+
+// rdar://22812517
+
+ at protocol NSObject
+
+- (int)respondsToSelector:(SEL)aSelector;
+
+ at end
+
+__attribute__((objc_root_class))
+ at interface NSObject <NSObject>
+
+ at end
+
+ at protocol OtherProto
+
+- (void)otherInstanceMethod; // expected-note {{method 'otherInstanceMethod' declared here}}
+
+ at end
+
+ at protocol MyProto <NSObject, OtherProto>
+ at end
+
+void allowInstanceMethodsFromRootProtocols(Class<MyProto> c) {
+ [c respondsToSelector: @selector(instanceMethod)]; // no warning
+ [c otherInstanceMethod]; // expected-warning {{instance method 'otherInstanceMethod' found instead of class method 'otherInstanceMethod'}}
+}
More information about the cfe-commits
mailing list