summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Analysis/GRExprEngine.cpp61
1 files changed, 32 insertions, 29 deletions
diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp
index a287e542981..0438059f6c2 100644
--- a/clang/lib/Analysis/GRExprEngine.cpp
+++ b/clang/lib/Analysis/GRExprEngine.cpp
@@ -42,7 +42,7 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx)
BasicVals(StateMgr.getBasicValueFactory()),
TF(NULL), // FIXME
SymMgr(StateMgr.getSymbolManager()),
- StmtEntryNode(NULL), CleanedState(NULL), CurrentStmt(NULL) {
+ CurrentStmt(NULL) {
// Compute liveness information.
Liveness.runOnCFG(G.getCFG());
@@ -167,9 +167,8 @@ ValueState* GRExprEngine::SetRVal(ValueState* St, Expr* Ex, RVal V) {
void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
Builder = &builder;
- StmtEntryNode = builder.getLastNode();
+ EntryNode = builder.getLastNode();
CurrentStmt = S;
- NodeSet Dst;
// Set up our simple checks.
@@ -187,49 +186,53 @@ void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
// Create the cleaned state.
- CleanedState = StateMgr.RemoveDeadBindings(StmtEntryNode->getState(),
- CurrentStmt, Liveness,
- DeadSymbols);
+ CleanedState = StateMgr.RemoveDeadBindings(EntryNode->getState(), CurrentStmt,
+ Liveness, DeadSymbols);
// Process any special transfer function for dead symbols.
NodeSet Tmp;
if (DeadSymbols.empty())
- Tmp.Add(StmtEntryNode);
+ Tmp.Add(EntryNode);
else {
SaveAndRestore<bool> OldSink(Builder->BuildSinks);
-/*
- FIXME: Will hook this up next.
-
- TF->EvalDeadSymbols(Tmp, *this, *Builder, StmtEntryNode->getLocation(), Pred,
- CleanedState, DeadSymbols);
-*/
- if (!Builder->BuildSinks && Tmp.empty() && !Builder->HasGeneratedNode)
- Tmp.Add(StmtEntryNode);
+ SaveOr OldHasGen(Builder->HasGeneratedNode);
+
+ TF->EvalDeadSymbols(Tmp, *this, *Builder, EntryNode->getLocation(),
+ EntryNode, CleanedState, DeadSymbols);
+
+ if (!Builder->BuildSinks && !Builder->HasGeneratedNode)
+ Tmp.Add(EntryNode);
}
-
+
+ bool HasAutoGenerated = false;
+
for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+
+ NodeSet Dst;
+
// Set the cleaned state.
- Builder->SetCleanedState(*I == StmtEntryNode ? CleanedState : (*I)->getState());
-
+ Builder->SetCleanedState(*I == EntryNode ? CleanedState : GetState(*I));
+
// Visit the statement.
- Visit(S, StmtEntryNode, Dst);
+ Visit(S, *I, Dst);
+
+ // Do we need to auto-generate a node? We only need to do this to generate
+ // a node with a "cleaned" state; GRCoreEngine will actually handle
+ // auto-transitions for other cases.
+ if (Dst.size() == 1 && *Dst.begin() == EntryNode
+ && !Builder->HasGeneratedNode && !HasAutoGenerated) {
+ HasAutoGenerated = true;
+ builder.generateNode(S, GetState(EntryNode), *I);
+ }
}
- // If no nodes were generated, generate a new node that has all the
- // dead mappings removed.
-
- if (Dst.size() == 1 && *Dst.begin() == StmtEntryNode &&
- !Builder->HasGeneratedNode)
- builder.generateNode(S, GetState(StmtEntryNode), StmtEntryNode);
-
// NULL out these variables to cleanup.
-
+ CleanedState = NULL;
+ EntryNode = NULL;
CurrentStmt = NULL;
- StmtEntryNode = NULL;
Builder = NULL;
- CleanedState = NULL;
}
void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) {
OpenPOWER on IntegriCloud