[cfe-commits] r150312 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/MallocChecker.cpp test/Analysis/malloc.c

Anna Zaks ganna at apple.com
Sat Feb 11 13:02:40 PST 2012


Author: zaks
Date: Sat Feb 11 15:02:40 2012
New Revision: 150312

URL: http://llvm.org/viewvc/llvm-project?rev=150312&view=rev
Log:
[analyzer] Malloc checker: Leak bugs should be suppressed by sinks.
Resolves a common false positive, where we were reporting a leak inside
asserts

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
    cfe/trunk/test/Analysis/malloc.c

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=150312&r1=150311&r2=150312&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Sat Feb 11 15:02:40 2012
@@ -148,6 +148,8 @@
   static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
   void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange range) const;
 
+  void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const;
+
   /// The bug visitor which allows us to print extra diagnostics along the
   /// BugReport path. For example, showing the allocation site of the leaked
   /// region.
@@ -672,6 +674,25 @@
   C.addTransition(MallocMemAux(C, CE, TotalSize, zeroVal, state));
 }
 
+void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
+                               CheckerContext &C) const {
+  assert(N);
+  if (!BT_Leak) {
+    BT_Leak.reset(new BuiltinBug("Memory leak",
+        "Allocated memory never released. Potential memory leak."));
+    // Leaks should not be reported if they are post-dominated by a sink:
+    // (1) Sinks are higher importance bugs.
+    // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
+    //     with __noreturn functions such as assert() or exit(). We choose not
+    //     to report leaks on such paths.
+    BT_Leak->setSuppressOnSink(true);
+  }
+
+  BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
+  R->addVisitor(new MallocBugVisitor(Sym));
+  C.EmitReport(R);
+}
+
 void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
                                      CheckerContext &C) const
 {
@@ -699,34 +720,23 @@
   ExplodedNode *N = C.addTransition(state->set<RegionState>(RS));
 
   if (N && generateReport) {
-    if (!BT_Leak)
-      BT_Leak.reset(new BuiltinBug("Memory leak",
-          "Allocated memory never released. Potential memory leak."));
     for (llvm::SmallVector<SymbolRef, 2>::iterator
-          I = Errors.begin(), E = Errors.end(); I != E; ++I) {
-      BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
-      R->addVisitor(new MallocBugVisitor(*I));
-      C.EmitReport(R);
+         I = Errors.begin(), E = Errors.end(); I != E; ++I) {
+      reportLeak(*I, N, C);
     }
   }
 }
 
-void MallocChecker::checkEndPath(CheckerContext &Ctx) const {
-  ProgramStateRef state = Ctx.getState();
+void MallocChecker::checkEndPath(CheckerContext &C) const {
+  ProgramStateRef state = C.getState();
   RegionStateTy M = state->get<RegionState>();
 
   for (RegionStateTy::iterator I = M.begin(), E = M.end(); I != E; ++I) {
     RefState RS = I->second;
     if (RS.isAllocated()) {
-      ExplodedNode *N = Ctx.addTransition(state);
-      if (N) {
-        if (!BT_Leak)
-          BT_Leak.reset(new BuiltinBug("Memory leak",
-                    "Allocated memory never released. Potential memory leak."));
-        BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
-        R->addVisitor(new MallocBugVisitor(I->first));
-        Ctx.EmitReport(R);
-      }
+      ExplodedNode *N = C.addTransition(state);
+      if (N)
+        reportLeak(I->first, N, C);
     }
   }
 }

Modified: cfe/trunk/test/Analysis/malloc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc.c?rev=150312&r1=150311&r2=150312&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/malloc.c (original)
+++ cfe/trunk/test/Analysis/malloc.c Sat Feb 11 15:02:40 2012
@@ -340,21 +340,15 @@
   return 0;// expected-warning {{Allocated memory never released. Potential memory leak.}}
 }
 
-// Below are the known false positives.
-
 extern void exit(int) __attribute__ ((__noreturn__));
 void mallocExit(int *g) {
   struct xx *p = malloc(12);
-
-  if (g != 0) {
-    exit(1); // expected-warning{{Allocated memory never released. Potential memory leak}}
-  }
+  if (g != 0)
+    exit(1);
   free(p);
   return;
 }
 
-
-// TODO: There should be no warning here.
 extern void __assert_fail (__const char *__assertion, __const char *__file,
     unsigned int __line, __const char *__function)
      __attribute__ ((__noreturn__));
@@ -363,11 +357,13 @@
 void mallocAssert(int *g) {
   struct xx *p = malloc(12);
 
-  assert(g != 0); // expected-warning{{Allocated memory never released. Potential memory leak}}
+  assert(g != 0);
   free(p);
   return;
 }
 
+// Below are the known false positives.
+
 // TODO: There should be no warning here.
 void reallocFails(int *g, int f) {
   char *p = malloc(12);





More information about the cfe-commits mailing list