From: Ted Kremenek Date: Fri, 2 May 2008 20:53:50 +0000 (+0000) Subject: Improved diagnostics for leaks: now we report which variable was leaked. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e92c1b26b3736807bbd7a3d49026d474291987ad;p=clang Improved diagnostics for leaks: now we report which variable was leaked. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50588 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index c3da51bd12..1fbd2b94bd 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -1519,7 +1519,7 @@ namespace { virtual void getRanges(BugReporter& BR, const SourceRange*& beg, const SourceRange*& end) { - if (getBugType().isLeak()) + if (!getBugType().isLeak()) RangedBugReport::getRanges(BR, beg, end); else { beg = 0; @@ -1714,14 +1714,36 @@ PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& BR, ExplodedNode* Last = N; typedef CFRefCount::RefBindings RefBindings; - // Find the first node that referred to the tracked symbol. + // Find the first node that referred to the tracked symbol. We also + // try and find the first VarDecl the value was stored to. + + VarDecl* FirstDecl = 0; while (N) { ValueState* St = N->getState(); RefBindings B = RefBindings((RefBindings::TreeTy*) St->CheckerState); - - if (!B.SlimFind(Sym)) + RefBindings::TreeTy* T = B.SlimFind(Sym); + + if (!T) break; + + VarDecl* VD = 0; + + // Determine if there is an LVal binding to the symbol. + for (ValueState::vb_iterator I=St->vb_begin(), E=St->vb_end(); I!=E; ++I) { + if (!isa(I->second) // Is the value a symbol? + || cast(I->second).getSymbol() != Sym) + continue; + + if (VD) { // Multiple decls map to this symbol. + VD = 0; + break; + } + + VD = I->first; + } + + if (VD) FirstDecl = VD; Last = N; N = N->pred_empty() ? NULL : *(N->pred_begin()); @@ -1738,7 +1760,13 @@ PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& BR, // FIXME: Also get the name of the variable. std::ostringstream os; - os << "Object allocated on line " << Line << " is leaked."; + + os << "Object allocated on line " << Line; + + if (FirstDecl) + os << " and stored into '" << FirstDecl->getName() << '\''; + + os << " is leaked."; Stmt* S = getStmt(BR); assert (S);