diff options
| -rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 34 | ||||
| -rw-r--r-- | clang/test/SemaObjC/incomplete-implementation.m | 26 |
2 files changed, 49 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 6020473e979..421b797c794 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/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/clang/test/SemaObjC/incomplete-implementation.m b/clang/test/SemaObjC/incomplete-implementation.m index 4b8d600cb8b..74dea2aa86b 100644 --- a/clang/test/SemaObjC/incomplete-implementation.m +++ b/clang/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 <NSObject> +@end + +@protocol NSApplicationDelegate <NSObject> +- (void)ImpleThisMethod; // expected-note {{method 'ImpleThisMethod' declared here}} +@end + +@interface AppDelegate : NSObject <NSApplicationDelegate> +@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 |

