]> granicus.if.org Git - clang/commitdiff
[analyzer] Add experimental option "leak-diagnostics-reference-allocation".
authorTed Kremenek <kremenek@apple.com>
Tue, 16 Apr 2013 21:44:22 +0000 (21:44 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 16 Apr 2013 21:44:22 +0000 (21:44 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179634 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/AllocationDiagnostics.cpp [new file with mode: 0644]
lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h [new file with mode: 0644]
lib/StaticAnalyzer/Checkers/CMakeLists.txt
lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
test/Analysis/analyzer-config.c
test/Analysis/analyzer-config.cpp

diff --git a/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.cpp b/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.cpp
new file mode 100644 (file)
index 0000000..3dec8a5
--- /dev/null
@@ -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/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h b/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h
new file mode 100644 (file)
index 0000000..2b314a3
--- /dev/null
@@ -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
+
index a20394d89347343d60851a6f354eccff4391c18d..7da68251063b883595ebaf4e9ad71b97bc4e55c5 100644 (file)
@@ -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
index 156e1f9c3ff410c9138f605c94e3137ac0b2e272..4c6301908371579a82c2c0a310863b575ad7cb03 100644 (file)
@@ -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());
 }
 
index 96b948352b3f41f0cbf43b05d3de955846a5379e..2a3d645ffdf2435df713da71641fbf8acb245eb4 100644 (file)
@@ -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
 
index 1224204f8c7b1e2a284293549ccd8978438f20fd..1ba59184d80a4684c2e456213da3b2137daa71b6 100644 (file)
@@ -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