]> granicus.if.org Git - clang/commitdiff
fix PR4010: add support for the warn_unused_result for function pointers
authorNuno Lopes <nunoplopes@sapo.pt>
Sun, 20 Dec 2009 23:11:08 +0000 (23:11 +0000)
committerNuno Lopes <nunoplopes@sapo.pt>
Sun, 20 Dec 2009 23:11:08 +0000 (23:11 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91803 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
lib/AST/Expr.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaStmt.cpp
test/Sema/unused-expr.c

index 6807f2c5a2d80cf7b938300fe01050e13b1020d2..1a615c1e3f8fe8e2d2574f3db85d33d8e3b0f377 100644 (file)
@@ -1176,6 +1176,11 @@ public:
   Expr *getCallee() { return cast<Expr>(SubExprs[FN]); }
   void setCallee(Expr *F) { SubExprs[FN] = F; }
 
+  Decl *getCalleeDecl();
+  const Decl *getCalleeDecl() const {
+    return const_cast<CallExpr*>(this)->getCalleeDecl();
+  }
+
   /// \brief If the callee is a FunctionDecl, return it. Otherwise return 0.
   FunctionDecl *getDirectCallee();
   const FunctionDecl *getDirectCallee() const {
index 034b91ed0f5910ec974f9cdfb80a25c7769c26e4..466ddc663f2a7c025bd477ee819a5345bb827cb4 100644 (file)
@@ -398,14 +398,18 @@ void CallExpr::DoDestroy(ASTContext& C) {
   C.Deallocate(this);
 }
 
-FunctionDecl *CallExpr::getDirectCallee() {
+Decl *CallExpr::getCalleeDecl() {
   Expr *CEE = getCallee()->IgnoreParenCasts();
   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE))
-    return dyn_cast<FunctionDecl>(DRE->getDecl());
+    return DRE->getDecl();
 
   return 0;
 }
 
+FunctionDecl *CallExpr::getDirectCallee() {
+    return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
+}
+
 /// setNumArgs - This changes the number of arguments present in this call.
 /// Any orphaned expressions are deleted by this, and any new operands are set
 /// to null.
@@ -858,7 +862,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
   case CXXMemberCallExprClass: {
     // If this is a direct call, get the callee.
     const CallExpr *CE = cast<CallExpr>(this);
-    if (const FunctionDecl *FD = CE->getDirectCallee()) {
+    if (const Decl *FD = CE->getCalleeDecl()) {
       // If the callee has attribute pure, const, or warn_unused_result, warn
       // about it. void foo() { strlen("bar"); } should warn.
       //
index 84ee2073382f93336e5bad1cc6166d76c62af4a5..718db0437f41f936105257a64fd97ba4e9df62db 100644 (file)
@@ -47,7 +47,7 @@ static const FunctionType *getFunctionType(const Decl *d,
 // FIXME: We should provide an abstraction around a method or function
 // to provide the following bits of information.
 
-/// isFunctionOrMethod - Return true if the given decl has function
+/// isFunction - Return true if the given decl has function
 /// type (function or function-typed variable).
 static bool isFunction(const Decl *d) {
   return getFunctionType(d, false) != NULL;
@@ -731,14 +731,13 @@ static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S)
   }
 
   // TODO: could also be applied to methods?
-  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
-  if (!Fn) {
+  if (!isFunctionOrMethod(D)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
       << Attr.getName() << 0 /*function*/;
     return;
   }
 
-  Fn->addAttr(::new (S.Context) WarnUnusedResultAttr());
+  D->addAttr(::new (S.Context) WarnUnusedResultAttr());
 }
 
 static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
index c2a3a3a8ca629e0a61434345c7b660052cf7b8e3..6a68db75eae0716d89e8c25e047070dc1eb359b8 100644 (file)
@@ -96,7 +96,7 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
   if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
     // If the callee has attribute pure, const, or warn_unused_result, warn with
     // a more specific message to make it clear what is happening.
-    if (const FunctionDecl *FD = CE->getDirectCallee()) {
+    if (const Decl *FD = CE->getCalleeDecl()) {
       if (FD->getAttr<WarnUnusedResultAttr>()) {
         Diag(Loc, diag::warn_unused_call) << R1 << R2 << "warn_unused_result";
         return;
index 70f3446e5397dc9a634c0c38e7f27e631c874b3e..284818dc58132225769ba533203b42781b956411 100644 (file)
@@ -96,3 +96,8 @@ int t6() {
 
 int t7 __attribute__ ((warn_unused_result)); // expected-warning {{warning: 'warn_unused_result' attribute only applies to function types}}
 
+// PR4010
+int (*fn4)(void) __attribute__ ((warn_unused_result));
+void t8() {
+  fn4(); // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}}
+}