aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-02-23 07:19:23 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-02-23 07:19:23 +0000
commit30726c6baee1417307236e854f1474fdb3cedb98 (patch)
tree881c0cfb6d78f4205f45bdce4df8e3a11a29a4eb
parent45d9b4e44154939b91d6b8f63e7756feaca547f2 (diff)
[analyzer] Migrate UnreachableCodeChecker to CheckerV2.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126308 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h11
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerV2.h15
-rw-r--r--lib/StaticAnalyzer/Checkers/ExprEngine.cpp1
-rw-r--r--lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp58
-rw-r--r--lib/StaticAnalyzer/Core/CheckerManager.cpp11
5 files changed, 64 insertions, 32 deletions
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index d41bbefe79..c8d8c6681a 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -32,6 +32,7 @@ namespace ento {
class ObjCMessage;
class SVal;
class ExplodedNodeSet;
+ class ExplodedGraph;
class GRState;
struct VoidCheckerFnParm {};
@@ -172,6 +173,10 @@ public:
const GRState *state,
ExprEngine &Eng);
+ /// \brief Run checkers for end of analysis.
+ void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
+ ExprEngine &Eng);
+
// FIXME: Temporary until checker running is moved completely into
// CheckerManager.
void registerCheckersToEngine(ExprEngine &eng);
@@ -199,6 +204,8 @@ public:
typedef CheckerFn<const ObjCMessage &, CheckerContext &> CheckObjCMessageFunc;
typedef CheckerFn<const SVal &/*location*/, bool/*isLoad*/, CheckerContext &>
CheckLocationFunc;
+ typedef CheckerFn<ExplodedGraph &, BugReporter &, ExprEngine &>
+ CheckEndAnalysisFunc;
typedef bool (*HandlesStmtFunc)(const Stmt *D);
void _registerForPreStmt(CheckStmtFunc checkfn,
@@ -211,6 +218,8 @@ public:
void _registerForLocation(CheckLocationFunc checkfn);
+ void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
+
//===----------------------------------------------------------------------===//
// Implementation details.
//===----------------------------------------------------------------------===//
@@ -276,6 +285,8 @@ private:
std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
std::vector<CheckLocationFunc> LocationCheckers;
+
+ std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
};
} // end ento namespace
diff --git a/include/clang/StaticAnalyzer/Core/CheckerV2.h b/include/clang/StaticAnalyzer/Core/CheckerV2.h
index 1f5b19ca80..45c5b73fcc 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerV2.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerV2.h
@@ -145,6 +145,21 @@ public:
}
};
+class EndAnalysis {
+ template <typename CHECKER>
+ static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
+ BugReporter &BR, ExprEngine &Eng) {
+ ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForEndAnalysis(
+ CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
+ }
+};
+
} // end check namespace
template <typename CHECK1, typename CHECK2=check::_VoidCheck,
diff --git a/lib/StaticAnalyzer/Checkers/ExprEngine.cpp b/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
index 234fd896d4..01aad7a4be 100644
--- a/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
@@ -562,6 +562,7 @@ void ExprEngine::processEndWorklist(bool hasWorkRemaining) {
I != E; ++I) {
I->second->VisitEndAnalysis(G, BR, *this);
}
+ getCheckerManager().runCheckersForEndAnalysis(G, BR, *this);
}
void ExprEngine::processCFGElement(const CFGElement E,
diff --git a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
index 3038e29c0e..1bc487a49c 100644
--- a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
@@ -14,15 +14,16 @@
//===----------------------------------------------------------------------===//
#include "ClangSACheckers.h"
-#include "clang/AST/ParentMap.h"
-#include "clang/Basic/Builtins.h"
-#include "clang/Basic/SourceManager.h"
+#include "clang/StaticAnalyzer/Core/CheckerV2.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/SmallPtrSet.h"
// The number of CFGBlock pointers we want to reserve memory for. This is used
@@ -33,40 +34,27 @@ using namespace clang;
using namespace ento;
namespace {
-class UnreachableCodeChecker : public Checker {
+class UnreachableCodeChecker : public CheckerV2<check::EndAnalysis> {
public:
- static void *getTag();
- void VisitEndAnalysis(ExplodedGraph &G,
- BugReporter &B,
- ExprEngine &Eng);
+ void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,
+ ExprEngine &Eng) const;
private:
+ typedef llvm::SmallSet<unsigned, DEFAULT_CFGBLOCKS> CFGBlocksSet;
+
static inline const Stmt *getUnreachableStmt(const CFGBlock *CB);
- void FindUnreachableEntryPoints(const CFGBlock *CB);
+ static void FindUnreachableEntryPoints(const CFGBlock *CB,
+ CFGBlocksSet &reachable,
+ CFGBlocksSet &visited);
static bool isInvalidPath(const CFGBlock *CB, const ParentMap &PM);
static inline bool isEmptyCFGBlock(const CFGBlock *CB);
-
- llvm::SmallSet<unsigned, DEFAULT_CFGBLOCKS> reachable;
- llvm::SmallSet<unsigned, DEFAULT_CFGBLOCKS> visited;
};
}
-void *UnreachableCodeChecker::getTag() {
- static int x = 0;
- return &x;
-}
-
-static void RegisterUnreachableCodeChecker(ExprEngine &Eng) {
- Eng.registerCheck(new UnreachableCodeChecker());
-}
-
-void ento::registerUnreachableCodeChecker(CheckerManager &mgr) {
- mgr.addCheckerRegisterFunction(RegisterUnreachableCodeChecker);
-}
-
-void UnreachableCodeChecker::VisitEndAnalysis(ExplodedGraph &G,
+void UnreachableCodeChecker::checkEndAnalysis(ExplodedGraph &G,
BugReporter &B,
- ExprEngine &Eng) {
- // Bail out if we didn't cover all paths
+ ExprEngine &Eng) const {
+ CFGBlocksSet reachable, visited;
+
if (Eng.hasWorkRemaining())
return;
@@ -109,7 +97,7 @@ void UnreachableCodeChecker::VisitEndAnalysis(ExplodedGraph &G,
// Find the entry points for this block
if (!visited.count(CB->getBlockID()))
- FindUnreachableEntryPoints(CB);
+ FindUnreachableEntryPoints(CB, reachable, visited);
// This block may have been pruned; check if we still want to report it
if (reachable.count(CB->getBlockID()))
@@ -155,7 +143,9 @@ void UnreachableCodeChecker::VisitEndAnalysis(ExplodedGraph &G,
}
// Recursively finds the entry point(s) for this dead CFGBlock.
-void UnreachableCodeChecker::FindUnreachableEntryPoints(const CFGBlock *CB) {
+void UnreachableCodeChecker::FindUnreachableEntryPoints(const CFGBlock *CB,
+ CFGBlocksSet &reachable,
+ CFGBlocksSet &visited) {
visited.insert(CB->getBlockID());
for (CFGBlock::const_pred_iterator I = CB->pred_begin(), E = CB->pred_end();
@@ -166,7 +156,7 @@ void UnreachableCodeChecker::FindUnreachableEntryPoints(const CFGBlock *CB) {
reachable.insert(CB->getBlockID());
if (!visited.count((*I)->getBlockID()))
// If we haven't previously visited the unreachable predecessor, recurse
- FindUnreachableEntryPoints(*I);
+ FindUnreachableEntryPoints(*I, reachable, visited);
}
}
}
@@ -226,3 +216,7 @@ bool UnreachableCodeChecker::isEmptyCFGBlock(const CFGBlock *CB) {
&& CB->size() == 0 // No statements
&& CB->getTerminator() == 0; // No terminator
}
+
+void ento::registerUnreachableCodeChecker(CheckerManager &mgr) {
+ mgr.registerChecker<UnreachableCodeChecker>();
+}
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp
index cb7c0ecdb4..0ff29757a6 100644
--- a/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -200,6 +200,13 @@ void CheckerManager::runCheckersForLocation(ExplodedNodeSet &Dst,
runPathSensitiveCheckers(C, Dst, Src);
}
+void CheckerManager::runCheckersForEndAnalysis(ExplodedGraph &G,
+ BugReporter &BR,
+ ExprEngine &Eng) {
+ for (unsigned i = 0, e = EndAnalysisCheckers.size(); i != e; ++i)
+ EndAnalysisCheckers[i](G, BR, Eng);
+}
+
void CheckerManager::registerCheckersToEngine(ExprEngine &eng) {
for (unsigned i = 0, e = Funcs.size(); i != e; ++i)
Funcs[i](eng);
@@ -245,6 +252,10 @@ void CheckerManager::_registerForLocation(CheckLocationFunc checkfn) {
LocationCheckers.push_back(checkfn);
}
+void CheckerManager::_registerForEndAnalysis(CheckEndAnalysisFunc checkfn) {
+ EndAnalysisCheckers.push_back(checkfn);
+}
+
//===----------------------------------------------------------------------===//
// Implementation details.
//===----------------------------------------------------------------------===//