diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-11-15 19:11:27 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-11-15 19:11:27 +0000 |
commit | b5b0fc196e8768076c3c9155cd79b248623861de (patch) | |
tree | f712d0d90710a553f0463760c530052266204c51 /clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | |
parent | 38990beed80119f7ee5f7da6a69efa6207f886ab (diff) | |
download | bcm5719-llvm-b5b0fc196e8768076c3c9155cd79b248623861de.tar.gz bcm5719-llvm-b5b0fc196e8768076c3c9155cd79b248623861de.zip |
[analyzer] Mark symbol values as dead in the environment.
This allows us to properly remove dead bindings at the end of the top-level
stack frame, using the ReturnStmt, if there is one, to keep the return value
live. This in turn removes the need for a check::EndPath callback in leak
checkers.
This does cause some changes in the path notes for leak checkers. Previously,
a leak would be reported at the location of the closing brace in a function.
Now, it gets reported at the last statement. This matches the way leaks are
currently reported for inlined functions, but is less than ideal for both.
llvm-svn: 168066
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 045591c9074..42bfe144db0 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/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); |