[cfe-commits] r151287 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h lib/StaticAnalyzer/Checkers/MallocChecker.cpp lib/StaticAnalyzer/Core/BugReporter.cpp test/Analysis/malloc.c
Anna Zaks
ganna at apple.com
Thu Feb 23 13:38:21 PST 2012
Author: zaks
Date: Thu Feb 23 15:38:21 2012
New Revision: 151287
URL: http://llvm.org/viewvc/llvm-project?rev=151287&view=rev
Log:
[analyzer] Malloc: unique leak reports by allocation site.
When we find two leak reports with the same allocation site, report only
one of them.
Provide a helper method to BugReporter to facilitate this.
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
cfe/trunk/test/Analysis/malloc.c
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h?rev=151287&r1=151286&r2=151287&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h Thu Feb 23 15:38:21 2012
@@ -71,6 +71,7 @@
std::string ShortDescription;
std::string Description;
PathDiagnosticLocation Location;
+ PathDiagnosticLocation UniqueingLocation;
const ExplodedNode *ErrorNode;
SmallVector<SourceRange, 4> Ranges;
ExtraTextList ExtraText;
@@ -95,6 +96,18 @@
: BT(bt), Description(desc), Location(l), ErrorNode(0),
Callbacks(F.getEmptyList()) {}
+ /// \brief Create a BugReport with a custom uniqueing location.
+ ///
+ /// The reports that have the same report location, description, bug type, and
+ /// ranges are uniqued - only one of the equivalent reports will be presented
+ /// to the user. This method allows to rest the location which should be used
+ /// for uniquing reports. For example, memory leaks checker, could set this to
+ /// the allocation site, rather then the location where the bug is reported.
+ BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode,
+ PathDiagnosticLocation LocationToUnique)
+ : BT(bt), Description(desc), UniqueingLocation(LocationToUnique),
+ ErrorNode(errornode), Callbacks(F.getEmptyList()) {}
+
virtual ~BugReport();
const BugType& getBugType() const { return BT; }
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=151287&r1=151286&r2=151287&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Thu Feb 23 15:38:21 2012
@@ -186,6 +186,11 @@
static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange range) const;
+ /// Find the location of the allocation for Sym on the path leading to the
+ /// exploded node N.
+ const Stmt *getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
+ CheckerContext &C) const;
+
void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const;
/// The bug visitor which allows us to print extra diagnostics along the
@@ -766,6 +771,24 @@
return MallocMemAux(C, CE, TotalSize, zeroVal, state);
}
+const Stmt *
+MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
+ CheckerContext &C) const {
+ // Walk the ExplodedGraph backwards and find the first node that referred to
+ // the tracked symbol.
+ const ExplodedNode *AllocNode = N;
+
+ while (N) {
+ if (!N->getState()->get<RegionState>(Sym))
+ break;
+ AllocNode = N;
+ N = N->pred_empty() ? NULL : *(N->pred_begin());
+ }
+
+ ProgramPoint P = AllocNode->getLocation();
+ return cast<clang::PostStmt>(P).getStmt();
+}
+
void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
CheckerContext &C) const {
assert(N);
@@ -779,8 +802,16 @@
BT_Leak->setSuppressOnSink(true);
}
+ // Most bug reports are cached at the location where they occurred.
+ // With leaks, we want to unique them by the location where they were
+ // allocated, and only report a single path.
+ const Stmt *AllocStmt = getAllocationSite(N, Sym, C);
+ PathDiagnosticLocation LocUsedForUniqueing =
+ PathDiagnosticLocation::createBegin(AllocStmt, C.getSourceManager(),
+ N->getLocationContext());
+
BugReport *R = new BugReport(*BT_Leak,
- "Memory is never released; potential memory leak", N);
+ "Memory is never released; potential memory leak", N, LocUsedForUniqueing);
R->addVisitor(new MallocBugVisitor(Sym));
C.EmitReport(R);
}
@@ -818,14 +849,17 @@
}
}
- ExplodedNode *N = C.addTransition(state->set<RegionState>(RS));
+ // Generate leak node.
+ static SimpleProgramPointTag Tag("MallocChecker : DeadSymbolsLeak");
+ ExplodedNode *N = C.addTransition(C.getState(), C.getPredecessor(), &Tag);
- if (N && generateReport) {
+ if (generateReport) {
for (llvm::SmallVector<SymbolRef, 2>::iterator
I = Errors.begin(), E = Errors.end(); I != E; ++I) {
reportLeak(*I, N, C);
}
}
+ C.addTransition(state->set<RegionState>(RS), N);
}
void MallocChecker::checkEndPath(CheckerContext &C) const {
Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=151287&r1=151286&r2=151287&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp Thu Feb 23 15:38:21 2012
@@ -1270,7 +1270,9 @@
void BugReport::Profile(llvm::FoldingSetNodeID& hash) const {
hash.AddPointer(&BT);
hash.AddString(Description);
- if (Location.isValid()) {
+ if (UniqueingLocation.isValid()) {
+ UniqueingLocation.Profile(hash);
+ } else if (Location.isValid()) {
Location.Profile(hash);
} else {
assert(ErrorNode);
Modified: cfe/trunk/test/Analysis/malloc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc.c?rev=151287&r1=151286&r2=151287&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/malloc.c (original)
+++ cfe/trunk/test/Analysis/malloc.c Thu Feb 23 15:38:21 2012
@@ -379,7 +379,7 @@
void mallocMalloc() {
int *p = malloc(12);
- p = malloc(12); // expected-warning{{Memory is never released; potential memory leak}}
+ p = malloc(12); // expected-warning 2 {{Memory is never released; potential memory leak}}
}
void mallocFreeMalloc() {
@@ -666,7 +666,7 @@
char *s2 = strndup(s, size);
s2 [validIndex + 1] = 'b';
if (s2[validIndex] != 'a')
- return 0;// expected-warning {{Memory is never released; potential memory leak}}
+ return 0;
else
return 1;// expected-warning {{Memory is never released; potential memory leak}}
}
More information about the cfe-commits
mailing list