Unify the code path for the Dead Stores checker to always use the BugReporter interface.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53054 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2008-07-02 23:16:33 +00:00
Родитель 01006786e3
Коммит e207558e9d
5 изменённых файлов: 97 добавлений и 120 удалений

Просмотреть файл

@ -108,7 +108,6 @@ namespace {
llvm::OwningPtr<CFG> cfg;
llvm::OwningPtr<LiveVariables> liveness;
llvm::OwningPtr<ParentMap> PM;
llvm::OwningPtr<PathDiagnosticClient> PD;
public:
AnalysisManager(AnalysisConsumer& c, Decl* d, Stmt* b)
@ -124,7 +123,8 @@ namespace {
}
virtual ParentMap& getParentMap() {
if (!PM) PM.reset(new ParentMap(getBody()));
if (!PM)
PM.reset(new ParentMap(getBody()));
return *PM.get();
}
@ -145,10 +145,10 @@ namespace {
}
virtual PathDiagnosticClient* getPathDiagnosticClient() {
if (PD.get() == 0 && !C.HTMLDir.empty())
PD.reset(CreateHTMLDiagnosticClient(C.HTMLDir, C.PP, C.PPF));
if (C.PD.get() == 0 && !C.HTMLDir.empty())
C.PD.reset(CreateHTMLDiagnosticClient(C.HTMLDir, C.PP, C.PPF));
return PD.get();
return C.PD.get();
}
virtual LiveVariables& getLiveVariables() {
@ -267,9 +267,8 @@ void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions actions) {
//===----------------------------------------------------------------------===//
static void ActionDeadStores(AnalysisManager& mgr) {
CheckDeadStores(mgr.getCFG(), mgr.getContext(),
mgr.getLiveVariables(), mgr.getParentMap(),
mgr.getDiagnostic());
BugReporter BR(mgr);
CheckDeadStores(mgr.getLiveVariables(), BR);
}
static void ActionUninitVals(AnalysisManager& mgr) {

Просмотреть файл

@ -27,12 +27,9 @@ class BugType;
class LangOptions;
class ParentMap;
class LiveVariables;
class BugReporter;
void CheckDeadStores(CFG& cfg, ASTContext &Ctx, ParentMap& Parents,
Diagnostic &Diags);
void CheckDeadStores(CFG& cfg, ASTContext &Ctx, LiveVariables& L,
ParentMap& Parents, Diagnostic &Diags);
void CheckDeadStores(LiveVariables& L, BugReporter& BR);
void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
bool FullUninitTaint=false);
@ -41,7 +38,6 @@ GRTransferFuncs* MakeGRSimpleValsTF();
GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
bool StandardWarnings,
const LangOptions& lopts);
BugType* MakeDeadStoresChecker();
} // end namespace clang

Просмотреть файл

@ -15,12 +15,15 @@
#ifndef LLVM_CLANG_ANALYSIS_BUGREPORTER
#define LLVM_CLANG_ANALYSIS_BUGREPORTER
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Analysis/PathSensitive/ValueState.h"
#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include <vector>
#include <list>
namespace clang {
@ -168,7 +171,7 @@ public:
}
SourceManager& getSourceManager() {
return getContext().getSourceManager();
return D.getSourceManager();
}
CFG& getCFG() {
@ -223,6 +226,66 @@ public:
}
};
class DiagBugReport : public RangedBugReport {
std::list<std::string> Strs;
FullSourceLoc L;
const char* description;
public:
DiagBugReport(const char* desc, BugType& D, FullSourceLoc l) :
RangedBugReport(D, NULL), L(l), description(desc) {}
virtual ~DiagBugReport() {}
virtual FullSourceLoc getLocation(SourceManager&) { return L; }
virtual const char* getDescription() const {
return description;
}
void addString(const std::string& s) { Strs.push_back(s); }
typedef std::list<std::string>::const_iterator str_iterator;
str_iterator str_begin() const { return Strs.begin(); }
str_iterator str_end() const { return Strs.end(); }
};
class DiagCollector : public DiagnosticClient {
std::list<DiagBugReport> Reports;
BugType& D;
public:
DiagCollector(BugType& d) : D(d) {}
virtual ~DiagCollector() {}
virtual void HandleDiagnostic(Diagnostic &Diags,
Diagnostic::Level DiagLevel,
FullSourceLoc Pos,
diag::kind ID,
const std::string *Strs,
unsigned NumStrs,
const SourceRange *Ranges,
unsigned NumRanges) {
// FIXME: Use a map from diag::kind to BugType, instead of having just
// one BugType.
Reports.push_back(DiagBugReport(Diags.getDescription(ID), D, Pos));
DiagBugReport& R = Reports.back();
for ( ; NumRanges ; --NumRanges, ++Ranges)
R.addRange(*Ranges);
for ( ; NumStrs ; --NumStrs, ++Strs)
R.addString(*Strs);
}
// Iterators.
typedef std::list<DiagBugReport>::iterator iterator;
iterator begin() { return Reports.begin(); }
iterator end() { return Reports.end(); }
};
} // end clang namespace
#endif

