[cfe-commits] r142453 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/Checker.h include/clang/StaticAnalyzer/Core/CheckerManager.h include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp lib/StaticAnalyzer/Core/CheckerManager.cpp lib/StaticAnalyzer/Core/CoreEngine.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp
Anna Zaks
ganna at apple.com
Tue Oct 18 16:06:44 PDT 2011
Author: zaks
Date: Tue Oct 18 18:06:44 2011
New Revision: 142453
URL: http://llvm.org/viewvc/llvm-project?rev=142453&view=rev
Log:
[analyzer] Make NodeBuilder and Pred node loosely coupled
NodeBuilder should not assume it's dealing with a single predecessor. Remove predecessor getters. Modify the BranchNodeBuilder to not be responsible for doing auto-transitions (which depend on a predecessor).
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.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/Checker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h?rev=142453&r1=142452&r2=142453&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h Tue Oct 18 18:06:44 2011
@@ -215,8 +215,9 @@
class BranchCondition {
template <typename CHECKER>
static void _checkBranchCondition(void *checker, const Stmt *condition,
- NodeBuilder &B, ExprEngine &Eng) {
- ((const CHECKER *)checker)->checkBranchCondition(condition, B, Eng);
+ NodeBuilder &B, ExplodedNode *Pred,
+ ExprEngine &Eng) {
+ ((const CHECKER *)checker)->checkBranchCondition(condition, B, Pred, Eng);
}
public:
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h?rev=142453&r1=142452&r2=142453&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h Tue Oct 18 18:06:44 2011
@@ -232,7 +232,8 @@
/// \brief Run checkers for branch condition.
void runCheckersForBranchCondition(const Stmt *condition,
- NodeBuilder &B, ExprEngine &Eng);
+ NodeBuilder &B, ExplodedNode *Pred,
+ ExprEngine &Eng);
/// \brief Run checkers for live symbols.
///
@@ -334,7 +335,8 @@
typedef CheckerFn<void (EndOfFunctionNodeBuilder &, ExprEngine &)>
CheckEndPathFunc;
- typedef CheckerFn<void (const Stmt *, NodeBuilder &, ExprEngine &)>
+ typedef CheckerFn<void (const Stmt *, NodeBuilder &, ExplodedNode *Pred,
+ ExprEngine &)>
CheckBranchConditionFunc;
typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
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=142453&r1=142452&r2=142453&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h Tue Oct 18 18:06:44 2011
@@ -191,6 +191,8 @@
/// is set to false, autotransitions are yet to be generated.
bool Finalized;
+ bool HasGeneratedNodes;
+
/// \brief The frontier set - a set of nodes which need to be propagated after
/// the builder dies.
typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy;
@@ -218,14 +220,14 @@
public:
NodeBuilder(ExplodedNode *N, NodeBuilderContext &Ctx, bool F = true)
- : BuilderPred(N), C(Ctx), Finalized(F) {
+ : BuilderPred(N), C(Ctx), Finalized(F), HasGeneratedNodes(false) {
assert(!N->isSink());
Deferred.insert(N);
}
/// Create a new builder using the parent builder's context.
NodeBuilder(ExplodedNode *N, const NodeBuilder &ParentBldr, bool F = true)
- : BuilderPred(N), C(ParentBldr.C), Finalized(F) {
+ : BuilderPred(N), C(ParentBldr.C), Finalized(F), HasGeneratedNodes(false) {
assert(!N->isSink());
Deferred.insert(N);
}
@@ -243,8 +245,9 @@
return generateNodeImpl(PP, State, Pred, MarkAsSink);
}
+ // TODO: will get removed.
bool hasGeneratedNodes() const {
- return (!Deferred.count(BuilderPred));
+ return HasGeneratedNodes;
}
typedef DeferredTy::iterator iterator;
@@ -269,12 +272,6 @@
BuilderPred->getLocationContext()->getCurrentStackFrame(),
C.Block->getBlockID());
}
-
- // \brief Get the builder's predecessor - the parent to all the other nodes.
- ExplodedNode *getPredecessor() const { return BuilderPred; }
-
- // \brief Returns state of the predecessor.
- const ProgramState *getState() const { return BuilderPred->getState(); }
};
class CommonNodeBuilder {
@@ -366,7 +363,7 @@
}
void importNodesFromBuilder(const NodeBuilder &NB) {
- ExplodedNode *NBPred = const_cast<ExplodedNode*>(NB.getPredecessor());
+ ExplodedNode *NBPred = const_cast<ExplodedNode*>(NB.BuilderPred);
if (NB.hasGeneratedNodes()) {
Deferred.erase(NBPred);
Deferred.insert(NB.Deferred.begin(), NB.Deferred.end());
@@ -378,35 +375,20 @@
const CFGBlock *DstT;
const CFGBlock *DstF;
- bool GeneratedTrue;
- bool GeneratedFalse;
bool InFeasibleTrue;
bool InFeasibleFalse;
- /// Generate default branching transitions of none were generated or
- /// suppressed.
- void finalizeResults() {
- if (Finalized)
- return;
- if (!GeneratedTrue) generateNode(BuilderPred->State, true);
- if (!GeneratedFalse) generateNode(BuilderPred->State, false);
- Finalized = true;
- }
-
public:
BranchNodeBuilder(ExplodedNode *Pred, NodeBuilderContext &C,
const CFGBlock *dstT, const CFGBlock *dstF)
- : NodeBuilder(Pred, C, false), DstT(dstT), DstF(dstF),
- GeneratedTrue(false), GeneratedFalse(false),
- InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
- }
+ : NodeBuilder(Pred, C), DstT(dstT), DstF(dstF),
+ InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
/// Create a new builder using the parent builder's context.
BranchNodeBuilder(ExplodedNode *Pred, BranchNodeBuilder &ParentBldr)
- : NodeBuilder(Pred, ParentBldr, false), DstT(ParentBldr.DstT),
- DstF(ParentBldr.DstF), GeneratedTrue(false), GeneratedFalse(false),
- InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
- }
+ : NodeBuilder(Pred, ParentBldr), DstT(ParentBldr.DstT),
+ DstF(ParentBldr.DstF),
+ InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
ExplodedNode *generateNode(const ProgramState *State, bool branch,
ExplodedNode *Pred = 0);
@@ -417,9 +399,9 @@
void markInfeasible(bool branch) {
if (branch)
- InFeasibleTrue = GeneratedTrue = true;
+ InFeasibleTrue = true;
else
- InFeasibleFalse = GeneratedFalse = true;
+ InFeasibleFalse = true;
}
bool isFeasible(bool branch) {
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=142453&r1=142452&r2=142453&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Tue Oct 18 18:06:44 2011
@@ -132,16 +132,20 @@
/// processCFGElement - Called by CoreEngine. Used to generate new successor
/// nodes by processing the 'effects' of a CFG element.
- void processCFGElement(const CFGElement E, StmtNodeBuilder& builder);
+ void processCFGElement(const CFGElement E, StmtNodeBuilder& Bldr,
+ ExplodedNode *Pred);
- void ProcessStmt(const CFGStmt S, StmtNodeBuilder &builder);
+ void ProcessStmt(const CFGStmt S, StmtNodeBuilder &builder,
+ ExplodedNode *Pred);
- void ProcessInitializer(const CFGInitializer I, StmtNodeBuilder &builder);
+ void ProcessInitializer(const CFGInitializer I, StmtNodeBuilder &Bldr,
+ ExplodedNode *Pred);
- void ProcessImplicitDtor(const CFGImplicitDtor D, StmtNodeBuilder &builder);
+ void ProcessImplicitDtor(const CFGImplicitDtor D, StmtNodeBuilder &builder,
+ ExplodedNode *Pred);
void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D,
- StmtNodeBuilder &builder);
+ StmtNodeBuilder &builder, ExplodedNode *Pred);
void ProcessBaseDtor(const CFGBaseDtor D, StmtNodeBuilder &builder);
void ProcessMemberDtor(const CFGMemberDtor D, StmtNodeBuilder &builder);
void ProcessTemporaryDtor(const CFGTemporaryDtor D,
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h?rev=142453&r1=142452&r2=142453&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h Tue Oct 18 18:06:44 2011
@@ -55,7 +55,8 @@
/// Called by CoreEngine. Used to generate new successor
/// nodes by processing the 'effects' of a block-level statement.
- virtual void processCFGElement(const CFGElement E, StmtNodeBuilder& builder)=0;
+ virtual void processCFGElement(const CFGElement E, StmtNodeBuilder& builder,
+ ExplodedNode* Pred)=0;
/// Called by CoreEngine when it starts processing a CFGBlock. The
/// SubEngine is expected to populate dstNodes with new nodes representing
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp?rev=142453&r1=142452&r2=142453&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp Tue Oct 18 18:06:44 2011
@@ -50,26 +50,26 @@
public:
void checkBranchCondition(const Stmt *Condition, NodeBuilder &Builder,
- ExprEngine &Eng) const;
+ ExplodedNode *Pred, ExprEngine &Eng) const;
};
}
void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
NodeBuilder &Builder,
+ ExplodedNode *Pred,
ExprEngine &Eng) const {
- const ProgramState *state = Builder.getState();
+ const ProgramState *state = Pred->getState();
SVal X = state->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,
- Builder.getPredecessor()->getLocationContext(), Tag);
+ 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,
- Builder.getPredecessor(), true);
+ Pred, true);
if (N) {
if (!BT)
BT.reset(
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp?rev=142453&r1=142452&r2=142453&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp Tue Oct 18 18:06:44 2011
@@ -298,10 +298,11 @@
/// \brief Run checkers for branch condition.
void CheckerManager::runCheckersForBranchCondition(const Stmt *condition,
NodeBuilder &B,
+ ExplodedNode *Pred,
ExprEngine &Eng) {
for (unsigned i = 0, e = BranchConditionCheckers.size(); i != e; ++i) {
CheckBranchConditionFunc fn = BranchConditionCheckers[i];
- fn(condition, B, Eng);
+ fn(condition, B, Pred, Eng);
}
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=142453&r1=142452&r2=142453&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Tue Oct 18 18:06:44 2011
@@ -316,7 +316,7 @@
if (CFGElement E = L.getFirstElement()) {
NodeBuilderContext Ctx(*this, L.getBlock());
StmtNodeBuilder Builder(Pred, 0, Ctx);
- SubEng.processCFGElement(E, Builder);
+ SubEng.processCFGElement(E, Builder, Pred);
}
else
HandleBlockExit(L.getBlock(), Pred);
@@ -433,7 +433,7 @@
else {
NodeBuilderContext Ctx(*this, B);
StmtNodeBuilder Builder(Pred, StmtIdx, Ctx);
- SubEng.processCFGElement((*B)[StmtIdx], Builder);
+ SubEng.processCFGElement((*B)[StmtIdx], Builder, Pred);
}
}
@@ -489,6 +489,8 @@
const ProgramState *State,
ExplodedNode *FromN,
bool MarkAsSink) {
+ HasGeneratedNodes = true;
+
bool IsNew;
ExplodedNode *N = C.Eng.G->getNode(Loc, State, &IsNew);
N->addPredecessor(FromN, *C.Eng.G);
@@ -567,9 +569,6 @@
ExplodedNode *BranchNodeBuilder::generateNode(const ProgramState *State,
bool branch,
ExplodedNode *NodePred) {
- assert(Finalized == false &&
- "We cannot create new nodes after the results have been finalized.");
-
// If the branch has been marked infeasible we should not generate a node.
if (!isFeasible(branch))
return NULL;
@@ -579,12 +578,6 @@
ProgramPoint Loc = BlockEdge(C.Block, branch ? DstT:DstF,
NodePred->getLocationContext());
ExplodedNode *Succ = generateNodeImpl(Loc, State, NodePred);
-
- if (branch)
- GeneratedTrue = true;
- else
- GeneratedFalse = true;
-
return Succ;
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=142453&r1=142452&r2=142453&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Oct 18 18:06:44 2011
@@ -196,26 +196,29 @@
}
void ExprEngine::processCFGElement(const CFGElement E,
- StmtNodeBuilder& builder) {
+ StmtNodeBuilder& Bldr,
+ ExplodedNode *Pred) {
switch (E.getKind()) {
case CFGElement::Invalid:
llvm_unreachable("Unexpected CFGElement kind.");
case CFGElement::Statement:
- ProcessStmt(const_cast<Stmt*>(E.getAs<CFGStmt>()->getStmt()), builder);
+ ProcessStmt(const_cast<Stmt*>(E.getAs<CFGStmt>()->getStmt()), Bldr, Pred);
return;
case CFGElement::Initializer:
- ProcessInitializer(E.getAs<CFGInitializer>()->getInitializer(), builder);
+ ProcessInitializer(E.getAs<CFGInitializer>()->getInitializer(),
+ Bldr, Pred);
return;
case CFGElement::AutomaticObjectDtor:
case CFGElement::BaseDtor:
case CFGElement::MemberDtor:
case CFGElement::TemporaryDtor:
- ProcessImplicitDtor(*E.getAs<CFGImplicitDtor>(), builder);
+ ProcessImplicitDtor(*E.getAs<CFGImplicitDtor>(), Bldr, Pred);
return;
}
}
-void ExprEngine::ProcessStmt(const CFGStmt S, StmtNodeBuilder& builder) {
+void ExprEngine::ProcessStmt(const CFGStmt S, StmtNodeBuilder& builder,
+ ExplodedNode *Pred) {
// TODO: Use RAII to remove the unnecessary, tagged nodes.
//RegisterCreatedNodes registerCreatedNodes(getGraph());
@@ -232,7 +235,7 @@
// A tag to track convenience transitions, which can be removed at cleanup.
static SimpleProgramPointTag cleanupTag("ExprEngine : Clean Node");
Builder = &builder;
- EntryNode = builder.getPredecessor();
+ EntryNode = Pred;
const ProgramState *EntryState = EntryNode->getState();
CleanedState = EntryState;
@@ -320,12 +323,10 @@
}
void ExprEngine::ProcessInitializer(const CFGInitializer Init,
- StmtNodeBuilder &builder) {
+ StmtNodeBuilder &builder,
+ ExplodedNode *pred) {
// We don't set EntryNode and currentStmt. And we don't clean up state.
const CXXCtorInitializer *BMI = Init.getInitializer();
-
- ExplodedNode *pred = builder.getPredecessor();
-
const StackFrameContext *stackFrame = cast<StackFrameContext>(pred->getLocationContext());
const CXXConstructorDecl *decl = cast<CXXConstructorDecl>(stackFrame->getDecl());
const CXXThisRegion *thisReg = getCXXThisRegion(decl, stackFrame);
@@ -373,12 +374,13 @@
}
void ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D,
- StmtNodeBuilder &builder) {
+ StmtNodeBuilder &builder,
+ ExplodedNode *Pred) {
Builder = &builder;
switch (D.getKind()) {
case CFGElement::AutomaticObjectDtor:
- ProcessAutomaticObjDtor(cast<CFGAutomaticObjDtor>(D), builder);
+ ProcessAutomaticObjDtor(cast<CFGAutomaticObjDtor>(D), builder, Pred);
break;
case CFGElement::BaseDtor:
ProcessBaseDtor(cast<CFGBaseDtor>(D), builder);
@@ -395,8 +397,8 @@
}
void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor dtor,
- StmtNodeBuilder &builder) {
- ExplodedNode *pred = builder.getPredecessor();
+ StmtNodeBuilder &builder,
+ ExplodedNode *pred) {
const ProgramState *state = pred->getState();
const VarDecl *varDecl = dtor.getVarDecl();
@@ -949,6 +951,7 @@
if (!Condition) {
BranchNodeBuilder NullCondBldr(Pred, BldCtx, DstT, DstF);
NullCondBldr.markInfeasible(false);
+ NullCondBldr.generateNode(Pred->getState(), true, Pred);
Engine.enqueue(NullCondBldr);
return;
}
@@ -959,7 +962,7 @@
NodeBuilder CheckerBldr(Pred, BldCtx);
getCheckerManager().runCheckersForBranchCondition(Condition, CheckerBldr,
- *this);
+ Pred, *this);
for (NodeBuilder::iterator I = CheckerBldr.results_begin(),
E = CheckerBldr.results_end(); E != I; ++I) {
@@ -969,7 +972,7 @@
continue;
BranchNodeBuilder builder(PredI, BldCtx, DstT, DstF);
- const ProgramState *PrevState = builder.getState();
+ const ProgramState *PrevState = Pred->getState();
SVal X = PrevState->getSVal(Condition);
if (X.isUnknownOrUndef()) {
@@ -992,8 +995,8 @@
}
// If the condition is still unknown, give up.
if (X.isUnknownOrUndef()) {
- builder.generateNode(MarkBranch(PrevState, Term, true), true);
- builder.generateNode(MarkBranch(PrevState, Term, false), false);
+ builder.generateNode(MarkBranch(PrevState, Term, true), true, PredI);
+ builder.generateNode(MarkBranch(PrevState, Term, false), false, PredI);
// Enqueue the results into the work list.
Engine.enqueue(builder);
continue;
@@ -1004,7 +1007,7 @@
// Process the true branch.
if (builder.isFeasible(true)) {
if (const ProgramState *state = PrevState->assume(V, true))
- builder.generateNode(MarkBranch(state, Term, true), true);
+ builder.generateNode(MarkBranch(state, Term, true), true, PredI);
else
builder.markInfeasible(true);
}
@@ -1012,7 +1015,7 @@
// Process the false branch.
if (builder.isFeasible(false)) {
if (const ProgramState *state = PrevState->assume(V, false))
- builder.generateNode(MarkBranch(state, Term, false), false);
+ builder.generateNode(MarkBranch(state, Term, false), false, PredI);
else
builder.markInfeasible(false);
}
More information about the cfe-commits
mailing list