]> granicus.if.org Git - clang/commitdiff
ObjectiveC. Remove false positive warning for missing property
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 2 Jan 2014 22:42:09 +0000 (22:42 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 2 Jan 2014 22:42:09 +0000 (22:42 +0000)
backing ivar by not issuing this warning if ivar is referenced
somewhere and accessor makes method calls. // rdar://15727325

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@198367 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclObjC.h
lib/Sema/SemaDeclObjC.cpp
lib/Sema/SemaExprObjC.cpp
lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTWriterDecl.cpp
test/SemaObjC/unused-backing-ivar-warning.m [moved from test/SemaObjC/unsued-backing-ivar-warning.m with 77% similarity]

index 5ac82ecfc12ebb28920343171a8ef1d486b3f2dc..51bdfe2e6ada7393208674b2e3e0add074926c03 100644 (file)
@@ -161,6 +161,9 @@ private:
 
   /// \brief Indicates if the method was a definition but its body was skipped.
   unsigned HasSkippedBody : 1;
+  
+  /// \brief True if method body makes a method call.
+  unsigned MethodCallsMethod : 1;
 
   // Result type of this method.
   QualType MethodDeclType;
@@ -242,7 +245,7 @@ private:
     DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
     RelatedResultType(HasRelatedResultType),
     SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
-    MethodDeclType(T), ResultTInfo(ResultTInfo),
+    MethodCallsMethod(0), MethodDeclType(T), ResultTInfo(ResultTInfo),
     ParamsAndSelLocs(0), NumParams(0),
     DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) {
     setImplicit(isImplicitlyDeclared);
@@ -436,6 +439,9 @@ public:
   bool hasSkippedBody() const { return HasSkippedBody; }
   void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
 
+  bool getMethodCallsMethod() const { return MethodCallsMethod; }
+  void setMethodCallsMethod(bool val = true) { MethodCallsMethod = val; }
+
   /// \brief Returns the property associated with this method's selector.
   ///
   /// Note that even if this particular method is not marked as a property
index 7024cf6cb354220e41deda422eecb83e0c9b8b7e..edbd714184433a9472e1a0bca9a58a861242f968 100644 (file)
@@ -3521,8 +3521,13 @@ void Sema::DiagnoseUnusedBackingIvarInAccessor(Scope *S) {
   const ObjCPropertyDecl *PDecl;
   const ObjCIvarDecl *IV = GetIvarBackingPropertyAccessor(CurMethod, PDecl);
   if (IV && !IV->getBackingIvarReferencedInAccessor()) {
-    Diag(getCurMethodDecl()->getLocation(), diag::warn_unused_property_backing_ivar)
-    << IV->getDeclName();
-    Diag(PDecl->getLocation(), diag::note_property_declare);
+    // Do not issue this warning if backing ivar is used somewhere and accessor
+    // implementation makes a call to a method. This is to prevent false positive in
+    // some corner cases.
+    if (!IV->isReferenced() || !CurMethod->getMethodCallsMethod()) {
+      Diag(getCurMethodDecl()->getLocation(), diag::warn_unused_property_backing_ivar)
+        << IV->getDeclName();
+      Diag(PDecl->getLocation(), diag::note_property_declare);
+    }
   }
 }
index ca67094f80f26a7971aeb39732bfe209179cab58..8b1befe4f85b0fee9d0a365d828ba82b0c77ee88 100644 (file)
@@ -2643,7 +2643,9 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
       }
     }
   }
-      
+  if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
+    CurMeth->setMethodCallsMethod(true);
+  
   return MaybeBindToTemporary(Result);
 }
 
index c2e286814bcabb699258f379b35f5dacda78c7c8..9f10c607bae6279e5ece97f25026f783ac06ae6f 100644 (file)
@@ -702,6 +702,7 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
   MD->setDefined(Record[Idx++]);
   MD->IsOverriding = Record[Idx++];
   MD->HasSkippedBody = Record[Idx++];
+  MD->MethodCallsMethod = Record[Idx++];
 
   MD->IsRedeclaration = Record[Idx++];
   MD->HasRedeclaration = Record[Idx++];
index 56ed503e840e0e0b0d1af4b1efd9107008feff2d..604ce5675127818c6ef023c4c37535359022301e 100644 (file)
@@ -438,6 +438,7 @@ void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
   Record.push_back(D->isDefined());
   Record.push_back(D->IsOverriding);
   Record.push_back(D->HasSkippedBody);
+  Record.push_back(D->MethodCallsMethod);
 
   Record.push_back(D->IsRedeclaration);
   Record.push_back(D->HasRedeclaration);
similarity index 77%
rename from test/SemaObjC/unsued-backing-ivar-warning.m
rename to test/SemaObjC/unused-backing-ivar-warning.m
index 9861d5048f701a84364d6aac04a2a6cd35b002c0..d07e52df776677ee4f1d703507f8114adf8fef11 100644 (file)
@@ -104,3 +104,23 @@ typedef char BOOL;
     return 0;
 }
 @end
+
+// rdar://15727327
+@interface Radar15727327 : NSObject
+@property (assign, readonly) long p;
+@property (assign) long q; // expected-note 2 {{property declared here}}
+@property (assign, readonly) long r; // expected-note {{property declared here}}
+- (long)Meth;
+@end
+
+@implementation Radar15727327
+@synthesize p;
+@synthesize q;
+@synthesize r;
+- (long)Meth { return p; }
+- (long) p { [self Meth]; return 0;  }
+- (long) q { return 0; } // expected-warning {{ivar 'q' which backs the property is not referenced in this property's accessor}}
+- (void) setQ : (long) val { } // expected-warning {{ivar 'q' which backs the property is not referenced in this property's accessor}}
+- (long) r { [self Meth]; return p; } // expected-warning {{ivar 'r' which backs the property is not referenced in this property's accessor}}
+@end
+