diff options
author | John McCall <rjmccall@apple.com> | 2010-03-12 07:11:26 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-03-12 07:11:26 +0000 |
commit | 0faede6f31b07bcec7b776f2b420c3ea9bb3e58c (patch) | |
tree | b442f88dbe25c9f5e0a9666ff67a4ac152d01dac | |
parent | 617def321f362e010cc8ec0523b4f54157e5a7a5 (diff) |
Improve the unused-value check to look into comma expressions and filter out
voids in sub-expressions. Patch by Mike M!
Fixes PR4806.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98335 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AST/Expr.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 7 | ||||
-rw-r--r-- | test/Sema/return.c | 2 | ||||
-rw-r--r-- | test/Sema/warn-unused-value.c | 53 | ||||
-rw-r--r-- | test/SemaCXX/decl-expr-ambiguity.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/warn-unused-value.cpp | 17 |
6 files changed, 83 insertions, 8 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index efd0fd1b8d..1b3202dd42 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -788,6 +788,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, switch (getStmtClass()) { default: + if (getType()->isVoidType()) + return false; Loc = getExprLoc(); R1 = getSourceRange(); return true; @@ -834,8 +836,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, if (IE->getValue() == 0) return false; - return (BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx) || - BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx)); + return (BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx) || + BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx)); } if (BO->isAssignmentOp()) @@ -936,6 +938,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, if (const Expr *E = dyn_cast<Expr>(CS->body_back())) return E->isUnusedResultAWarning(Loc, R1, R2, Ctx); + if (getType()->isVoidType()) + return false; Loc = cast<StmtExpr>(this)->getLParenLoc(); R1 = getSourceRange(); return true; @@ -949,6 +953,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, R1 = cast<CStyleCastExpr>(this)->getSubExpr()->getSourceRange(); return true; case CXXFunctionalCastExprClass: { + if (getType()->isVoidType()) + return false; const CastExpr *CE = cast<CastExpr>(this); // If this is a cast to void or a constructor conversion, check the operand. diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 75d9f67ad9..fd65c32c20 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -76,10 +76,6 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { if (!E) return; - // Ignore expressions that have void type. - if (E->getType()->isVoidType()) - return; - SourceLocation Loc; SourceRange R1, R2; if (!E->isUnusedResultAWarning(Loc, R1, R2, Context)) @@ -103,6 +99,9 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { } if (const CallExpr *CE = dyn_cast<CallExpr>(E)) { + if (E->getType()->isVoidType()) + 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. if (const Decl *FD = CE->getCalleeDecl()) { diff --git a/test/Sema/return.c b/test/Sema/return.c index 5d1c97f2a2..3ab23f4f8f 100644 --- a/test/Sema/return.c +++ b/test/Sema/return.c @@ -1,4 +1,4 @@ -// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wno-unreachable-code +// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wno-unreachable-code -Wno-unused-value // clang emits the following warning by default. // With GCC, -pedantic, -Wreturn-type or -Wall are required to produce the diff --git a/test/Sema/warn-unused-value.c b/test/Sema/warn-unused-value.c new file mode 100644 index 0000000000..2e0fa54eff --- /dev/null +++ b/test/Sema/warn-unused-value.c @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value %s + +int i = 0; +int j = 0; + +void foo(); + +// PR4806 +void pr4806() { + 1,foo(); // expected-warning {{expression result unused}} + + // other + foo(); + i; // expected-warning {{expression result unused}} + + i,foo(); // expected-warning {{expression result unused}} + foo(),i; // expected-warning {{expression result unused}} + + i,j,foo(); // expected-warning {{expression result unused}} + i,foo(),j; // expected-warning {{expression result unused}} + foo(),i,j; // expected-warning {{expression result unused}} + + i++; + + i++,foo(); + foo(),i++; + + i++,j,foo(); // expected-warning {{expression result unused}} + i++,foo(),j; // expected-warning {{expression result unused}} + foo(),i++,j; // expected-warning {{expression result unused}} + + i,j++,foo(); // expected-warning {{expression result unused}} + i,foo(),j++; // expected-warning {{expression result unused}} + foo(),i,j++; // expected-warning {{expression result unused}} + + i++,j++,foo(); + i++,foo(),j++; + foo(),i++,j++; + + {}; + ({}); + ({}),foo(); + foo(),({}); + + (int)1U; // expected-warning {{expression result unused}} + (void)1U; + + // pointer to volatile has side effect (thus no warning) + int* pi = &i; + volatile int* pj = &j; + *pi; // expected-warning {{expression result unused}} + *pj; +} diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp index 81f68392d8..4243c1c0ea 100644 --- a/test/SemaCXX/decl-expr-ambiguity.cpp +++ b/test/SemaCXX/decl-expr-ambiguity.cpp @@ -10,7 +10,7 @@ void f() { int(a)++; // expected-error {{expression is not assignable}} __extension__ int(a)++; // expected-error {{expression is not assignable}} __typeof(int)(a,5)<<a; // expected-error {{function-style cast to a builtin type can only take one argument}} - void(a), ++a; // expected-warning {{expression result unused}} + void(a), ++a; if (int(a)+1) {} for (int(a)+1;;) {} // expected-warning {{expression result unused}} a = sizeof(int()+1); diff --git a/test/SemaCXX/warn-unused-value.cpp b/test/SemaCXX/warn-unused-value.cpp new file mode 100644 index 0000000000..775c3cf01f --- /dev/null +++ b/test/SemaCXX/warn-unused-value.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value %s + +// PR4806 +namespace test0 { + class Box { + public: + int i; + volatile int j; + }; + + void doit() { + // pointer to volatile has side effect (thus no warning) + Box* box = new Box; + box->i; // expected-warning {{expression result unused}} + box->j; + } +} |