Просмотреть файл

@ -44,8 +44,8 @@ public:
std::string msg = inEnclosing
? "Although the value stored to '" + name +
"' is used in the enclosing expression, the value is never actually read"
" from '" + name + "'"
"' is used in the enclosing expression, the value is never actually"
" read from '" + name + "'"
: "Value stored to '" + name + "' is never read";
return Diags.getCustomDiagID(Diagnostic::Warning, msg.c_str());
@ -143,116 +143,38 @@ public:
} // end anonymous namespace
//===----------------------------------------------------------------------===//
// Driver function to invoke the Dead-Stores checker on a CFG.
//===----------------------------------------------------------------------===//
void clang::CheckDeadStores(CFG& cfg, ASTContext &Ctx,
ParentMap& Parents, Diagnostic &Diags) {
LiveVariables L(cfg);
L.runOnCFG(cfg);
CheckDeadStores(cfg, Ctx, L, Parents, Diags);
}
void clang::CheckDeadStores(CFG& cfg, ASTContext &Ctx, LiveVariables& L,
ParentMap& Parents, Diagnostic &Diags) {
DeadStoreObs A(Ctx, Diags, Diags.getClient(), Parents);
L.runOnAllBlocks(cfg, &A);
}
//===----------------------------------------------------------------------===//
// BugReporter-based invocation of the Dead-Stores checker.
//===----------------------------------------------------------------------===//
namespace {
class VISIBILITY_HIDDEN DiagBugReport : public RangedBugReport {
std::list<std::string> Strs;
FullSourceLoc L;
const char* description;
class SimpleBugType : public BugTypeCacheLocation {
const char* name;
public:
DiagBugReport(const char* desc, BugType& D, FullSourceLoc l) :
RangedBugReport(D, NULL), L(l), description(desc) {}
SimpleBugType(const char* n) : name(n) {}
virtual ~DiagBugReport() {}
virtual FullSourceLoc getLocation(SourceManager&) { return L; }
virtual const char* getDescription() const {
return description;
}
void addString(const std::string& s) { Strs.push_back(s); }
typedef std::list<std::string>::const_iterator str_iterator;
str_iterator str_begin() const { return Strs.begin(); }
str_iterator str_end() const { return Strs.end(); }
};
class VISIBILITY_HIDDEN DiagCollector : public DiagnosticClient {
std::list<DiagBugReport> Reports;
BugType& D;
public:
DiagCollector(BugType& d) : D(d) {}
virtual ~DiagCollector() {}
virtual void HandleDiagnostic(Diagnostic &Diags,
Diagnostic::Level DiagLevel,
FullSourceLoc Pos,
diag::kind ID,
const std::string *Strs,
unsigned NumStrs,
const SourceRange *Ranges,
unsigned NumRanges) {
// FIXME: Use a map from diag::kind to BugType, instead of having just
// one BugType.
Reports.push_back(DiagBugReport(Diags.getDescription(ID), D, Pos));
DiagBugReport& R = Reports.back();
for ( ; NumRanges ; --NumRanges, ++Ranges)
R.addRange(*Ranges);
for ( ; NumStrs ; --NumStrs, ++Strs)
R.addString(*Strs);
}
// Iterators.
typedef std::list<DiagBugReport>::iterator iterator;
iterator begin() { return Reports.begin(); }
iterator end() { return Reports.end(); }
};
class VISIBILITY_HIDDEN DeadStoresChecker : public BugTypeCacheLocation {
public:
virtual const char* getName() const {
return "dead store";
return name;
}
};
} // end anonymous namespace
virtual const char* getDescription() const {
return "Value stored to variable is never subsequently read.";
}
//===----------------------------------------------------------------------===//
// Driver function to invoke the Dead-Stores checker on a CFG.
//===----------------------------------------------------------------------===//
virtual void EmitWarnings(BugReporter& BR) {
void clang::CheckDeadStores(LiveVariables& L, BugReporter& BR) {
SimpleBugType BT("dead store");
DiagCollector C(BT);
// Run the dead store checker and collect the diagnostics.
DiagCollector C(*this);
DeadStoreObs A(BR.getContext(), BR.getDiagnostic(), C, BR.getParentMap());
BR.getLiveVariables().runOnAllBlocks(BR.getCFG(), &A);
L.runOnAllBlocks(BR.getCFG(), &A);
// Emit the bug reports.
for (DiagCollector::iterator I = C.begin(), E = C.end(); I != E; ++I)
BR.EmitWarning(*I);
}
};
} // end anonymous namespace
BugType* clang::MakeDeadStoresChecker() {
return new DeadStoresChecker();
}

Просмотреть файл

@ -350,9 +350,6 @@ void GRSimpleVals::RegisterChecks(GRExprEngine& Eng) {
Eng.Register(new BadMsgExprArg());
Eng.Register(new BadReceiver());
// Flow-sensitive checks.
Eng.Register(MakeDeadStoresChecker());
// Add extra checkers.
ASTContext& Ctx = Eng.getContext();
ValueStateManager* VMgr = &Eng.getStateManager();