diff --git a/Driver/AnalysisConsumer.cpp b/Driver/AnalysisConsumer.cpp index db5c7e0b5e..f14fd1dd66 100644 --- a/Driver/AnalysisConsumer.cpp +++ b/Driver/AnalysisConsumer.cpp @@ -108,7 +108,6 @@ namespace { llvm::OwningPtr cfg; llvm::OwningPtr liveness; llvm::OwningPtr PM; - llvm::OwningPtr 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) { diff --git a/include/clang/Analysis/LocalCheckers.h b/include/clang/Analysis/LocalCheckers.h index 2028393879..aaba985954 100644 --- a/include/clang/Analysis/LocalCheckers.h +++ b/include/clang/Analysis/LocalCheckers.h @@ -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 diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h index 398c9a9a59..7674b04ff3 100644 --- a/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/include/clang/Analysis/PathSensitive/BugReporter.h @@ -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 +#include + 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 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::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 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::iterator iterator; + iterator begin() { return Reports.begin(); } + iterator end() { return Reports.end(); } +}; + } // end clang namespace #endif diff --git a/lib/Analysis/DeadStores.cpp b/lib/Analysis/DeadStores.cpp index 3097dc355d..e5bf2a3c19 100644 --- a/lib/Analysis/DeadStores.cpp +++ b/lib/Analysis/DeadStores.cpp @@ -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 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::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 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::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"; - } - - virtual const char* getDescription() const { - return "Value stored to variable is never subsequently read."; - } - - virtual void EmitWarnings(BugReporter& BR) { - - // 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); - - // Emit the bug reports. - - for (DiagCollector::iterator I = C.begin(), E = C.end(); I != E; ++I) - BR.EmitWarning(*I); + return name; } }; } // end anonymous namespace -BugType* clang::MakeDeadStoresChecker() { - return new DeadStoresChecker(); +//===----------------------------------------------------------------------===// +// Driver function to invoke the Dead-Stores checker on a CFG. +//===----------------------------------------------------------------------===// + +void clang::CheckDeadStores(LiveVariables& L, BugReporter& BR) { + + SimpleBugType BT("dead store"); + DiagCollector C(BT); + + DeadStoreObs A(BR.getContext(), BR.getDiagnostic(), C, BR.getParentMap()); + L.runOnAllBlocks(BR.getCFG(), &A); + + // Emit the bug reports. + + for (DiagCollector::iterator I = C.begin(), E = C.end(); I != E; ++I) + BR.EmitWarning(*I); } + diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp index 33657dadb1..926bcc8e58 100644 --- a/lib/Analysis/GRSimpleVals.cpp +++ b/lib/Analysis/GRSimpleVals.cpp @@ -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();