[cfe-commits] r68496 - /cfe/trunk/lib/Analysis/CFRefCount.cpp
Ted Kremenek
kremenek at apple.com
Mon Apr 6 21:54:20 PDT 2009
Author: kremenek
Date: Mon Apr 6 23:54:20 2009
New Revision: 68496
URL: http://llvm.org/viewvc/llvm-project?rev=68496&view=rev
Log:
Eagerly compute the leak location when a leak occurs at the end of a path.
Modified:
cfe/trunk/lib/Analysis/CFRefCount.cpp
Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=68496&r1=68495&r2=68496&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Mon Apr 6 23:54:20 2009
@@ -2906,7 +2906,9 @@
SourceManager& SMgr = BR.getContext().getSourceManager();
unsigned AllocLine =SMgr.getInstantiationLineNumber(FirstStmt->getLocStart());
-#if 1
+ // Compute an actual location for the leak. Sometimes a leak doesn't
+ // occur at an actual statement (e.g., transition between blocks; end
+ // of function) so we need to walk the graph and compute a real location.
const ExplodedNode<GRState>* LeakN = EndN;
PathDiagnosticLocation L;
@@ -2924,7 +2926,6 @@
}
}
-
LeakN = LeakN->succ_empty() ? 0 : *(LeakN->succ_begin());
}
@@ -2933,65 +2934,6 @@
L = PathDiagnosticLocation(CS->getRBracLoc(), SMgr);
}
-#else
- // Get the leak site. We want to find the last place where the symbol
- // was used in an expression.
- const ExplodedNode<GRState>* LeakN = EndN;
- Stmt *S = 0;
-
- while (LeakN) {
- bool atBranch = false;
- ProgramPoint P = LeakN->getLocation();
-
- if (const PostStmt *PS = dyn_cast<PostStmt>(&P))
- S = PS->getStmt();
- else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
- // FIXME: What we really want is to set LeakN to be the node
- // for the BlockEntrance for the branch we took and have BugReporter
- // do the right thing.
- S = BE->getSrc()->getTerminator();
- atBranch = (S != 0);
- }
-
- if (S) {
- // Scan 'S' for uses of Sym.
- GRStateRef state(LeakN->getState(), BR.getStateManager());
- bool foundSymbol = false;
-
- // First check if 'S' itself binds to the symbol.
- if (Expr *Ex = dyn_cast<Expr>(S))
- if (state.GetSValAsScalarOrLoc(Ex).getAsLocSymbol() == Sym)
- foundSymbol = true;
-
- if (!foundSymbol)
- for (Stmt::child_iterator I=S->child_begin(), E=S->child_end();
- I!=E; ++I)
- if (Expr *Ex = dyn_cast_or_null<Expr>(*I)) {
- SVal X = state.GetSValAsScalarOrLoc(Ex);
- if (X.getAsLocSymbol() == Sym) {
- foundSymbol = true;
- break;
- }
- }
-
- if (foundSymbol)
- break;
- }
-
- // Don't traverse any higher than the branch.
- if (atBranch)
- break;
-
- LeakN = LeakN->pred_empty() ? 0 : *(LeakN->pred_begin());
- }
-
- assert(LeakN && S && "No leak site found.");
-
- // Generate the diagnostic.
- // FIXME: We need to do a better job at determing the leak site, e.g., at
- // the end of function bodies.
- PathDiagnosticLocation L(S, SMgr);
-#endif
std::string sbuf;
llvm::raw_string_ostream os(sbuf);
@@ -3062,6 +3004,59 @@
// Handle dead symbols and end-of-path.
//===----------------------------------------------------------------------===//
+static ExplodedNode<GRState>*
+GetLeakNode(ExplodedNode<GRState>* EndN, SymbolRef Sym,
+ GRStateManager &StateMgr) {
+
+ // Get the leak site. We want to find the last place where the symbol
+ // was used in an expression.
+ ExplodedNode<GRState>* LeakN = EndN;
+ Stmt *S = 0;
+
+ while (LeakN) {
+ ProgramPoint P = LeakN->getLocation();
+
+ if (const PostStmt *PS = dyn_cast<PostStmt>(&P))
+ S = PS->getStmt();
+ else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+ // FIXME: What we really want is to set LeakN to be the node
+ // for the BlockEntrance for the branch we took and have BugReporter
+ // do the right thing.
+ S = BE->getSrc()->getTerminator();
+ }
+
+ if (S) {
+ // Scan 'S' for uses of Sym.
+ GRStateRef state(LeakN->getState(), StateMgr);
+ bool foundSymbol = false;
+
+ // First check if 'S' itself binds to the symbol.
+ if (Expr *Ex = dyn_cast<Expr>(S))
+ if (state.GetSValAsScalarOrLoc(Ex).getAsLocSymbol() == Sym)
+ foundSymbol = true;
+
+ if (!foundSymbol)
+ for (Stmt::child_iterator I=S->child_begin(), E=S->child_end();
+ I!=E; ++I)
+ if (Expr *Ex = dyn_cast_or_null<Expr>(*I)) {
+ SVal X = state.GetSValAsScalarOrLoc(Ex);
+ if (X.getAsLocSymbol() == Sym) {
+ foundSymbol = true;
+ break;
+ }
+ }
+
+ if (foundSymbol)
+ break;
+ }
+
+ LeakN = LeakN->pred_empty() ? 0 : *(LeakN->pred_begin());
+ }
+
+ assert(LeakN && "No leak site found.");
+ return LeakN;
+}
+
void CFRefCount::EvalEndPath(GRExprEngine& Eng,
GREndPathNodeBuilder<GRState>& Builder) {
@@ -3096,7 +3091,10 @@
CFRefBug *BT = static_cast<CFRefBug*>(I->second ? leakAtReturn
: leakWithinFunction);
assert(BT && "BugType not initialized.");
- CFRefLeakReport* report = new CFRefLeakReport(*BT, *this, N, I->first, Eng);
+ CFRefLeakReport* report =
+ new CFRefLeakReport(*BT, *this,
+ GetLeakNode(N, I->first, Eng.getStateManager()),
+ I->first, Eng);
BR->EmitReport(report);
}
}
More information about the cfe-commits
mailing list