[cfe-commits] r161512 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h lib/StaticAnalyzer/Checkers/MallocChecker.cpp lib/StaticAnalyzer/Core/MemRegion.cpp test/Analysis/malloc.c

Jordan Rose jordan_rose at apple.com
Wed Aug 8 11:23:36 PDT 2012


Author: jrose
Date: Wed Aug  8 13:23:36 2012
New Revision: 161512

URL: http://llvm.org/viewvc/llvm-project?rev=161512&view=rev
Log:
[analyzer] Clean up the printing of FieldRegions for leaks.

Unfortunately, generalized region printing is very difficult:
- ElementRegions are used both for casting and as actual elements.
- Accessing values through a pointer means going through an intermediate
  SymbolRegionValue; symbolic regions are untyped.
- Referring to implicitly-defined variables like 'this' and 'self' could be
  very confusing if they come from another stack frame.

We fall back to simply not printing the region name if we can't be sure it
will print well. This will allow us to improve in the future.

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
    cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp
    cfe/trunk/test/Analysis/malloc.c

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h?rev=161512&r1=161511&r2=161512&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h Wed Aug  8 13:23:36 2012
@@ -150,8 +150,11 @@
 
   void dump() const;
 
+  /// \brief Returns true if this region can be printed in a user-friendly way.
+  virtual bool canPrintPretty() const;
+
   /// \brief Print the region for use in diagnostics.
-  virtual void dumpPretty(raw_ostream &os) const;
+  virtual void printPretty(raw_ostream &os) const;
 
   Kind getKind() const { return kind; }
 
@@ -846,7 +849,8 @@
     return R->getKind() == VarRegionKind;
   }
 
-  void dumpPretty(raw_ostream &os) const;
+  bool canPrintPretty() const;
+  void printPretty(raw_ostream &os) const;
 };
   
 /// CXXThisRegion - Represents the region for the implicit 'this' parameter
@@ -905,7 +909,9 @@
   }
 
   void dumpToStream(raw_ostream &os) const;
-  void dumpPretty(raw_ostream &os) const;
+
+  bool canPrintPretty() const;
+  void printPretty(raw_ostream &os) const;
 };
 
 class ObjCIvarRegion : public DeclRegion {

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=161512&r1=161511&r2=161512&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Wed Aug  8 13:23:36 2012
@@ -1000,10 +1000,9 @@
   SmallString<200> buf;
   llvm::raw_svector_ostream os(buf);
   os << "Memory is never released; potential leak";
-  // FIXME: Make all region pretty-printing nice enough to show.
-  if (Region && isa<VarRegion>(Region)) {
+  if (Region && Region->canPrintPretty()) {
     os << " of memory pointed to by '";
-    Region->dumpPretty(os);
+    Region->printPretty(os);
     os << '\'';
   }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp?rev=161512&r1=161511&r2=161512&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp Wed Aug  8 13:23:36 2012
@@ -546,17 +546,29 @@
   os << "StackLocalsSpaceRegion";
 }
 
-void MemRegion::dumpPretty(raw_ostream &os) const {
+bool MemRegion::canPrintPretty() const {
+  return false;
+}
+
+void MemRegion::printPretty(raw_ostream &os) const {
   return;
 }
 
-void VarRegion::dumpPretty(raw_ostream &os) const {
+bool VarRegion::canPrintPretty() const {
+  return true;
+}
+
+void VarRegion::printPretty(raw_ostream &os) const {
   os << getDecl()->getName();
 }
 
-void FieldRegion::dumpPretty(raw_ostream &os) const {
-  superRegion->dumpPretty(os);
-  os << "->" << getDecl();
+bool FieldRegion::canPrintPretty() const {
+  return superRegion->canPrintPretty();
+}
+
+void FieldRegion::printPretty(raw_ostream &os) const {
+  superRegion->printPretty(os);
+  os << "." << getDecl()->getName();
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/test/Analysis/malloc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc.c?rev=161512&r1=161511&r2=161512&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/malloc.c (original)
+++ cfe/trunk/test/Analysis/malloc.c Wed Aug  8 13:23:36 2012
@@ -19,7 +19,7 @@
 
 void f1() {
   int *p = malloc(12);
-  return; // expected-warning{{Memory is never released; potential leak}}
+  return; // expected-warning{{Memory is never released; potential leak of memory pointed to by 'p'}}
 }
 
 void f2() {
@@ -44,7 +44,7 @@
   char *p = (char*)malloc(size);
   if (p) {
     char *q = (char*)realloc(p, sizeIn);
-    char x = *q; // expected-warning {{Memory is never released; potential leak}}
+    char x = *q; // expected-warning {{Memory is never released; potential leak of memory pointed to by 'q'}}
   }
 }
 
@@ -102,7 +102,7 @@
 }
 
 void reallocPtrZero1() {
-  char *r = realloc(0, 12); // expected-warning {{Memory is never released; potential leak}}
+  char *r = realloc(0, 12); // expected-warning {{Memory is never released; potential leak of memory pointed to by 'r'}}
 }
 
 void reallocPtrZero2() {
@@ -529,6 +529,12 @@
   return y; // no-warning
 }
 
+void testStructLeak() {
+  StructWithPtr St;
+  St.memP = malloc(12);
+  return; // expected-warning {{Memory is never released; potential leak of memory pointed to by 'St.memP'}}
+}
+
 void testElemRegion1() {
   char *x = (void*)malloc(2);
   int *ix = (int*)x;





More information about the cfe-commits mailing list