[cfe-commits] r142827 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h lib/StaticAnalyzer/Core/CheckerContext.cpp lib/StaticAnalyzer/Core/CheckerManager.cpp lib/StaticAnalyzer/Core/CoreEngine.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp
Anna Zaks
ganna at apple.com
Mon Oct 24 11:25:59 PDT 2011
Author: zaks
Date: Mon Oct 24 13:25:58 2011
New Revision: 142827
URL: http://llvm.org/viewvc/llvm-project?rev=142827&view=rev
Log:
[analyzer] Use a temporary builder in CheckerContext.
First step toward removing the global Stmt builder. Added several transitional methods (like takeNodes/addNodes).
+ Stop early if the set of exploded nodes for the next iteration is empty.
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h?rev=142827&r1=142826&r2=142827&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h Mon Oct 24 13:25:58 2011
@@ -23,29 +23,24 @@
namespace ento {
class CheckerContext {
- ExplodedNodeSet &Dst;
ExprEngine &Eng;
ExplodedNode *Pred;
const ProgramPoint Location;
const ProgramState *ST;
- const unsigned size;
NodeBuilder &NB;
public:
bool *respondsToCallback;
public:
- CheckerContext(ExplodedNodeSet &dst,
- NodeBuilder &builder,
+ CheckerContext(NodeBuilder &builder,
ExprEngine &eng,
ExplodedNode *pred,
const ProgramPoint &loc,
bool *respondsToCB = 0,
const ProgramState *st = 0)
- : Dst(dst),
- Eng(eng),
+ : Eng(eng),
Pred(pred),
Location(loc),
ST(st),
- size(Dst.size()),
NB(builder),
respondsToCallback(respondsToCB) {
assert(!(ST && ST != Pred->getState()));
@@ -153,7 +148,6 @@
bool markAsSink,
ExplodedNode *pred = 0,
const ProgramPointTag *tag = 0) {
-
ExplodedNode *node = NB.generateNode(tag ? Location.withTag(tag) : Location,
state,
pred ? pred : Pred, markAsSink);
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h?rev=142827&r1=142826&r2=142827&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h Mon Oct 24 13:25:58 2011
@@ -202,6 +202,14 @@
return true;
}
+ bool haveNoSinksInFrontier() {
+ for (iterator I = Frontier.begin(), E = Frontier.end(); I != E; ++I) {
+ if ((*I)->isSink())
+ return false;
+ }
+ return true;
+ }
+
/// Allow subclasses to finalize results before result_begin() is executed.
virtual void finalizeResults() {}
@@ -214,13 +222,19 @@
NodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
const NodeBuilderContext &Ctx, bool F = true)
: C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) {
- Frontier.insert(SrcNode);
+ assert(DstSet.empty());
+ Frontier.Add(SrcNode);
}
NodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
const NodeBuilderContext &Ctx, bool F = true)
: C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) {
+ assert(DstSet.empty());
+ //assert(!SrcSet.empty());
+
Frontier.insert(SrcSet);
+
+ assert(haveNoSinksInFrontier());
}
virtual ~NodeBuilder() {}
@@ -365,13 +379,23 @@
return N;
}
- void importNodesFromBuilder(const NodeBuilder &NB) {
- ExplodedNode *NBPred = const_cast<ExplodedNode*>(NB.C.ContextPred);
- if (NB.hasGeneratedNodes()) {
- Frontier.erase(NBPred);
- Frontier.insert(NB.Frontier);
- }
+ void takeNodes(const ExplodedNodeSet &S) {
+ for (ExplodedNodeSet::iterator I = S.begin(), E = S.end(); I != E; ++I )
+ Frontier.erase(*I);
}
+
+ void takeNodes(ExplodedNode *N) {
+ Frontier.erase(N);
+ }
+
+ void addNodes(const ExplodedNodeSet &S) {
+ Frontier.insert(S);
+ }
+
+ void addNodes(ExplodedNode *N) {
+ Frontier.Add(N);
+ }
+
};
class BranchNodeBuilder: public NodeBuilder {
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp?rev=142827&r1=142826&r2=142827&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp Mon Oct 24 13:25:58 2011
@@ -16,10 +16,4 @@
using namespace clang;
using namespace ento;
-CheckerContext::~CheckerContext() {
- // Copy the results into the Dst set.
- for (NodeBuilder::iterator I = NB.begin(),
- E = NB.end(); I != E; ++I) {
- Dst.Add(*I);
- }
-}
+CheckerContext::~CheckerContext() {}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp?rev=142827&r1=142826&r2=142827&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp Mon Oct 24 13:25:58 2011
@@ -93,6 +93,9 @@
static void expandGraphWithCheckers(CHECK_CTX checkCtx,
ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src) {
+ const NodeBuilderContext &BldrCtx = checkCtx.Eng.getBuilderContext();
+ if (Src.empty())
+ return;
typename CHECK_CTX::CheckersTy::const_iterator
I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
@@ -113,9 +116,18 @@
CurrSet->clear();
}
+ NodeBuilder B(*PrevSet, *CurrSet, BldrCtx);
+ checkCtx.Eng.getBuilder().takeNodes(*PrevSet);
for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
- NI != NE; ++NI)
- checkCtx.runChecker(*I, *CurrSet, *NI);
+ NI != NE; ++NI) {
+ checkCtx.runChecker(*I, B, *NI);
+ }
+
+ // If all the produced transitions are sinks, stop.
+ if (CurrSet->empty())
+ return;
+
+ checkCtx.Eng.getBuilder().addNodes(*CurrSet);
// Update which NodeSet is the current one.
PrevSet = CurrSet;
@@ -138,13 +150,13 @@
: IsPreVisit(isPreVisit), Checkers(checkers), S(s), Eng(eng) { }
void runChecker(CheckerManager::CheckStmtFunc checkFn,
- ExplodedNodeSet &Dst, ExplodedNode *Pred) {
+ NodeBuilder &Bldr, ExplodedNode *Pred) {
// FIXME: Remove respondsToCallback from CheckerContext;
ProgramPoint::Kind K = IsPreVisit ? ProgramPoint::PreStmtKind :
ProgramPoint::PostStmtKind;
const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
Pred->getLocationContext(), checkFn.Checker);
- CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, L, 0);
+ CheckerContext C(Bldr, Eng, Pred, L, 0);
checkFn(S, C);
}
@@ -178,12 +190,12 @@
: IsPreVisit(isPreVisit), Checkers(checkers), Msg(msg), Eng(eng) { }
void runChecker(CheckerManager::CheckObjCMessageFunc checkFn,
- ExplodedNodeSet &Dst, ExplodedNode *Pred) {
+ NodeBuilder &Bldr, ExplodedNode *Pred) {
ProgramPoint::Kind K = IsPreVisit ? ProgramPoint::PreStmtKind :
ProgramPoint::PostStmtKind;
const ProgramPoint &L = ProgramPoint::getProgramPoint(Msg.getOriginExpr(),
K, Pred->getLocationContext(), checkFn.Checker);
- CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, L, 0);
+ CheckerContext C(Bldr, Eng, Pred, L, 0);
checkFn(Msg, C);
}
@@ -220,12 +232,12 @@
: Checkers(checkers), Loc(loc), IsLoad(isLoad), S(s), Eng(eng) { }
void runChecker(CheckerManager::CheckLocationFunc checkFn,
- ExplodedNodeSet &Dst, ExplodedNode *Pred) {
+ NodeBuilder &Bldr, ExplodedNode *Pred) {
ProgramPoint::Kind K = IsLoad ? ProgramPoint::PreLoadKind :
ProgramPoint::PreStoreKind;
const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
Pred->getLocationContext(), checkFn.Checker);
- CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, L, 0);
+ CheckerContext C(Bldr, Eng, Pred, L, 0);
checkFn(Loc, IsLoad, S, C);
}
@@ -258,11 +270,11 @@
: Checkers(checkers), Loc(loc), Val(val), S(s), Eng(eng) { }
void runChecker(CheckerManager::CheckBindFunc checkFn,
- ExplodedNodeSet &Dst, ExplodedNode *Pred) {
+ NodeBuilder &Bldr, ExplodedNode *Pred) {
ProgramPoint::Kind K = ProgramPoint::PreStmtKind;
const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
Pred->getLocationContext(), checkFn.Checker);
- CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, L, 0);
+ CheckerContext C(Bldr, Eng, Pred, L, 0);
checkFn(Loc, Val, S, C);
}
@@ -329,11 +341,11 @@
: Checkers(checkers), SR(sr), S(s), Eng(eng) { }
void runChecker(CheckerManager::CheckDeadSymbolsFunc checkFn,
- ExplodedNodeSet &Dst, ExplodedNode *Pred) {
+ NodeBuilder &Bldr, ExplodedNode *Pred) {
ProgramPoint::Kind K = ProgramPoint::PostPurgeDeadSymbolsKind;
const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
Pred->getLocationContext(), checkFn.Checker);
- CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, L, 0);
+ CheckerContext C(Bldr, Eng, Pred, L, 0);
checkFn(SR, C);
}
@@ -438,11 +450,13 @@
}
#endif
+ Eng.getBuilder().takeNodes(Pred);
+ ExplodedNodeSet checkDst;
+ NodeBuilder B(Pred, checkDst, Eng.getBuilderContext());
// Next, check if any of the EvalCall callbacks can evaluate the call.
for (std::vector<EvalCallFunc>::iterator
EI = EvalCallCheckers.begin(), EE = EvalCallCheckers.end();
EI != EE; ++EI) {
- ExplodedNodeSet checkDst;
ProgramPoint::Kind K = ProgramPoint::PostStmtKind;
const ProgramPoint &L = ProgramPoint::getProgramPoint(CE, K,
Pred->getLocationContext(), EI->Checker);
@@ -450,7 +464,7 @@
{ // CheckerContext generates transitions(populates checkDest) on
// destruction, so introduce the scope to make sure it gets properly
// populated.
- CheckerContext C(checkDst, Eng.getBuilder(), Eng, Pred, L, 0);
+ CheckerContext C(B, Eng, Pred, L, 0);
evaluated = (*EI)(CE, C);
}
assert(!(evaluated && anyEvaluated)
@@ -458,6 +472,7 @@
if (evaluated) {
anyEvaluated = true;
Dst.insert(checkDst);
+ Eng.getBuilder().addNodes(checkDst);
#ifdef NDEBUG
break; // on release don't check that no other checker also evals.
#endif
@@ -466,6 +481,7 @@
// If none of the checkers evaluated the call, ask ExprEngine to handle it.
if (!anyEvaluated) {
+ Eng.getBuilder().addNodes(Pred);
if (defaultEval)
defaultEval->expandGraph(Dst, Pred);
else
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=142827&r1=142826&r2=142827&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Mon Oct 24 13:25:58 2011
@@ -504,7 +504,7 @@
if (MarkAsSink)
N->markAsSink();
- if (IsNew)
+ if (IsNew && !MarkAsSink)
Frontier.Add(N);
return (IsNew ? N : 0);
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=142827&r1=142826&r2=142827&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Oct 24 13:25:58 2011
@@ -964,6 +964,9 @@
NodeBuilder CheckerBldr(Pred, TmpCheckersOut, BldCtx);
getCheckerManager().runCheckersForBranchCondition(Condition, CheckerBldr,
Pred, *this);
+ // We generated only sinks.
+ if (TmpCheckersOut.empty())
+ return;
BranchNodeBuilder builder(CheckerBldr.getResults(), Dst, BldCtx, DstT, DstF);
for (NodeBuilder::iterator I = CheckerBldr.begin(),
More information about the cfe-commits
mailing list