diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-04-24 23:35:58 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-04-24 23:35:58 +0000 |
commit | ae8014cb7eb951e25962d5134c8f8cc740859af8 (patch) | |
tree | a5ad23720258d8928b3bfa8c78a9f4369d76cd2b /clang | |
parent | a42d24003d01502b7e1dd469d9fdc239eb2355db (diff) | |
download | bcm5719-llvm-ae8014cb7eb951e25962d5134c8f8cc740859af8.tar.gz bcm5719-llvm-ae8014cb7eb951e25962d5134c8f8cc740859af8.zip |
More boilerplate for handling specialized-transfer function logic for dead symbols.
llvm-svn: 50233
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Analysis/PathSensitive/GRExprEngine.h | 12 | ||||
-rw-r--r-- | clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h | 10 | ||||
-rw-r--r-- | clang/lib/Analysis/GRExprEngine.cpp | 61 |
3 files changed, 47 insertions, 36 deletions
diff --git a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h index 819043edb46..de8807a2018 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -78,12 +78,12 @@ protected: /// SymMgr - Object that manages the symbol information. SymbolManager& SymMgr; - /// StmtEntryNode - The immediate predecessor node. - NodeTy* StmtEntryNode; - - /// CleanedState - The state for StmtEntryNode "cleaned" of all dead + /// EntryNode - The immediate predecessor node. + NodeTy* EntryNode; + + /// CleanedState - The state for EntryNode "cleaned" of all dead /// variables and symbols (as determined by a liveness analysis). - ValueState* CleanedState; + ValueState* CleanedState; /// CurrentStmt - The current block-level statement. Stmt* CurrentStmt; @@ -392,7 +392,7 @@ public: protected: ValueState* GetState(NodeTy* N) { - return N == StmtEntryNode ? CleanedState : N->getState(); + return N == EntryNode ? CleanedState : N->getState(); } ValueState* SetRVal(ValueState* St, Expr* Ex, RVal V); diff --git a/clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h index 47f5d2a59d0..769353039c0 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h +++ b/clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h @@ -84,11 +84,19 @@ public: ValueState* St, RVal TargetLV, RVal Val); - // End-of-path. + // End-of-path and dead symbol notification. virtual void EvalEndPath(GRExprEngine& Engine, GREndPathNodeBuilder<ValueState>& Builder) {} + + virtual void EvalDeadSymbols(ExplodedNodeSet<ValueState>& Dst, + GRExprEngine& Engine, + GRStmtNodeBuilder<ValueState>& Builder, + ProgramPoint P, ExplodedNode<ValueState>* Pred, + ValueState* St, + const ValueStateManager::DeadSymbolsTy& Dead) {} + // Return statements. virtual void EvalReturn(ExplodedNodeSet<ValueState>& Dst, 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) { |