aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-05-05 23:12:21 +0000
committerTed Kremenek <kremenek@apple.com>2008-05-05 23:12:21 +0000
commita23157e6b9e2388edebd3d383dd7acfab6a4c0c0 (patch)
tree6893b42f0b5ee1ea9e94ef58288b4298254e358c
parent95e2c71181c7ec1ffea0066bbae49e8742bd0687 (diff)
Emit dead store warnings for ++ and -- operators.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50679 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/DeadStores.cpp32
-rw-r--r--test/Analysis/dead-stores.c9
2 files changed, 32 insertions, 9 deletions
diff --git a/lib/Analysis/DeadStores.cpp b/lib/Analysis/DeadStores.cpp
index 6858e3ab37..f7523e508f 100644
--- a/lib/Analysis/DeadStores.cpp
+++ b/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/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
index 58960605f0..2ec9b48f00 100644
--- a/test/Analysis/dead-stores.c
+++ b/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;
+}