From: Fariborz Jahanian Date: Tue, 30 Mar 2010 18:22:15 +0000 (+0000) Subject: Add Support for 'warn_unused_result" attribute on X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f031774aa2638b4d3f487e7e44180c1f89b867ef;p=clang Add Support for 'warn_unused_result" attribute on objective-c methods. (radar 7418262). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99903 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 154d3197f3..58c40cf338 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -783,8 +783,9 @@ def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning< def warn_attribute_ignored : Warning<"%0 attribute ignored">; def warn_attribute_precede_definition : Warning< "attribute declaration must precede definition">; -def warn_attribute_void_function : Warning< - "attribute %0 cannot be applied to functions without return value">; +def warn_attribute_void_function_method : Warning< + "attribute %0 cannot be applied to " + "%select{functions|Objective-C method}1 without return value">; def warn_attribute_weak_on_field : Warning< "__weak attribute cannot be specified on a field declaration">; def warn_attribute_weak_on_local : Warning< diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 6a71e925d9..b4e5a5d960 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -914,8 +914,15 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, case CXXConstructExprClass: return false; - case ObjCMessageExprClass: + case ObjCMessageExprClass: { + const ObjCMessageExpr *ME = cast(this); + const ObjCMethodDecl *MD = ME->getMethodDecl(); + if (MD && MD->getAttr()) { + Loc = getExprLoc(); + return true; + } return false; + } case ObjCImplicitSetterGetterRefExprClass: { // Dot syntax for message send. #if 0 diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index b3041129db..d12dec4561 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -837,18 +837,24 @@ static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) return; } - if (!isFunction(D)) { + if (!isFunction(D) && !isa(D)) { S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << Attr.getName() << 0 /*function*/; return; } - if (getFunctionType(D)->getResultType()->isVoidType()) { - S.Diag(Attr.getLoc(), diag::warn_attribute_void_function) - << Attr.getName(); + if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { + S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) + << Attr.getName() << 0; return; } - + if (const ObjCMethodDecl *MD = dyn_cast(D)) + if (MD->getResultType()->isVoidType()) { + S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) + << Attr.getName() << 1; + return; + } + D->addAttr(::new (S.Context) WarnUnusedResultAttr()); } diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 733022aac3..1e37bb00c4 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -119,7 +119,13 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { } } } - + else if (const ObjCMessageExpr *ME = dyn_cast(E)) { + const ObjCMethodDecl *MD = ME->getMethodDecl(); + if (MD && MD->getAttr()) { + Diag(Loc, diag::warn_unused_call) << R1 << R2 << "warn_unused_result"; + return; + } + } Diag(Loc, DiagID) << R1 << R2; } diff --git a/test/SemaObjC/method-warn-unused-attribute.m b/test/SemaObjC/method-warn-unused-attribute.m index d9dcf996ec..042f4422f8 100644 --- a/test/SemaObjC/method-warn-unused-attribute.m +++ b/test/SemaObjC/method-warn-unused-attribute.m @@ -1,8 +1,16 @@ // RUN: %clang_cc1 -fsyntax-only -Wunused-value -verify %s @interface INTF -// Currently this is rejected by both GCC and Clang (and Clang was crashing on it). -- (id) foo __attribute__((warn_unused_result)); // expected-warning{{warning: 'warn_unused_result' attribute only applies to function types}} +- (id) foo __attribute__((warn_unused_result)); +- (void) garf __attribute__((warn_unused_result)); // expected-warning {{attribute 'warn_unused_result' cannot be applied to Objective-C method without return value}} +- (int) fee __attribute__((warn_unused_result)); ++ (int) c __attribute__((warn_unused_result)); @end +void foo(INTF *a) { + [a garf]; + [a fee]; // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}} + [INTF c]; // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}} +} +