diff options
-rw-r--r-- | include/clang/StaticAnalyzer/Core/Checker.h | 7 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Core/CheckerManager.h | 5 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp | 19 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/CheckerManager.cpp | 36 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngine.cpp | 21 |
5 files changed, 53 insertions, 35 deletions
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h index 181080a213..358510ef0b 100644 --- a/include/clang/StaticAnalyzer/Core/Checker.h +++ b/include/clang/StaticAnalyzer/Core/Checker.h @@ -214,10 +214,9 @@ public: class BranchCondition { template <typename CHECKER> - static void _checkBranchCondition(void *checker, const Stmt *condition, - NodeBuilder &B, ExplodedNode *Pred, - ExprEngine &Eng) { - ((const CHECKER *)checker)->checkBranchCondition(condition, B, Pred, Eng); + static void _checkBranchCondition(void *checker, const Stmt *Condition, + CheckerContext & C) { + ((const CHECKER *)checker)->checkBranchCondition(Condition, C); } public: diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h index e74bd8b826..806085460b 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -236,7 +236,7 @@ public: /// \brief Run checkers for branch condition. void runCheckersForBranchCondition(const Stmt *condition, - NodeBuilder &B, ExplodedNode *Pred, + ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng); /// \brief Run checkers for live symbols. @@ -339,8 +339,7 @@ public: typedef CheckerFn<void (CheckerContext &)> CheckEndPathFunc; - typedef CheckerFn<void (const Stmt *, NodeBuilder &, ExplodedNode *Pred, - ExprEngine &)> + typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckBranchConditionFunc; typedef CheckerFn<void (SymbolReaper &, CheckerContext &)> diff --git a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp index d030469459..afb79b5d16 100644 --- a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp @@ -49,27 +49,18 @@ class UndefBranchChecker : public Checker<check::BranchCondition> { }; public: - void checkBranchCondition(const Stmt *Condition, NodeBuilder &Builder, - ExplodedNode *Pred, ExprEngine &Eng) const; + void checkBranchCondition(const Stmt *Condition, CheckerContext &Ctx) const; }; } void UndefBranchChecker::checkBranchCondition(const Stmt *Condition, - NodeBuilder &Builder, - ExplodedNode *Pred, - ExprEngine &Eng) const { - const ProgramState *state = Pred->getState(); - SVal X = state->getSVal(Condition); + CheckerContext &Ctx) const { + SVal X = Ctx.getState()->getSVal(Condition); if (X.isUndef()) { - // TODO: The PP will be generated with the correct tag by the CheckerManager - // after we migrate the callback to CheckerContext. - const ProgramPointTag *Tag = 0; - ProgramPoint PP = PostCondition(Condition, Pred->getLocationContext(), Tag); // Generate a sink node, which implicitly marks both outgoing branches as // infeasible. - ExplodedNode *N = Builder.generateNode(PP, state, - Pred, true); + ExplodedNode *N = Ctx.generateSink(); if (N) { if (!BT) BT.reset( @@ -107,7 +98,7 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition, R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex)); R->addRange(Ex->getSourceRange()); - Eng.getBugReporter().EmitReport(R); + Ctx.EmitReport(R); } } } diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp index 67fe4d6ca2..ecb1a7a4ce 100644 --- a/lib/StaticAnalyzer/Core/CheckerManager.cpp +++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp @@ -320,15 +320,39 @@ void CheckerManager::runCheckersForEndPath(NodeBuilderContext &BC, } } +namespace { + struct CheckBranchConditionContext { + typedef std::vector<CheckerManager::CheckBranchConditionFunc> CheckersTy; + const CheckersTy &Checkers; + const Stmt *Condition; + ExprEngine &Eng; + + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } + + CheckBranchConditionContext(const CheckersTy &checkers, + const Stmt *Cond, ExprEngine &eng) + : Checkers(checkers), Condition(Cond), Eng(eng) {} + + void runChecker(CheckerManager::CheckBranchConditionFunc checkFn, + NodeBuilder &Bldr, ExplodedNode *Pred) { + ProgramPoint L = PostCondition(Condition, Pred->getLocationContext(), + checkFn.Checker); + CheckerContext C(Bldr, Eng, Pred, L, 0); + checkFn(Condition, C); + } + }; +} + /// \brief Run checkers for branch condition. -void CheckerManager::runCheckersForBranchCondition(const Stmt *condition, - NodeBuilder &B, +void CheckerManager::runCheckersForBranchCondition(const Stmt *Condition, + ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng) { - for (unsigned i = 0, e = BranchConditionCheckers.size(); i != e; ++i) { - CheckBranchConditionFunc fn = BranchConditionCheckers[i]; - fn(condition, B, Pred, Eng); - } + ExplodedNodeSet Src; + Src.insert(Pred); + CheckBranchConditionContext C(BranchConditionCheckers, Condition, Eng); + expandGraphWithCheckers(C, Dst, Src); } /// \brief Run checkers for live symbols. diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 3e5a31cda0..8ba2cd80a2 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -217,10 +217,13 @@ void ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred, ProcessImplicitDtor(*E.getAs<CFGImplicitDtor>(), Pred); return; } + currentStmtIdx = 0; + currentBuilderContext = 0; } const Stmt *ExprEngine::getStmt() const { - const CFGStmt *CS = (*currentBuilderContext->getBlock())[currentStmtIdx].getAs<CFGStmt>(); + const CFGStmt *CS = (*currentBuilderContext->getBlock())[currentStmtIdx] + .getAs<CFGStmt>(); return CS ? CS->getStmt() : 0; } @@ -1033,6 +1036,8 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) { + currentBuilderContext = &BldCtx; + // Check for NULL conditions; e.g. "for(;;)" if (!Condition) { BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF); @@ -1045,17 +1050,16 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term, Condition->getLocStart(), "Error evaluating branch"); - ExplodedNodeSet TmpCheckersOut; - NodeBuilder CheckerBldr(Pred, TmpCheckersOut, BldCtx); - getCheckerManager().runCheckersForBranchCondition(Condition, CheckerBldr, + ExplodedNodeSet CheckersOutSet; + getCheckerManager().runCheckersForBranchCondition(Condition, CheckersOutSet, Pred, *this); // We generated only sinks. - if (TmpCheckersOut.empty()) + if (CheckersOutSet.empty()) return; - BranchNodeBuilder builder(CheckerBldr.getResults(), Dst, BldCtx, DstT, DstF); - for (NodeBuilder::iterator I = CheckerBldr.begin(), - E = CheckerBldr.end(); E != I; ++I) { + BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF); + for (NodeBuilder::iterator I = CheckersOutSet.begin(), + E = CheckersOutSet.end(); E != I; ++I) { ExplodedNode *PredI = *I; if (PredI->isSink()) @@ -1107,6 +1111,7 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term, builder.markInfeasible(false); } } + currentBuilderContext = 0; } /// processIndirectGoto - Called by CoreEngine. Used to generate successor |