aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ExprEngine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp28
1 files changed, 22 insertions, 6 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 045591c907..42bfe144db 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -268,22 +268,39 @@ static bool shouldRemoveDeadBindings(AnalysisManager &AMgr,
void ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out,
const Stmt *ReferenceStmt,
- const StackFrameContext *LC,
+ const LocationContext *LC,
const Stmt *DiagnosticStmt,
ProgramPoint::Kind K) {
assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind ||
- ReferenceStmt == 0)
+ ReferenceStmt == 0 || isa<ReturnStmt>(ReferenceStmt))
&& "PostStmt is not generally supported by the SymbolReaper yet");
+ assert(LC && "Must pass the current (or expiring) LocationContext");
+
+ if (!DiagnosticStmt) {
+ DiagnosticStmt = ReferenceStmt;
+ assert(DiagnosticStmt && "Required for clearing a LocationContext");
+ }
+
NumRemoveDeadBindings++;
CleanedState = Pred->getState();
- SymbolReaper SymReaper(LC, ReferenceStmt, SymMgr, getStoreManager());
+
+ // LC is the location context being destroyed, but SymbolReaper wants a
+ // location context that is still live. (If this is the top-level stack
+ // frame, this will be null.)
+ if (!ReferenceStmt) {
+ assert(K == ProgramPoint::PostStmtPurgeDeadSymbolsKind &&
+ "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext");
+ LC = LC->getParent();
+ }
+
+ const StackFrameContext *SFC = LC ? LC->getCurrentStackFrame() : 0;
+ SymbolReaper SymReaper(SFC, ReferenceStmt, SymMgr, getStoreManager());
getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper);
// Create a state in which dead bindings are removed from the environment
// and the store. TODO: The function should just return new env and store,
// not a new state.
- const StackFrameContext *SFC = LC->getCurrentStackFrame();
CleanedState = StateMgr.removeDeadBindings(CleanedState, SFC, SymReaper);
// Process any special transfer function for dead symbols.
@@ -345,8 +362,7 @@ void ExprEngine::ProcessStmt(const CFGStmt S,
EntryNode = Pred;
ExplodedNodeSet CleanedStates;
if (shouldRemoveDeadBindings(AMgr, S, Pred, EntryNode->getLocationContext())){
- removeDead(EntryNode, CleanedStates, currStmt,
- Pred->getStackFrame(), currStmt);
+ removeDead(EntryNode, CleanedStates, currStmt, Pred->getLocationContext());
} else
CleanedStates.Add(EntryNode);