[cfe-commits] r51198 - /cfe/trunk/lib/Analysis/CFRefCount.cpp
Ted Kremenek
kremenek at apple.com
Fri May 16 11:33:44 PDT 2008
Author: kremenek
Date: Fri May 16 13:33:44 2008
New Revision: 51198
URL: http://llvm.org/viewvc/llvm-project?rev=51198&view=rev
Log:
Cache leaks by the allocation site, not the leak location.
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=51198&r1=51197&r2=51198&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Fri May 16 13:33:44 2008
@@ -25,6 +25,7 @@
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/STLExtras.h"
#include <ostream>
#include <sstream>
@@ -1740,6 +1741,7 @@
virtual void EmitWarnings(BugReporter& BR);
virtual void GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes);
virtual bool isLeak() const { return true; }
+ virtual bool isCached(BugReport& R);
};
//===---------===//
@@ -1772,6 +1774,8 @@
}
}
+ SymbolID getSymbol() const { return Sym; }
+
virtual PathDiagnosticPiece* getEndPath(BugReporter& BR,
ExplodedNode<ValueState>* N);
@@ -1963,37 +1967,17 @@
return P;
}
-
-PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& BR,
- ExplodedNode<ValueState>* EndN) {
-
- if (!getBugType().isLeak())
- return RangedBugReport::getEndPath(BR, EndN);
+static std::pair<ExplodedNode<ValueState>*,VarDecl*>
+GetAllocationSite(ExplodedNode<ValueState>* N, SymbolID Sym) {
typedef CFRefCount::RefBindings RefBindings;
-
- // Get the retain count.
- unsigned long RetCount = 0;
-
- {
- ValueState* St = EndN->getState();
- RefBindings B = RefBindings((RefBindings::TreeTy*) St->CheckerState);
- RefBindings::TreeTy* T = B.SlimFind(Sym);
- assert (T);
- RetCount = GetCount(T->getValue().second);
- }
-
- // We are a leak. Walk up the graph to get to the first node where the
- // symbol appeared.
-
- ExplodedNode<ValueState>* N = EndN;
ExplodedNode<ValueState>* Last = N;
// 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);
@@ -2001,7 +1985,7 @@
if (!T)
break;
-
+
VarDecl* VD = 0;
// Determine if there is an LVal binding to the symbol.
@@ -2019,15 +2003,44 @@
}
if (VD) FirstDecl = VD;
-
+
Last = N;
N = N->pred_empty() ? NULL : *(N->pred_begin());
}
- // Get the allocate site.
+ return std::make_pair(Last, FirstDecl);
+}
+
+PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& BR,
+ ExplodedNode<ValueState>* EndN) {
- assert (Last);
- Stmt* FirstStmt = cast<PostStmt>(Last->getLocation()).getStmt();
+ if (!getBugType().isLeak())
+ return RangedBugReport::getEndPath(BR, EndN);
+
+ typedef CFRefCount::RefBindings RefBindings;
+
+ // Get the retain count.
+ unsigned long RetCount = 0;
+
+ {
+ ValueState* St = EndN->getState();
+ RefBindings B = RefBindings((RefBindings::TreeTy*) St->CheckerState);
+ RefBindings::TreeTy* T = B.SlimFind(Sym);
+ assert (T);
+ RetCount = GetCount(T->getValue().second);
+ }
+
+ // We are a leak. Walk up the graph to get to the first node where the
+ // symbol appeared, and also get the first VarDecl that tracked object
+ // is stored to.
+
+ ExplodedNode<ValueState>* AllocNode = 0;
+ VarDecl* FirstDecl = 0;
+ llvm::tie(AllocNode, FirstDecl) = GetAllocationSite(EndN, Sym);
+
+ // Get the allocate site.
+ assert (AllocNode);
+ Stmt* FirstStmt = cast<PostStmt>(AllocNode->getLocation()).getStmt();
SourceManager& SMgr = BR.getContext().getSourceManager();
unsigned AllocLine = SMgr.getLogicalLineNumber(FirstStmt->getLocStart());
@@ -2128,6 +2141,23 @@
Nodes.push_back(I->first);
}
+bool Leak::isCached(BugReport& R) {
+
+ // Most bug reports are cached at the location where they occured.
+ // With leaks, we want to unique them by the location where they were
+ // allocated, and only report only a single path.
+
+ SymbolID Sym = static_cast<CFRefReport&>(R).getSymbol();
+
+ ExplodedNode<ValueState>* AllocNode =
+ GetAllocationSite(R.getEndNode(), Sym).first;
+
+ if (!AllocNode)
+ return false;
+
+ return BugTypeCacheLocation::isCached(AllocNode->getLocation());
+}
+
//===----------------------------------------------------------------------===//
// Transfer function creation for external clients.
//===----------------------------------------------------------------------===//
More information about the cfe-commits
mailing list