diff options
author | Matt Beaumont-Gay <matthewbg@google.com> | 2013-02-26 19:34:08 +0000 |
---|---|---|
committer | Matt Beaumont-Gay <matthewbg@google.com> | 2013-02-26 19:34:08 +0000 |
commit | 9016bb771265a10f188c76342254badecc695253 (patch) | |
tree | 766e70770d940a238dc8e6074fda741272a5eb94 | |
parent | d3b2f0ac1cedad284d860acd652f28a05bcbcbed (diff) |
Warn on dropping the return value from a warn_unused_result function, even in
macros.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176114 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 22 | ||||
-rw-r--r-- | test/Sema/unused-expr.c | 6 |
2 files changed, 23 insertions, 5 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 3b6d073470..9b7ba04044 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -158,9 +158,14 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { if (!E) return; SourceLocation ExprLoc = E->IgnoreParens()->getExprLoc(); - if (SourceMgr.isInSystemMacro(ExprLoc) || - SourceMgr.isMacroBodyExpansion(ExprLoc)) - return; + // In most cases, we don't want to warn if the expression is written in a + // macro body, or if the macro comes from a system header. If the offending + // expression is a call to a function with the warn_unused_result attribute, + // we warn no matter the location. Because of the order in which the various + // checks need to happen, we factor out the macro-related test here. + bool ShouldSuppress = + SourceMgr.isMacroBodyExpansion(ExprLoc) || + SourceMgr.isInSystemMacro(ExprLoc); const Expr *WarnExpr; SourceLocation Loc; @@ -193,12 +198,16 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { return; // If the callee has attribute pure, const, or warn_unused_result, warn with - // a more specific message to make it clear what is happening. + // a more specific message to make it clear what is happening. If the call + // is written in a macro body, only warn if it has the warn_unused_result + // attribute. if (const Decl *FD = CE->getCalleeDecl()) { if (FD->getAttr<WarnUnusedResultAttr>()) { Diag(Loc, diag::warn_unused_result) << R1 << R2; return; } + if (ShouldSuppress) + return; if (FD->getAttr<PureAttr>()) { Diag(Loc, diag::warn_unused_call) << R1 << R2 << "pure"; return; @@ -208,7 +217,10 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { return; } } - } else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) { + } else if (ShouldSuppress) + return; + + if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) { if (getLangOpts().ObjCAutoRefCount && ME->isDelegateInitCall()) { Diag(Loc, diag::err_arc_unused_init_message) << R1; return; diff --git a/test/Sema/unused-expr.c b/test/Sema/unused-expr.c index 0786ede676..ea08631eba 100644 --- a/test/Sema/unused-expr.c +++ b/test/Sema/unused-expr.c @@ -132,6 +132,8 @@ int fn5() __attribute__ ((__const)); #define M3(a) (t3(a), fn2()) #define M4(a, b) (foo((a), (b)) ? 0 : t3(a), 1) #define M5(a, b) (foo((a), (b)), 1) +#define M6() fn1() +#define M7() fn2() void t11(int i, int j) { M1(i, j); // no warning NOP((long)foo(i, j)); // expected-warning {{expression result unused}} @@ -143,6 +145,8 @@ void t11(int i, int j) { NOP((foo(i, j) ? 0 : t3(i), 1)); // expected-warning {{expression result unused}} M5(i, j); // no warning NOP((foo(i, j), 1)); // expected-warning {{expression result unused}} + M6(); // expected-warning {{ignoring return value}} + M7(); // no warning } #undef NOP #undef M1 @@ -150,3 +154,5 @@ void t11(int i, int j) { #undef M3 #undef M4 #undef M5 +#undef M6 +#undef M7 |