[cfe-commits] r157435 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExprObjC.cpp lib/Sema/SemaPseudoObject.cpp test/SemaObjC/property-user-setter.m

Fariborz Jahanian fjahanian at apple.com
Thu May 24 15:48:38 PDT 2012


Author: fjahanian
Date: Thu May 24 17:48:38 2012
New Revision: 157435

URL: http://llvm.org/viewvc/llvm-project?rev=157435&view=rev
Log:
objective-c: warn on use of property setters
backing two propeties because proprty names
match except for first letter being of different
case. // rdar://11528439, [PR12936].

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/lib/Sema/SemaPseudoObject.cpp
    cfe/trunk/test/SemaObjC/property-user-setter.m

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=157435&r1=157434&r2=157435&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu May 24 17:48:38 2012
@@ -626,6 +626,10 @@
 def warn_property_getter_owning_mismatch : Warning<
   "property declared as returning non-retained objects"
   "; getter returning retained objects">;
+def warn_property_setter_ambiguous_use : Warning<
+  "synthesized properties '%0' and '%1' both claim setter %2 -"
+  " use of this setter may cause unexpected behavior">,
+  InGroup<DiagGroup<"objc-multiple-property-setter-use">>;
 def err_ownin_getter_rule : Error<
   "property's synthesized getter follows Cocoa naming"
   " convention for returning 'owned' objects">;

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=157435&r1=157434&r2=157435&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Thu May 24 17:48:38 2012
@@ -1415,8 +1415,7 @@
     return ExprError();
   
   // Search for a declared property first.
-  ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(Member);
-  if (PD) {
+  if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(Member)) {
     // Check whether we can reference this property.
     if (DiagnoseUseOfDecl(PD, MemberLoc))
       return ExprError();
@@ -1484,11 +1483,11 @@
     SelectorTable::constructSetterName(PP.getIdentifierTable(),
                                        PP.getSelectorTable(), Member);
   ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
-  // Check for corner case of: @property int p; ... self.P = 0;
-  // setter name is synthesized "setP" but there is no property name 'P'.
-  if (Setter && Setter->isSynthesized() && !PD)
+  if (Setter && Setter->isSynthesized())
+    // Check for corner case of: @property int p; ... self.P = 0;
+    // setter name is synthesized "setP" but there is no property name 'P'.
     Setter = 0;
-  
+      
   // May be founf in property's qualified list.
   if (!Setter)
     Setter = LookupMethodInQualifiedType(SetterSel, OPT, true);

Modified: cfe/trunk/lib/Sema/SemaPseudoObject.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaPseudoObject.cpp?rev=157435&r1=157434&r2=157435&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaPseudoObject.cpp (original)
+++ cfe/trunk/lib/Sema/SemaPseudoObject.cpp Thu May 24 17:48:38 2012
@@ -34,6 +34,7 @@
 #include "clang/Sema/Initialization.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/SmallString.h"
 
 using namespace clang;
 using namespace sema;
@@ -232,7 +233,7 @@
                                     Expr *op);
 
     bool tryBuildGetOfReference(Expr *op, ExprResult &result);
-    bool findSetter();
+    bool findSetter(bool warn=true);
     bool findGetter();
 
     Expr *rebuildAndCaptureObject(Expr *syntacticBase);
@@ -505,7 +506,7 @@
 /// reference.
 ///
 /// \return true if a setter was found, in which case Setter 
-bool ObjCPropertyOpBuilder::findSetter() {
+bool ObjCPropertyOpBuilder::findSetter(bool warn) {
   // For implicit properties, just trust the lookup we already did.
   if (RefExpr->isImplicitProperty()) {
     if (ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
@@ -531,6 +532,23 @@
   // Do a normal method lookup first.
   if (ObjCMethodDecl *setter =
         LookupMethodInReceiverType(S, SetterSelector, RefExpr)) {
+    if (setter->isSynthesized() && warn)
+      if (const ObjCInterfaceDecl *IFace =
+          dyn_cast<ObjCInterfaceDecl>(setter->getDeclContext())) {
+        const StringRef thisPropertyName(prop->getName());
+        char front = thisPropertyName.front();
+        front = islower(front) ? toupper(front) : tolower(front);
+        SmallString<100> PropertyName = thisPropertyName;
+        PropertyName[0] = front;
+        IdentifierInfo *AltMember = &S.PP.getIdentifierTable().get(PropertyName);
+        if (ObjCPropertyDecl *prop1 = IFace->FindPropertyDeclaration(AltMember))
+          if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
+            S.Diag(RefExpr->getExprLoc(), diag::warn_property_setter_ambiguous_use)
+              << prop->getName() << prop1->getName() << setter->getSelector();
+            S.Diag(prop->getLocation(), diag::note_property_declare);
+            S.Diag(prop1->getLocation(), diag::note_property_declare);
+          }
+      }
     Setter = setter;
     return true;
   }
@@ -603,7 +621,7 @@
 ///   value being set as the value of the property operation.
 ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
                                            bool captureSetValueAsResult) {
-  bool hasSetter = findSetter();
+  bool hasSetter = findSetter(false);
   assert(hasSetter); (void) hasSetter;
 
   if (SyntacticRefExpr)

Modified: cfe/trunk/test/SemaObjC/property-user-setter.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-user-setter.m?rev=157435&r1=157434&r2=157435&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/property-user-setter.m (original)
+++ cfe/trunk/test/SemaObjC/property-user-setter.m Thu May 24 17:48:38 2012
@@ -111,8 +111,10 @@
 @property (copy) id p;
 @property (copy) id r;
 @property (copy) id Q;
- at property (copy) id t;
- at property (copy) id T;
+ at property (copy) id t; // expected-note 2 {{property declared here}}
+ at property (copy) id T; // expected-note 2 {{property declared here}}
+ at property (copy) id Pxyz; // expected-note 2 {{property declared here}}
+ at property (copy) id pxyz; // expected-note 2 {{property declared here}}
 @end
 
 @implementation rdar11363363
@@ -120,11 +122,15 @@
 @synthesize r;
 @synthesize Q;
 @synthesize t, T;
+ at synthesize Pxyz, pxyz;
 - (id) Meth {
   self.P = 0; // expected-error {{property 'P' not found on object of type 'rdar11363363 *'}}
   self.q = 0; // expected-error {{property 'q' not found on object of type 'rdar11363363 *'}}
-  self.t = 0; // OK
-  self.T = 0; // OK
+// rdar://11528439
+  self.t = 0; // expected-warning {{synthesized properties 't' and 'T' both claim setter 'setT:'}}
+  self.T = 0; // expected-warning {{synthesized properties 'T' and 't' both claim setter 'setT:'}}
+  self.Pxyz = 0; // expected-warning {{synthesized properties 'Pxyz' and 'pxyz' both claim setter 'setPxyz:'}}
+  self.pxyz = 0; // expected-warning {{synthesized properties 'pxyz' and 'Pxyz' both claim setter 'setPxyz:'}}
   self.R = 0; // expected-error {{property 'R' not found on object of type 'rdar11363363 *'; did you mean to access ivar 'R'?}}
   return self.R; // expected-error {{property 'R' not found on object of type 'rdar11363363 *'; did you mean to access ivar 'R'?}}
 }





More information about the cfe-commits mailing list