summaryrefslogtreecommitdiffstats
path: root/clang
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
commitf15cd14a3d1e4dbbdc22f6c3ae7c46189a16be5e (patch)
tree5c27c84e0e96bbe9ea0e4c7683002d534ae6e820 /clang
parent310a38d51e334a0626dc10b68c7807574df1d363 (diff)
downloadbcm5719-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.cpp32
-rw-r--r--clang/test/Analysis/dead-stores.c9
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;
+}
OpenPOWER on IntegriCloud