diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-02-28 01:27:33 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-02-28 01:27:33 +0000 |
commit | cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9 (patch) | |
tree | ed9f7de5944690615d97478e98accdc664a82574 | |
parent | 265c674f634e99e5df1135d764e21365351372da (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.h | 13 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Core/CheckerV2.h | 16 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/Checkers.td | 4 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/ExprEngine.cpp | 3 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/InternalChecks.h | 1 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp | 38 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/CheckerManager.cpp | 15 | ||||
-rw-r--r-- | test/Analysis/new.cpp | 2 |
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; |