r177662 - Objective-C: Tighten the rules when warning

Fariborz Jahanian fjahanian at apple.com
Thu Mar 21 13:50:53 PDT 2013


Author: fjahanian
Date: Thu Mar 21 15:50:53 2013
New Revision: 177662

URL: http://llvm.org/viewvc/llvm-project?rev=177662&view=rev
Log:
Objective-C: Tighten the rules when warning
is issused for on overriding 'readwrite'
property which is not auto-synthesized.
Buttom line is that if hueristics determine
that there will be a user implemented setter,
no warning will be issued. // rdar://13388503

Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/Sema/SemaObjCProperty.cpp
    cfe/trunk/test/SemaObjC/default-synthesize-3.m

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=177662&r1=177661&r2=177662&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Thu Mar 21 15:50:53 2013
@@ -544,6 +544,7 @@ public:
   ObjCMethodDecl *getClassMethod(Selector Sel) const {
     return getMethod(Sel, false/*isInstance*/);
   }
+  bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const;
   ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
 
   ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=177662&r1=177661&r2=177662&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Thu Mar 21 15:50:53 2013
@@ -92,6 +92,72 @@ ObjCContainerDecl::getMethod(Selector Se
   return 0;
 }
 
+/// HasUserDeclaredSetterMethod - This routine returns 'true' if a user declared setter
+/// method was found in the class, its protocols, its super classes or categories.
+/// It also returns 'true' if one of its categories has declared a 'readwrite' property.
+/// This is because, user must provide a setter method for the category's 'readwrite'
+/// property.
+bool
+ObjCContainerDecl::HasUserDeclaredSetterMethod(const ObjCPropertyDecl *Property) const {
+  Selector Sel = Property->getSetterName();
+  lookup_const_result R = lookup(Sel);
+  for (lookup_const_iterator Meth = R.begin(), MethEnd = R.end();
+       Meth != MethEnd; ++Meth) {
+    ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
+    if (MD && MD->isInstanceMethod() && !MD->isImplicit())
+      return true;
+  }
+
+  if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(this)) {
+    // Also look into categories, including class extensions, looking
+    // for a user declared instance method.
+    for (ObjCInterfaceDecl::visible_categories_iterator
+         Cat = ID->visible_categories_begin(),
+         CatEnd = ID->visible_categories_end();
+         Cat != CatEnd;
+         ++Cat) {
+      if (ObjCMethodDecl *MD = Cat->getInstanceMethod(Sel))
+        if (!MD->isImplicit())
+          return true;
+      if (Cat->IsClassExtension())
+        continue;
+      // Also search through the categories looking for a 'readwrite' declaration
+      // of this property. If one found, presumably a setter will be provided
+      // (properties declared in categories will not get auto-synthesized).
+      for (ObjCContainerDecl::prop_iterator P = Cat->prop_begin(),
+           E = Cat->prop_end(); P != E; ++P)
+        if (P->getIdentifier() == Property->getIdentifier()) {
+          if (P->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite)
+            return true;
+          break;
+        }
+    }
+    
+    // Also look into protocols, for a user declared instance method.
+    for (ObjCInterfaceDecl::all_protocol_iterator P =
+         ID->all_referenced_protocol_begin(),
+         PE = ID->all_referenced_protocol_end(); P != PE; ++P) {
+      ObjCProtocolDecl *Proto = (*P);
+      if (Proto->HasUserDeclaredSetterMethod(Property))
+        return true;
+    }
+    // And in its super class.
+    ObjCInterfaceDecl *OSC = ID->getSuperClass();
+    while (OSC) {
+      if (OSC->HasUserDeclaredSetterMethod(Property))
+        return true;
+      OSC = OSC->getSuperClass();
+    }
+  }
+  if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(this))
+    for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
+         E = PD->protocol_end(); PI != E; ++PI) {
+      if ((*PI)->HasUserDeclaredSetterMethod(Property))
+        return true;
+    }
+  return false;
+}
+
 ObjCPropertyDecl *
 ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
                                    IdentifierInfo *propertyID) {

Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=177662&r1=177661&r2=177662&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Thu Mar 21 15:50:53 2013
@@ -1590,7 +1590,8 @@ void Sema::DefaultSynthesizeProperties(S
       if ((Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite) &&
           (PropInSuperClass->getPropertyAttributes() &
            ObjCPropertyDecl::OBJC_PR_readonly) &&
-          !IMPDecl->getInstanceMethod(Prop->getSetterName())) {
+          !IMPDecl->getInstanceMethod(Prop->getSetterName()) &&
+          !IDecl->HasUserDeclaredSetterMethod(Prop)) {
             Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property)
               << Prop->getIdentifier()->getName();
             Diag(PropInSuperClass->getLocation(), diag::note_property_declare);

Modified: cfe/trunk/test/SemaObjC/default-synthesize-3.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/default-synthesize-3.m?rev=177662&r1=177661&r2=177662&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/default-synthesize-3.m (original)
+++ cfe/trunk/test/SemaObjC/default-synthesize-3.m Thu Mar 21 15:50:53 2013
@@ -80,3 +80,34 @@ __attribute ((objc_requires_property_def
 }
 
 @end
+
+// More test where such warnings should not be issued.
+ at protocol MyProtocol
+-(void)setProp1:(id)x;
+ at end
+
+ at protocol P1 <MyProtocol>
+ at end
+
+ at interface B
+ at property (readonly) id prop;
+ at property (readonly) id prop1;
+ at property (readonly) id prop2;
+ at end
+
+ at interface B()
+-(void)setProp:(id)x;
+ at end
+
+ at interface B(cat)
+ at property (readwrite) id prop2;
+ at end
+
+ at interface S : B<P1>
+ at property (assign,readwrite) id prop;
+ at property (assign,readwrite) id prop1;
+ at property (assign,readwrite) id prop2;
+ at end
+
+ at implementation S
+ at end





More information about the cfe-commits mailing list