aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-02-28 01:27:33 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-02-28 01:27:33 +0000
commitcc05d511b26ac6dc80fcbcc78ac305d2755aa0b9 (patch)
treeed9f7de5944690615d97478e98accdc664a82574
parent265c674f634e99e5df1135d764e21365351372da (diff)
[analyzer] Migrate UndefBranchChecker to CheckerV2.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126616 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h13
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerV2.h16
-rw-r--r--lib/StaticAnalyzer/Checkers/Checkers.td4
-rw-r--r--lib/StaticAnalyzer/Checkers/ExprEngine.cpp3
-rw-r--r--lib/StaticAnalyzer/Checkers/InternalChecks.h1
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp38
-rw-r--r--lib/StaticAnalyzer/Core/CheckerManager.cpp15
-rw-r--r--test/Analysis/new.cpp2
8 files changed, 67 insertions, 25 deletions
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index f7ee2bed8d..3c23cbd29f 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -37,6 +37,7 @@ namespace ento {
class ExplodedGraph;
class GRState;
class EndOfFunctionNodeBuilder;
+ class BranchNodeBuilder;
class MemRegion;
class SymbolReaper;
@@ -202,6 +203,10 @@ public:
/// \brief Run checkers for end of path.
void runCheckersForEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng);
+ /// \brief Run checkers for branch condition.
+ void runCheckersForBranchCondition(const Stmt *condition,
+ BranchNodeBuilder &B, ExprEngine &Eng);
+
/// \brief Run checkers for live symbols.
void runCheckersForLiveSymbols(const GRState *state,
SymbolReaper &SymReaper);
@@ -239,7 +244,6 @@ public:
typedef CheckerFn<const Decl *, AnalysisManager&, BugReporter &>
CheckDeclFunc;
- typedef CheckerFn<const Stmt *, CheckerContext &> CheckStmtFunc;
typedef bool (*HandlesDeclFunc)(const Decl *D);
void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
@@ -250,6 +254,7 @@ public:
// Internal registration functions for path-sensitive checking.
//===----------------------------------------------------------------------===//
+ typedef CheckerFn<const Stmt *, CheckerContext &> CheckStmtFunc;
typedef CheckerFn<const ObjCMessage &, CheckerContext &> CheckObjCMessageFunc;
typedef CheckerFn<const SVal &/*location*/, bool/*isLoad*/, CheckerContext &>
CheckLocationFunc;
@@ -258,6 +263,8 @@ public:
typedef CheckerFn<ExplodedGraph &, BugReporter &, ExprEngine &>
CheckEndAnalysisFunc;
typedef CheckerFn<EndOfFunctionNodeBuilder &, ExprEngine &> CheckEndPathFunc;
+ typedef CheckerFn<const Stmt *, BranchNodeBuilder &, ExprEngine &>
+ CheckBranchConditionFunc;
typedef CheckerFn<SymbolReaper &, CheckerContext &> CheckDeadSymbolsFunc;
typedef CheckerFn<const GRState *, SymbolReaper &> CheckLiveSymbolsFunc;
@@ -278,6 +285,8 @@ public:
void _registerForEndPath(CheckEndPathFunc checkfn);
+ void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
+
void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
@@ -415,6 +424,8 @@ private:
std::vector<CheckEndPathFunc> EndPathCheckers;
+ std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
+
std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
diff --git a/include/clang/StaticAnalyzer/Core/CheckerV2.h b/include/clang/StaticAnalyzer/Core/CheckerV2.h
index 7dbbd32ae9..931cee9931 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerV2.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerV2.h
@@ -190,6 +190,22 @@ public:
}
};
+class BranchCondition {
+ template <typename CHECKER>
+ static void _checkBranchCondition(void *checker, const Stmt *condition,
+ BranchNodeBuilder &B, ExprEngine &Eng) {
+ ((const CHECKER *)checker)->checkBranchCondition(condition, B, Eng);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForBranchCondition(
+ CheckerManager::CheckBranchConditionFunc(checker,
+ _checkBranchCondition<CHECKER>));
+ }
+};
+
class LiveSymbols {
template <typename CHECKER>
static void _checkLiveSymbols(void *checker, const GRState *state,
diff --git a/lib/StaticAnalyzer/Checkers/Checkers.td b/lib/StaticAnalyzer/Checkers/Checkers.td
index 6599b96b00..1a2205fd5b 100644
--- a/lib/StaticAnalyzer/Checkers/Checkers.td
+++ b/lib/StaticAnalyzer/Checkers/Checkers.td
@@ -75,6 +75,10 @@ def ObjCUnusedIvarsChecker : Checker<"UnusedIvars">,
let ParentPackage = Core in {
+def UndefBranchChecker : Checker<"UndefBranch">,
+ HelpText<"Check for undefined branch conditions">,
+ DescFile<"UndefBranchChecker.cpp">;
+
def UndefCapturedBlockVarChecker : Checker<"UndefBlockVar">,
HelpText<"Check for blocks that capture uninitialized values">,
DescFile<"UndefCapturedBlockVarChecker.cpp">;
diff --git a/lib/StaticAnalyzer/Checkers/ExprEngine.cpp b/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
index f39c7b9d73..00d13783cb 100644
--- a/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
@@ -330,7 +330,6 @@ static void RegisterInternalChecks(ExprEngine &Eng) {
RegisterReturnUndefChecker(Eng);
RegisterUndefinedArraySubscriptChecker(Eng);
RegisterUndefinedAssignmentChecker(Eng);
- RegisterUndefBranchChecker(Eng);
}
ExprEngine::ExprEngine(AnalysisManager &mgr, TransferFuncs *tf)
@@ -1319,6 +1318,8 @@ void ExprEngine::processBranch(const Stmt* Condition, const Stmt* Term,
checker->VisitBranchCondition(builder, *this, Condition, tag);
}
+ getCheckerManager().runCheckersForBranchCondition(Condition, builder, *this);
+
// If the branch condition is undefined, return;
if (!builder.isFeasible(true) && !builder.isFeasible(false))
return;
diff --git a/lib/StaticAnalyzer/Checkers/InternalChecks.h b/lib/StaticAnalyzer/Checkers/InternalChecks.h
index 421b616456..42bd9687dc 100644
--- a/lib/StaticAnalyzer/Checkers/InternalChecks.h
+++ b/lib/StaticAnalyzer/Checkers/InternalChecks.h
@@ -28,7 +28,6 @@ void RegisterCallAndMessageChecker(ExprEngine &Eng);
void RegisterDereferenceChecker(ExprEngine &Eng);
void RegisterDivZeroChecker(ExprEngine &Eng);
void RegisterReturnUndefChecker(ExprEngine &Eng);
-void RegisterUndefBranchChecker(ExprEngine &Eng);
void RegisterUndefinedArraySubscriptChecker(ExprEngine &Eng);
void RegisterUndefinedAssignmentChecker(ExprEngine &Eng);
void RegisterVLASizeChecker(ExprEngine &Eng);
diff --git a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
index 14ae9edc7b..0902d91fff 100644
--- a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
@@ -12,17 +12,19 @@
//
//===----------------------------------------------------------------------===//
-#include "InternalChecks.h"
+#include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/CheckerV2.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Checker.h"
using namespace clang;
using namespace ento;
namespace {
-class UndefBranchChecker : public Checker {
- BuiltinBug *BT;
+class UndefBranchChecker : public CheckerV2<check::BranchCondition> {
+ mutable llvm::OwningPtr<BuiltinBug> BT;
struct FindUndefExpr {
GRStateManager& VM;
@@ -48,26 +50,15 @@ class UndefBranchChecker : public Checker {
};
public:
- UndefBranchChecker() : BT(0) {}
- static void *getTag();
- void VisitBranchCondition(BranchNodeBuilder &Builder, ExprEngine &Eng,
- const Stmt *Condition, void *tag);
+ void checkBranchCondition(const Stmt *Condition, BranchNodeBuilder &Builder,
+ ExprEngine &Eng) const;
};
}
-void ento::RegisterUndefBranchChecker(ExprEngine &Eng) {
- Eng.registerCheck(new UndefBranchChecker());
-}
-
-void *UndefBranchChecker::getTag() {
- static int x;
- return &x;
-}
-
-void UndefBranchChecker::VisitBranchCondition(BranchNodeBuilder &Builder,
- ExprEngine &Eng,
- const Stmt *Condition, void *tag){
+void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
+ BranchNodeBuilder &Builder,
+ ExprEngine &Eng) const {
const GRState *state = Builder.getState();
SVal X = state->getSVal(Condition);
if (X.isUndef()) {
@@ -75,7 +66,8 @@ void UndefBranchChecker::VisitBranchCondition(BranchNodeBuilder &Builder,
if (N) {
N->markAsSink();
if (!BT)
- BT = new BuiltinBug("Branch condition evaluates to a garbage value");
+ BT.reset(
+ new BuiltinBug("Branch condition evaluates to a garbage value"));
// What's going on here: we want to highlight the subexpression of the
// condition that is the most likely source of the "uninitialized
@@ -118,3 +110,7 @@ void UndefBranchChecker::VisitBranchCondition(BranchNodeBuilder &Builder,
Builder.markInfeasible(false);
}
}
+
+void ento::registerUndefBranchChecker(CheckerManager &mgr) {
+ mgr.registerChecker<UndefBranchChecker>();
+}
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp
index 0a4e847ef4..4776f5702d 100644
--- a/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -256,6 +256,16 @@ void CheckerManager::runCheckersForEndPath(EndOfFunctionNodeBuilder &B,
}
}
+/// \brief Run checkers for branch condition.
+void CheckerManager::runCheckersForBranchCondition(const Stmt *condition,
+ BranchNodeBuilder &B,
+ ExprEngine &Eng) {
+ for (unsigned i = 0, e = BranchConditionCheckers.size(); i != e; ++i) {
+ CheckBranchConditionFunc fn = BranchConditionCheckers[i];
+ fn(condition, B, Eng);
+ }
+}
+
/// \brief Run checkers for live symbols.
void CheckerManager::runCheckersForLiveSymbols(const GRState *state,
SymbolReaper &SymReaper) {
@@ -431,6 +441,11 @@ void CheckerManager::_registerForEndPath(CheckEndPathFunc checkfn) {
EndPathCheckers.push_back(checkfn);
}
+void CheckerManager::_registerForBranchCondition(
+ CheckBranchConditionFunc checkfn) {
+ BranchConditionCheckers.push_back(checkfn);
+}
+
void CheckerManager::_registerForLiveSymbols(CheckLiveSymbolsFunc checkfn) {
LiveSymbolsCheckers.push_back(checkfn);
}
diff --git a/test/Analysis/new.cpp b/test/Analysis/new.cpp
index f26eecd4b1..b32063788f 100644
--- a/test/Analysis/new.cpp
+++ b/test/Analysis/new.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-checker=core -analyzer-store region -verify %s
void f1() {
int *n = new int;