summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-04-24 23:35:58 +0000
committerTed Kremenek <kremenek@apple.com>2008-04-24 23:35:58 +0000
commitae8014cb7eb951e25962d5134c8f8cc740859af8 (patch)
treea5ad23720258d8928b3bfa8c78a9f4369d76cd2b /clang
parenta42d24003d01502b7e1dd469d9fdc239eb2355db (diff)
downloadbcm5719-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.h12
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h10
-rw-r--r--clang/lib/Analysis/GRExprEngine.cpp61
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) {
OpenPOWER on IntegriCloud