]> granicus.if.org Git - clang/commitdiff
Objective-C. Patch to warn if the result of calling a property getter
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 18 Jul 2014 22:59:10 +0000 (22:59 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 18 Jul 2014 22:59:10 +0000 (22:59 +0000)
is unused (this is match behavior when property-dot syntax is used to
use same getter). rdar://17514245
Patch by Anders Carlsson with minor refactoring by me.

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

lib/AST/Expr.cpp
lib/Sema/SemaStmt.cpp
test/SemaObjC/class-property-access.m
test/SemaObjC/conditional-expr.m
test/SemaObjC/property-noninherited-availability-attr.m
test/SemaObjC/unused.m

index 0cc046c6d24fe469c42cd43817e489a273221b2a..5f559b7e5ce30a852f3c1869bb5d06be1390516d 100644 (file)
@@ -2161,12 +2161,15 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
       return true;
     }
 
-    const ObjCMethodDecl *MD = ME->getMethodDecl();
-    if (MD && MD->hasAttr<WarnUnusedResultAttr>()) {
-      WarnE = this;
-      Loc = getExprLoc();
-      return true;
-    }
+    if (const ObjCMethodDecl *MD = ME->getMethodDecl())
+      if (MD->hasAttr<WarnUnusedResultAttr>() ||
+          (MD->isPropertyAccessor() && !MD->getReturnType()->isVoidType() &&
+           !ME->getReceiverType()->isObjCIdType())) {
+        WarnE = this;
+        Loc = getExprLoc();
+        return true;
+      }
+
     return false;
   }
 
index dc5619db9a468efd99af82ed0d624ea1c2b91d19..1ddb3694cbeba1bf8038f143e56ca822a5e8f998 100644 (file)
@@ -253,9 +253,15 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
       return;
     }
     const ObjCMethodDecl *MD = ME->getMethodDecl();
-    if (MD && MD->hasAttr<WarnUnusedResultAttr>()) {
-      Diag(Loc, diag::warn_unused_result) << R1 << R2;
-      return;
+    if (MD) {
+      if (MD->hasAttr<WarnUnusedResultAttr>()) {
+        Diag(Loc, diag::warn_unused_result) << R1 << R2;
+        return;
+      }
+      if (MD->isPropertyAccessor()) {
+        Diag(Loc, diag::warn_unused_property_expr);
+        return;
+      }
     }
   } else if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
     const Expr *Source = POE->getSyntacticForm();
index a4c188c434ec2211a5882d7c59c996618d0b032d..d57b986c3eac6cee0c2e2e7e821dd9cd35381395 100644 (file)
@@ -41,8 +41,8 @@ void Test1() {
     (void)Subclass.classMethod;
 
     // also okay
-    [RootClass property];
-    [Subclass property];
+    (void)[RootClass property];
+    (void)[Subclass property];
     [RootClass method];
     [Subclass method];
     [RootClass classMethod];
index 049a095ce37ca0a1b770f0dcbb63c0466ba38d08..d8862c584a0dfe7c72541fa47433beec34cba45e 100644 (file)
@@ -96,8 +96,8 @@ id f7(int a, id<P0> x, A* p) {
   return a ? x : p;
 }
 
-void f8(int a, A<P0> *x, A *y) {
-  [ (a ? x : y ) intProp ];
+int f8(int a, A<P0> *x, A *y) {
+  return [ (a ? x : y ) intProp ];
 }
 
 void f9(int a, A<P0> *x, A<P1> *y) {
index 793ceb6dc08e44d989e798e36cf53efb2cb16a34..dfa72d1077efb1ee265930b5d70aebc3f1760348 100644 (file)
 
 void test(Foo *y, Bar *x, id<myProtocol> z) {
   y.myProperty = 0; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}}
-  [y myProperty];   // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}} 
+  (void)[y myProperty];   // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}} 
 
   x.myProperty = 1; // no-warning
-  [x myProperty]; // no-warning
+  (void)[x myProperty]; // no-warning
 
   x.myProtocolProperty = 0; // no-warning
 
-  [x myProtocolProperty]; // no-warning
-  [z myProtocolProperty]; // expected-warning {{'myProtocolProperty' is deprecated: first deprecated in OS X 10.8}}
+  (void)[x myProtocolProperty]; // no-warning
+  (void)[z myProtocolProperty]; // expected-warning {{'myProtocolProperty' is deprecated: first deprecated in OS X 10.8}}
 }
index 16a38995ffd9361a06e61369825bec43ba761aa2..6ea3fe8e00ab3ef9490dd4d54593ae58e239d096 100644 (file)
@@ -81,3 +81,26 @@ void rdar15596883(id x) {
   rdar15596883_foo();
 }
 
+@interface PropertyObject : NSObject 
+@property int length;
+@end
+
+@protocol P
+@property int property;
+@end
+
+void test3(PropertyObject *o)
+{
+  [o length]; // expected-warning {{property access result unused - getters should not be used for side effects}}
+  (void)[o length];
+}
+
+void test4(id o)
+{
+  [o length]; // No warning.
+}
+
+void test5(id <P> p)
+{
+    [p property]; // expected-warning {{property access result unused - getters should not be used for side effects}}
+}