summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2013-04-16 21:44:22 +0000
committerTed Kremenek <kremenek@apple.com>2013-04-16 21:44:22 +0000
commit8671acba9563e2fbf8627c6b9f58d022fee78458 (patch)
treea19b3030b6f4a47ac0e6b084cf53822c62dc37e8
parentc9cb7d2462d9e849cd6bc80889637ce2b7b31706 (diff)
downloadbcm5719-llvm-8671acba9563e2fbf8627c6b9f58d022fee78458.tar.gz
bcm5719-llvm-8671acba9563e2fbf8627c6b9f58d022fee78458.zip
[analyzer] Add experimental option "leak-diagnostics-reference-allocation".
This is an opt-in tweak for leak diagnostics to reference the allocation site if the diagnostic consumer only wants a pithy amount of information, and not the entire path. This is a strawman enhancement that I expect to see some experimentation with over the next week, and can go away if we don't want it. Currently it is only used by RetainCountChecker, but could be used by MallocChecker if and when we decide this should stay in. llvm-svn: 179634
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.cpp24
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h31
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt1
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp35
-rw-r--r--clang/test/Analysis/analyzer-config.c3
-rw-r--r--clang/test/Analysis/analyzer-config.cpp3
6 files changed, 85 insertions, 12 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.cpp
new file mode 100644
index 00000000000..3dec8a58c92
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.cpp
@@ -0,0 +1,24 @@
+//=- AllocationDiagnostics.cpp - Config options for allocation diags *- C++ -*-//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Declares the configuration functions for leaks/allocation diagnostics.
+//
+//===--------------------------
+
+#include "AllocationDiagnostics.h"
+
+namespace clang {
+namespace ento {
+
+bool shouldIncludeAllocationSiteInLeakDiagnostics(AnalyzerOptions &AOpts) {
+ return AOpts.getBooleanOption("leak-diagnostics-reference-allocation",
+ false);
+}
+
+}}
diff --git a/clang/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h b/clang/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h
new file mode 100644
index 00000000000..2b314a3b749
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h
@@ -0,0 +1,31 @@
+//=--- AllocationDiagnostics.h - Config options for allocation diags *- C++ -*-//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Declares the configuration functions for leaks/allocation diagnostics.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SA_LIB_CHECKERS_ALLOC_DIAGS_H
+#define LLVM_CLANG_SA_LIB_CHECKERS_ALLOC_DIAGS_H
+
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+
+namespace clang { namespace ento {
+
+/// \brief Returns true if leak diagnostics should directly reference
+/// the allocatin site (where possible).
+///
+/// The default is false.
+///
+bool shouldIncludeAllocationSiteInLeakDiagnostics(AnalyzerOptions &AOpts);
+
+}}
+
+#endif
+
diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index a20394d8934..7da68251063 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -4,6 +4,7 @@ clang_tablegen(Checkers.inc -gen-clang-sa-checkers
TARGET ClangSACheckers)
add_clang_library(clangStaticAnalyzerCheckers
+ AllocationDiagnostics.cpp
AnalyzerStatsChecker.cpp
ArrayBoundChecker.cpp
ArrayBoundCheckerV2.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 156e1f9c3ff..4c630190837 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -37,6 +37,8 @@
#include "llvm/ADT/StringExtras.h"
#include <cstdarg>
+#include "AllocationDiagnostics.h"
+
using namespace clang;
using namespace ento;
using llvm::StrInStrNoCase;
@@ -1773,11 +1775,11 @@ namespace {
class CFRefLeakReport : public CFRefReport {
const MemRegion* AllocBinding;
-
public:
CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts, bool GCEnabled,
const SummaryLogTy &Log, ExplodedNode *n, SymbolRef sym,
- CheckerContext &Ctx);
+ CheckerContext &Ctx,
+ bool IncludeAllocationLine);
PathDiagnosticLocation getLocation(const SourceManager &SM) const {
assert(Location.isValid());
@@ -2323,8 +2325,9 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
bool GCEnabled, const SummaryLogTy &Log,
ExplodedNode *n, SymbolRef sym,
- CheckerContext &Ctx)
-: CFRefReport(D, LOpts, GCEnabled, Log, n, sym, false) {
+ CheckerContext &Ctx,
+ bool IncludeAllocationLine)
+ : CFRefReport(D, LOpts, GCEnabled, Log, n, sym, false) {
// Most bug reports are cached at the location where they occurred.
// With leaks, we want to unique them by the location where they were
@@ -2365,9 +2368,13 @@ CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
os << "(when using garbage collection) ";
os << "of an object";
- // FIXME: AllocBinding doesn't get populated for RegionStore yet.
- if (AllocBinding)
+ if (AllocBinding) {
os << " stored into '" << AllocBinding->getString() << '\'';
+ if (IncludeAllocationLine) {
+ FullSourceLoc SL(AllocStmt->getLocStart(), Ctx.getSourceManager());
+ os << " (allocated on line " << SL.getSpellingLineNumber() << ")";
+ }
+ }
addVisitor(new CFRefLeakReportVisitor(sym, GCEnabled, Log));
}
@@ -2408,8 +2415,14 @@ class RetainCountChecker
mutable SummaryLogTy SummaryLog;
mutable bool ShouldResetSummaryLog;
+ /// Optional setting to indicate if leak reports should include
+ /// the allocation line.
+ mutable bool IncludeAllocationLine;
+
public:
- RetainCountChecker() : ShouldResetSummaryLog(false) {}
+ RetainCountChecker(AnalyzerOptions &AO)
+ : ShouldResetSummaryLog(false),
+ IncludeAllocationLine(shouldIncludeAllocationSiteInLeakDiagnostics(AO)) {}
virtual ~RetainCountChecker() {
DeleteContainerSeconds(DeadSymbolTags);
@@ -3354,7 +3367,8 @@ void RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
CFRefReport *report =
new CFRefLeakReport(*getLeakAtReturnBug(LOpts, GCEnabled),
LOpts, GCEnabled, SummaryLog,
- N, Sym, C);
+ N, Sym, C, IncludeAllocationLine);
+
C.emitReport(report);
}
}
@@ -3594,7 +3608,8 @@ RetainCountChecker::processLeaks(ProgramStateRef state,
assert(BT && "BugType not initialized.");
CFRefLeakReport *report = new CFRefLeakReport(*BT, LOpts, GCEnabled,
- SummaryLog, N, *I, Ctx);
+ SummaryLog, N, *I, Ctx,
+ IncludeAllocationLine);
Ctx.emitReport(report);
}
}
@@ -3716,6 +3731,6 @@ void RetainCountChecker::printState(raw_ostream &Out, ProgramStateRef State,
//===----------------------------------------------------------------------===//
void ento::registerRetainCountChecker(CheckerManager &Mgr) {
- Mgr.registerChecker<RetainCountChecker>();
+ Mgr.registerChecker<RetainCountChecker>(Mgr.getAnalyzerOptions());
}
diff --git a/clang/test/Analysis/analyzer-config.c b/clang/test/Analysis/analyzer-config.c
index 96b948352b3..2a3d645ffdf 100644
--- a/clang/test/Analysis/analyzer-config.c
+++ b/clang/test/Analysis/analyzer-config.c
@@ -11,10 +11,11 @@ void foo() { bar(); }
// CHECK-NEXT: graph-trim-interval = 1000
// CHECK-NEXT: ipa = dynamic-bifurcate
// CHECK-NEXT: ipa-always-inline-size = 3
+// CHECK-NEXT: leak-diagnostics-reference-allocation = false
// CHECK-NEXT: max-inlinable-size = 50
// CHECK-NEXT: max-nodes = 150000
// CHECK-NEXT: max-times-inline-large = 32
// CHECK-NEXT: mode = deep
// CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 10
+// CHECK-NEXT: num-entries = 11
diff --git a/clang/test/Analysis/analyzer-config.cpp b/clang/test/Analysis/analyzer-config.cpp
index 1224204f8c7..1ba59184d80 100644
--- a/clang/test/Analysis/analyzer-config.cpp
+++ b/clang/test/Analysis/analyzer-config.cpp
@@ -21,9 +21,10 @@ public:
// CHECK-NEXT: graph-trim-interval = 1000
// CHECK-NEXT: ipa = dynamic-bifurcate
// CHECK-NEXT: ipa-always-inline-size = 3
+// CHECK-NEXT: leak-diagnostics-reference-allocation = false
// CHECK-NEXT: max-inlinable-size = 50
// CHECK-NEXT: max-nodes = 150000
// CHECK-NEXT: max-times-inline-large = 32
// CHECK-NEXT: mode = deep
// CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 14
+// CHECK-NEXT: num-entries = 15
OpenPOWER on IntegriCloud