diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-05-05 23:12:21 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-05-05 23:12:21 +0000 |
commit | f15cd14a3d1e4dbbdc22f6c3ae7c46189a16be5e (patch) | |
tree | 5c27c84e0e96bbe9ea0e4c7683002d534ae6e820 /clang | |
parent | 310a38d51e334a0626dc10b68c7807574df1d363 (diff) | |
download | bcm5719-llvm-f15cd14a3d1e4dbbdc22f6c3ae7c46189a16be5e.tar.gz bcm5719-llvm-f15cd14a3d1e4dbbdc22f6c3ae7c46189a16be5e.zip |
Emit dead store warnings for ++ and -- operators.
llvm-svn: 50679
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Analysis/DeadStores.cpp | 32 | ||||
-rw-r--r-- | clang/test/Analysis/dead-stores.c | 9 |
2 files changed, 32 insertions, 9 deletions
diff --git a/clang/lib/Analysis/DeadStores.cpp b/clang/lib/Analysis/DeadStores.cpp index 6858e3ab370..f7523e508f0 100644 --- a/clang/lib/Analysis/DeadStores.cpp +++ b/clang/lib/Analysis/DeadStores.cpp @@ -35,6 +35,19 @@ public: virtual ~DeadStoreObs() {} + void CheckDeclRef(DeclRefExpr* DR, Expr* Val, + const LiveVariables::AnalysisDataTy& AD, + const LiveVariables::ValTy& Live) { + + if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) + if (VD->hasLocalStorage() && !Live(VD, AD)) { + SourceRange R = Val->getSourceRange(); + Diags.Report(&Client, + Ctx.getFullLoc(DR->getSourceRange().getBegin()), + diag::warn_dead_store, 0, 0, &R, 1); + } + } + virtual void ObserveStmt(Stmt* S, const LiveVariables::AnalysisDataTy& AD, const LiveVariables::ValTy& Live) { @@ -47,15 +60,18 @@ public: if (!B->isAssignmentOp()) return; // Skip non-assignments. if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS())) - if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) - if (VD->hasLocalStorage() && !Live(VD,AD)) { - SourceRange R = B->getRHS()->getSourceRange(); - Diags.Report(&Client, - Ctx.getFullLoc(DR->getSourceRange().getBegin()), - diag::warn_dead_store, 0, 0, &R, 1); - } + CheckDeclRef(DR, B->getRHS(), AD, Live); } - else if(DeclStmt* DS = dyn_cast<DeclStmt>(S)) + else if (UnaryOperator* U = dyn_cast<UnaryOperator>(S)) { + if (!U->isIncrementOp()) + return; + + Expr *Ex = U->getSubExpr()->IgnoreParenCasts(); + + if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(Ex)) + CheckDeclRef(DR, U, AD, Live); + } + else if (DeclStmt* DS = dyn_cast<DeclStmt>(S)) // Iterate through the decls. Warn if any initializers are complex // expressions that are not live (never used). for (ScopedDecl* SD = DS->getDecl(); SD; SD = SD->getNextDeclarator()) { diff --git a/clang/test/Analysis/dead-stores.c b/clang/test/Analysis/dead-stores.c index 58960605f08..2ec9b48f006 100644 --- a/clang/test/Analysis/dead-stores.c +++ b/clang/test/Analysis/dead-stores.c @@ -35,4 +35,11 @@ void f5() { int x = 4; // no-warning int *p = &x; // expected-warning{{value stored to variable is never used}} -}
\ No newline at end of file +} + +int f6() { + + int x = 4; + ++x; // expected-warning{{value stored to variable is never used}} + return 1; +} |