From de329d141bcca35ba6b3feecf2453ad1b450a525 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 5 Dec 2013 20:52:31 +0000 Subject: [PATCH] ObjectiveC: Don't warn when method implemented in category is declared in category's primary class's super class. Because the super class is expected to implemented the method. // rdar://15580969 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196531 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDeclObjC.cpp | 34 +++++++++++++++-------- test/SemaObjC/incomplete-implementation.m | 26 +++++++++++++++++ 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 6020473e97..421b797c79 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1867,27 +1867,39 @@ void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap, /// warns each time an exact match is found. void Sema::CheckCategoryVsClassMethodMatches( ObjCCategoryImplDecl *CatIMPDecl) { + // Get category's primary class. + ObjCCategoryDecl *CatDecl = CatIMPDecl->getCategoryDecl(); + if (!CatDecl) + return; + ObjCInterfaceDecl *IDecl = CatDecl->getClassInterface(); + if (!IDecl) + return; + ObjCInterfaceDecl *SuperIDecl = IDecl->getSuperClass(); SelectorSet InsMap, ClsMap; for (ObjCImplementationDecl::instmeth_iterator I = CatIMPDecl->instmeth_begin(), - E = CatIMPDecl->instmeth_end(); I!=E; ++I) - InsMap.insert((*I)->getSelector()); + E = CatIMPDecl->instmeth_end(); I!=E; ++I) { + Selector Sel = (*I)->getSelector(); + // When checking for methods implemented in the category, skip over + // those declared in category class's super class. This is because + // the super class must implement the method. + if (SuperIDecl && SuperIDecl->lookupMethod(Sel, true)) + continue; + InsMap.insert(Sel); + } for (ObjCImplementationDecl::classmeth_iterator I = CatIMPDecl->classmeth_begin(), - E = CatIMPDecl->classmeth_end(); I != E; ++I) - ClsMap.insert((*I)->getSelector()); + E = CatIMPDecl->classmeth_end(); I != E; ++I) { + Selector Sel = (*I)->getSelector(); + if (SuperIDecl && SuperIDecl->lookupMethod(Sel, false)) + continue; + ClsMap.insert(Sel); + } if (InsMap.empty() && ClsMap.empty()) return; - // Get category's primary class. - ObjCCategoryDecl *CatDecl = CatIMPDecl->getCategoryDecl(); - if (!CatDecl) - return; - ObjCInterfaceDecl *IDecl = CatDecl->getClassInterface(); - if (!IDecl) - return; SelectorSet InsMapSeen, ClsMapSeen; bool IncompleteImpl = false; MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, diff --git a/test/SemaObjC/incomplete-implementation.m b/test/SemaObjC/incomplete-implementation.m index 4b8d600cb8..74dea2aa86 100644 --- a/test/SemaObjC/incomplete-implementation.m +++ b/test/SemaObjC/incomplete-implementation.m @@ -39,3 +39,29 @@ __attribute__((visibility("default"))) @end +// rdar://15580969 +typedef char BOOL; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +@end + +@interface NSObject +@end + +@protocol NSApplicationDelegate +- (void)ImpleThisMethod; // expected-note {{method 'ImpleThisMethod' declared here}} +@end + +@interface AppDelegate : NSObject +@end + +@implementation AppDelegate (MRRCategory) + +- (BOOL)isEqual:(id)object +{ + return __objc_no; +} + +- (void)ImpleThisMethod {} // expected-warning {{category is implementing a method which will also be implemented by its primary class}} +@end -- 2.40.0