[cfe-commits] r64980 - /cfe/trunk/lib/Analysis/CFRefCount.cpp
Ted Kremenek
kremenek at apple.com
Wed Feb 18 15:28:26 PST 2009
Author: kremenek
Date: Wed Feb 18 17:28:26 2009
New Revision: 64980
URL: http://llvm.org/viewvc/llvm-project?rev=64980&view=rev
Log:
retain/release checker: Place the leak diagnostic after the last statement that
references the tracked object.
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=64980&r1=64979&r2=64980&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Wed Feb 18 17:28:26 2009
@@ -2579,22 +2579,44 @@
SourceManager& SMgr = BR.getContext().getSourceManager();
unsigned AllocLine =SMgr.getInstantiationLineNumber(FirstStmt->getLocStart());
- // Get the leak site. We may have multiple ExplodedNodes (one with the
- // leak) that occur on the same line number; if the node with the leak
- // has any immediate predecessor nodes with the same line number, find
- // any transitive-successors that have a different statement and use that
- // line number instead. This avoids emiting a diagnostic like:
- //
- // // 'y' is leaked.
- // int x = foo(y);
- //
- // instead we want:
- //
- // int x = foo(y);
- // // 'y' is leaked.
+ // 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) {
+ ProgramPoint P = LeakN->getLocation();
+
+
+ if (const PostStmt *PS = dyn_cast<PostStmt>(&P))
+ S = PS->getStmt();
+ else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P))
+ S = BE->getSrc()->getTerminator();
+
+ if (S) {
+ // Scan 'S' for uses of Sym.
+ GRStateRef state(LeakN->getState(), BR.getStateManager());
+ bool foundSymbol = false;
+
+ 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.GetSVal(Ex);
+ if (isa<loc::SymbolVal>(X) &&
+ cast<loc::SymbolVal>(X).getSymbol() == Sym){
+ foundSymbol = true;
+ break;
+ }
+ }
+
+ if (foundSymbol)
+ break;
+ }
+
+ LeakN = LeakN->pred_empty() ? 0 : *(LeakN->pred_begin());
+ }
- Stmt* S = getStmt(BR); // This is the statement where the leak occured.
- assert (S);
+ assert(LeakN && S && "No leak site found.");
// Generate the diagnostic.
FullSourceLoc L(S->getLocStart(), SMgr);
More information about the cfe-commits
mailing list