diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Analysis/GRExprEngine.cpp | 61 |
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) { |