From f15cd14a3d1e4dbbdc22f6c3ae7c46189a16be5e Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 5 May 2008 23:12:21 +0000 Subject: [PATCH] Emit dead store warnings for ++ and -- operators. llvm-svn: 50679 --- clang/lib/Analysis/DeadStores.cpp | 32 +++++++++++++++++++++++-------- 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 6858e3ab370c..f7523e508f08 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(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(B->getLHS())) - if (VarDecl* VD = dyn_cast(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(S)) + else if (UnaryOperator* U = dyn_cast(S)) { + if (!U->isIncrementOp()) + return; + + Expr *Ex = U->getSubExpr()->IgnoreParenCasts(); + + if (DeclRefExpr* DR = dyn_cast(Ex)) + CheckDeclRef(DR, U, AD, Live); + } + else if (DeclStmt* DS = dyn_cast(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 58960605f084..2ec9b48f0065 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; +}