From ac6b4efaab360171a5872f991913d1dc5a97e1ca Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 18 Jul 2014 22:59:10 +0000 Subject: [PATCH] Objective-C. Patch to warn if the result of calling a property getter 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. llvm-svn: 213423 --- clang/lib/AST/Expr.cpp | 15 ++++++++------ clang/lib/Sema/SemaStmt.cpp | 12 ++++++++--- clang/test/SemaObjC/class-property-access.m | 4 ++-- clang/test/SemaObjC/conditional-expr.m | 4 ++-- .../property-noninherited-availability-attr.m | 8 ++++---- clang/test/SemaObjC/unused.m | 23 ++++++++++++++++++++++ 6 files changed, 49 insertions(+), 17 deletions(-) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 0cc046c..5f559b7 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2161,12 +2161,15 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc, return true; } - const ObjCMethodDecl *MD = ME->getMethodDecl(); - if (MD && MD->hasAttr()) { - WarnE = this; - Loc = getExprLoc(); - return true; - } + if (const ObjCMethodDecl *MD = ME->getMethodDecl()) + if (MD->hasAttr() || + (MD->isPropertyAccessor() && !MD->getReturnType()->isVoidType() && + !ME->getReceiverType()->isObjCIdType())) { + WarnE = this; + Loc = getExprLoc(); + return true; + } + return false; } diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index dc5619d..1ddb369 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -253,9 +253,15 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { return; } const ObjCMethodDecl *MD = ME->getMethodDecl(); - if (MD && MD->hasAttr()) { - Diag(Loc, diag::warn_unused_result) << R1 << R2; - return; + if (MD) { + if (MD->hasAttr()) { + 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(E)) { const Expr *Source = POE->getSyntacticForm(); diff --git a/clang/test/SemaObjC/class-property-access.m b/clang/test/SemaObjC/class-property-access.m index a4c188c..d57b986 100644 --- a/clang/test/SemaObjC/class-property-access.m +++ b/clang/test/SemaObjC/class-property-access.m @@ -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]; diff --git a/clang/test/SemaObjC/conditional-expr.m b/clang/test/SemaObjC/conditional-expr.m index 049a095..d8862c5 100644 --- a/clang/test/SemaObjC/conditional-expr.m +++ b/clang/test/SemaObjC/conditional-expr.m @@ -96,8 +96,8 @@ id f7(int a, id x, A* p) { return a ? x : p; } -void f8(int a, A *x, A *y) { - [ (a ? x : y ) intProp ]; +int f8(int a, A *x, A *y) { + return [ (a ? x : y ) intProp ]; } void f9(int a, A *x, A *y) { diff --git a/clang/test/SemaObjC/property-noninherited-availability-attr.m b/clang/test/SemaObjC/property-noninherited-availability-attr.m index 793ceb6..dfa72d1 100644 --- a/clang/test/SemaObjC/property-noninherited-availability-attr.m +++ b/clang/test/SemaObjC/property-noninherited-availability-attr.m @@ -21,13 +21,13 @@ void test(Foo *y, Bar *x, id 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}} } diff --git a/clang/test/SemaObjC/unused.m b/clang/test/SemaObjC/unused.m index 16a3899..6ea3fe8 100644 --- a/clang/test/SemaObjC/unused.m +++ b/clang/test/SemaObjC/unused.m @@ -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 property]; // expected-warning {{property access result unused - getters should not be used for side effects}} +} -- 2.7.4