summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-11-15 19:11:27 +0000
committerJordan Rose <jordan_rose@apple.com>2012-11-15 19:11:27 +0000
commitb5b0fc196e8768076c3c9155cd79b248623861de (patch)
treef712d0d90710a553f0463760c530052266204c51 /clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
parent38990beed80119f7ee5f7da6a69efa6207f886ab (diff)
downloadbcm5719-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.cpp28
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);
OpenPOWER on IntegriCloud