Author: mren Date: Wed May 18 13:12:34 2016 New Revision: 269968 URL: http://llvm.org/viewvc/llvm-project?rev=269968&view=rev Log: ObjectiveC Class Properties: warn if a class property accessor is mistakenly an instance method.
When diagnosing unimplemented class property, make sure we emit a warning when we only see an instance method with the right selector. Also warn when we only see a class method for an instance property. rdar://26141719 Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp cfe/trunk/test/SemaObjC/objc-class-property.m Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=269968&r1=269967&r2=269968&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original) +++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Wed May 18 13:12:34 2016 @@ -1763,19 +1763,23 @@ void Sema::DefaultSynthesizeProperties(S DefaultSynthesizeProperties(S, IC, IDecl); } -static void DiagnoseUnimplementedAccessor(Sema &S, - ObjCInterfaceDecl *PrimaryClass, - Selector Method, - ObjCImplDecl* IMPDecl, - ObjCContainerDecl *CDecl, - ObjCCategoryDecl *C, - ObjCPropertyDecl *Prop, - Sema::SelectorSet &SMap) { +static void DiagnoseUnimplementedAccessor( + Sema &S, ObjCInterfaceDecl *PrimaryClass, Selector Method, + ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, ObjCCategoryDecl *C, + ObjCPropertyDecl *Prop, + llvm::SmallPtrSet<const ObjCMethodDecl *, 8> &SMap) { + // Check to see if we have a corresponding selector in SMap and with the + // right method type. + auto I = std::find_if(SMap.begin(), SMap.end(), + [&](const ObjCMethodDecl *x) { + return x->getSelector() == Method && + x->isClassMethod() == Prop->isClassProperty(); + }); // When reporting on missing property setter/getter implementation in // categories, do not report when they are declared in primary class, // class's protocol, or one of it super classes. This is because, // the class is going to implement them. - if (!SMap.count(Method) && + if (I == SMap.end() && (PrimaryClass == nullptr || !PrimaryClass->lookupPropertyAccessor(Method, C, Prop->isClassProperty()))) { @@ -1867,10 +1871,10 @@ void Sema::DiagnoseUnimplementedProperti for (const auto *I : IMPDecl->property_impls()) PropImplMap.insert(I->getPropertyDecl()); - SelectorSet InsMap; + llvm::SmallPtrSet<const ObjCMethodDecl *, 8> InsMap; // Collect property accessors implemented in current implementation. for (const auto *I : IMPDecl->methods()) - InsMap.insert(I->getSelector()); + InsMap.insert(I); ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl); ObjCInterfaceDecl *PrimaryClass = nullptr; @@ -1882,7 +1886,7 @@ void Sema::DiagnoseUnimplementedProperti // setter/getter is implemented in category's primary class // implementation. for (const auto *I : IMP->methods()) - InsMap.insert(I->getSelector()); + InsMap.insert(I); } for (ObjCContainerDecl::PropertyMap::iterator Modified: cfe/trunk/test/SemaObjC/objc-class-property.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-class-property.m?rev=269968&r1=269967&r2=269968&view=diff ============================================================================== --- cfe/trunk/test/SemaObjC/objc-class-property.m (original) +++ cfe/trunk/test/SemaObjC/objc-class-property.m Wed May 18 13:12:34 2016 @@ -43,3 +43,16 @@ void message_id(id me) { void message_class(Class me) { [me c2]; } + +@interface NSObject +@end + +@interface MyClass : NSObject +@property(class, readonly) int classProp; // expected-note {{property declared here}} +@end + +@implementation MyClass // expected-warning {{class property 'classProp' requires method 'classProp' to be defined}} +- (int)classProp { // Oops, mistakenly made this an instance method. + return 8; +} +@end _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits