For looking at "dead stores" in declarations, we now check to see

if the assigned value is a constant expression, e.g.:

int x = 0;

We then check to see if "x" is ever reassigned later.  If so, we don't
emit a warning.  This is because programmers frequently use defensive
programming to make sure a variable has a defined value.

llvm-svn: 41853
This commit is contained in:
Ted Kremenek 2007-09-11 17:24:14 +00:00
parent 74fb0f1a1c
commit 2f1a79d329
1 changed files with 21 additions and 7 deletions

View File

@ -18,6 +18,7 @@
#include "clang/AST/CFG.h" #include "clang/AST/CFG.h"
#include "clang/Basic/Diagnostic.h" #include "clang/Basic/Diagnostic.h"
#include "clang/Lex/Preprocessor.h" #include "clang/Lex/Preprocessor.h"
#include "clang/AST/ASTContext.h"
using namespace clang; using namespace clang;
@ -25,8 +26,11 @@ namespace {
class DeadStoreObserver : public LiveVariablesObserver { class DeadStoreObserver : public LiveVariablesObserver {
Preprocessor& PP; Preprocessor& PP;
ASTContext Ctx;
public: public:
DeadStoreObserver(Preprocessor& pp) : PP(pp) {} DeadStoreObserver(Preprocessor& pp) :
PP(pp), Ctx(PP.getTargetInfo(), PP.getIdentifierTable()) {}
virtual ~DeadStoreObserver() {} virtual ~DeadStoreObserver() {}
virtual void ObserveStmt(Stmt* S, LiveVariables& L, llvm::BitVector& Live) { virtual void ObserveStmt(Stmt* S, LiveVariables& L, llvm::BitVector& Live) {
@ -52,12 +56,22 @@ public:
for (VarDecl* V = cast<VarDecl>(DS->getDecl()); V != NULL ; for (VarDecl* V = cast<VarDecl>(DS->getDecl()); V != NULL ;
V = cast_or_null<VarDecl>(V->getNextDeclarator())) V = cast_or_null<VarDecl>(V->getNextDeclarator()))
if (Expr* E = V->getInit()) if (Expr* E = V->getInit())
if (!L.isLive(Live,V)) { if (!L.isLive(Live,V))
SourceRange R = E->getSourceRange(); // Special case: check for initializations with constants.
PP.getDiagnostics().Report(V->getLocation(), //
diag::warn_dead_store, 0, 0, // e.g. : int x = 0;
&R,1); //
} // If x is EVER assigned a new value later, don't issue
// a warning. This is because such initialization can be
// due to defensive programming.
if (!E->isConstantExpr(Ctx,NULL) ||
L.getVarInfo(V).Kills.size() == 0) {
// Flag a warning.
SourceRange R = E->getSourceRange();
PP.getDiagnostics().Report(V->getLocation(),
diag::warn_dead_store, 0, 0,
&R,1);
}
} }
} }
}; };