[cfe-commits] r53960 - in /cfe/trunk: lib/Analysis/CheckDeadStores.cpp test/Analysis/dead-stores.c
Ted Kremenek
kremenek at apple.com
Wed Jul 23 14:16:39 PDT 2008
Author: kremenek
Date: Wed Jul 23 16:16:38 2008
New Revision: 53960
URL: http://llvm.org/viewvc/llvm-project?rev=53960&view=rev
Log:
Further refine dead store checking to distinguish between dead stores and dead increments.
Modified:
cfe/trunk/lib/Analysis/CheckDeadStores.cpp
cfe/trunk/test/Analysis/dead-stores.c
Modified: cfe/trunk/lib/Analysis/CheckDeadStores.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CheckDeadStores.cpp?rev=53960&r1=53959&r2=53960&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CheckDeadStores.cpp (original)
+++ cfe/trunk/lib/Analysis/CheckDeadStores.cpp Wed Jul 23 16:16:38 2008
@@ -30,6 +30,8 @@
ASTContext &Ctx;
BugReporter& BR;
ParentMap& Parents;
+
+ enum DeadStoreKind { Standard, Enclosing, DeadIncrement, DeadInit };
public:
DeadStoreObs(ASTContext &ctx, BugReporter& br, ParentMap& parents)
@@ -37,44 +39,80 @@
virtual ~DeadStoreObs() {}
- void Report(VarDecl* V, bool inEnclosing, SourceLocation L, SourceRange R,
- bool isInitialization = false) {
+ void Report(VarDecl* V, DeadStoreKind dsk, SourceLocation L, SourceRange R) {
std::string name(V->getName());
- if (isInitialization) {
- std::string msg = "Value stored to '" + name +
- "' during its initialization is never read";
-
- BR.EmitBasicReport("dead initialization", msg.c_str(), L, R);
- }
- else {
- std::string msg = inEnclosing
- ? "Although the value stored to '" + name +
- "' is used in the enclosing expression, the value is never actually"
- " read from '" + name + "'"
- : "Value stored to '" + name + "' is never read";
+ const char* BugType = 0;
+ std::string msg;
- BR.EmitBasicReport("dead store", msg.c_str(), L, R);
+ switch (dsk) {
+ default:
+ assert(false && "Impossible dead store type.");
+
+ case DeadInit:
+ BugType = "dead initialization";
+ msg = "Value stored to '" + name +
+ "' during its initialization is never read";
+ break;
+
+ case DeadIncrement:
+ BugType = "dead store (++/--)";
+ case Standard:
+ if (!BugType) BugType = "dead store";
+ msg = "Value stored to '" + name + "' is never read";
+ break;
+
+ case Enclosing:
+ BugType = "dead store";
+ msg = "Although the value stored to '" + name +
+ "' is used in the enclosing expression, the value is never actually"
+ " read from '" + name + "'";
+ break;
}
+
+ BR.EmitBasicReport(BugType, msg.c_str(), L, R);
}
void CheckVarDecl(VarDecl* VD, Expr* Ex, Expr* Val,
- bool hasEnclosing,
+ DeadStoreKind dsk,
const LiveVariables::AnalysisDataTy& AD,
const LiveVariables::ValTy& Live) {
if (VD->hasLocalStorage() && !Live(VD, AD))
- Report(VD, hasEnclosing, Ex->getSourceRange().getBegin(),
+ Report(VD, dsk, Ex->getSourceRange().getBegin(),
Val->getSourceRange());
}
- void CheckDeclRef(DeclRefExpr* DR, Expr* Val,
+ void CheckDeclRef(DeclRefExpr* DR, Expr* Val, DeadStoreKind dsk,
const LiveVariables::AnalysisDataTy& AD,
const LiveVariables::ValTy& Live) {
if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
- CheckVarDecl(VD, DR, Val, false, AD, Live);
+ CheckVarDecl(VD, DR, Val, dsk, AD, Live);
+ }
+
+ bool isIncrement(VarDecl* VD, BinaryOperator* B) {
+ if (B->isCompoundAssignmentOp())
+ return true;
+
+ Expr* RHS = B->getRHS()->IgnoreParenCasts();
+ BinaryOperator* BRHS = dyn_cast<BinaryOperator>(RHS);
+
+ if (!BRHS)
+ return false;
+
+ DeclRefExpr *DR;
+
+ if ((DR = dyn_cast<DeclRefExpr>(BRHS->getLHS()->IgnoreParenCasts())))
+ if (DR->getDecl() == VD)
+ return true;
+
+ if ((DR = dyn_cast<DeclRefExpr>(BRHS->getRHS()->IgnoreParenCasts())))
+ if (DR->getDecl() == VD)
+ return true;
+
+ return false;
}
virtual void ObserveStmt(Stmt* S,
@@ -103,7 +141,12 @@
if (Result == 0)
return;
- CheckVarDecl(VD, DR, Val, Parents.isSubExpr(B), AD, Live);
+ DeadStoreKind dsk =
+ Parents.isSubExpr(B)
+ ? Enclosing
+ : (isIncrement(VD,B) ? DeadIncrement : Standard);
+
+ CheckVarDecl(VD, DR, Val, dsk, AD, Live);
}
}
else if (UnaryOperator* U = dyn_cast<UnaryOperator>(S)) {
@@ -113,7 +156,7 @@
Expr *Ex = U->getSubExpr()->IgnoreParenCasts();
if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(Ex))
- CheckDeclRef(DR, U, AD, Live);
+ CheckDeclRef(DR, U, DeadIncrement, AD, Live);
}
else if (DeclStmt* DS = dyn_cast<DeclStmt>(S))
// Iterate through the decls. Warn if any initializers are complex
@@ -134,7 +177,7 @@
// a warning. This is because such initialization can be
// due to defensive programming.
if (!E->isConstantExpr(Ctx,NULL))
- Report(V, false, V->getLocation(), E->getSourceRange(), true);
+ Report(V, DeadInit, V->getLocation(), E->getSourceRange());
}
}
}
Modified: cfe/trunk/test/Analysis/dead-stores.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dead-stores.c?rev=53960&r1=53959&r2=53960&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/dead-stores.c (original)
+++ cfe/trunk/test/Analysis/dead-stores.c Wed Jul 23 16:16:38 2008
@@ -59,3 +59,17 @@
return 0;
}
+int f9() {
+ int x = 4;
+ x = x + 10; // expected-warning{{never read}}
+ return 1;
+}
+
+
+int f10() {
+ int x = 4;
+ x = 10 + x; // expected-warning{{never read}}
+ return 1;
+}
+
+
More information about the cfe-commits
mailing list