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

Anna Zaks ganna at apple.com
Wed Jun 20 13:57:46 PDT 2012


Author: zaks
Date: Wed Jun 20 15:57:46 2012
New Revision: 158850

URL: http://llvm.org/viewvc/llvm-project?rev=158850&view=rev
Log:
[analyzer] Malloc: cleanup, disallow free on relinquished memory.

This commits sets the grounds for more aggressive use after free
checking. We will use the Relinquished sate to denote that someone
else is now responsible for releasing the memory.

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

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=158850&r1=158849&r2=158850&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Wed Jun 20 15:57:46 2012
@@ -34,15 +34,24 @@
 namespace {
 
 class RefState {
-  enum Kind { AllocateUnchecked, AllocateFailed, Released, Escaped,
+  enum Kind { // Reference to allocated memory.
+              Allocated,
+              // Reference to released/freed memory.
+              Released,
+              // Reference to escaped memory - no assumptions can be made of
+              // the state after the reference escapes.
+              Escaped,
+              // The responsibility for freeing resources has transfered from
+              // this reference. A relinquished symbol should not be freed.
               Relinquished } K;
   const Stmt *S;
 
 public:
   RefState(Kind k, const Stmt *s) : K(k), S(s) {}
 
-  bool isAllocated() const { return K == AllocateUnchecked; }
+  bool isAllocated() const { return K == Allocated; }
   bool isReleased() const { return K == Released; }
+  bool isRelinquished() const { return K == Relinquished; }
 
   const Stmt *getStmt() const { return S; }
 
@@ -50,11 +59,8 @@
     return K == X.K && S == X.S;
   }
 
-  static RefState getAllocateUnchecked(const Stmt *s) { 
-    return RefState(AllocateUnchecked, s); 
-  }
-  static RefState getAllocateFailed() {
-    return RefState(AllocateFailed, 0);
+  static RefState getAllocated(const Stmt *s) {
+    return RefState(Allocated, s);
   }
   static RefState getReleased(const Stmt *s) { return RefState(Released, s); }
   static RefState getEscaped(const Stmt *s) { return RefState(Escaped, s); }
@@ -528,7 +534,7 @@
   assert(Sym);
 
   // Set the symbol's state to Allocated.
-  return state->set<RegionState>(Sym, RefState::getAllocateUnchecked(CE));
+  return state->set<RegionState>(Sym, RefState::getAllocated(CE));
 
 }
 
@@ -628,7 +634,8 @@
     return 0;
 
   // Check double free.
-  if (RS->isReleased()) {
+  // TODO: Split the 2 cases for better error messages.
+  if (RS->isReleased() || RS->isRelinquished()) {
     if (ExplodedNode *N = C.generateSink()) {
       if (!BT_DoubleFree)
         BT_DoubleFree.reset(
@@ -1237,7 +1244,7 @@
       if (RS) {
         if (RS->isReleased() && ! I.getData().IsFreeOnFailure)
           state = state->set<RegionState>(ReallocSym,
-                             RefState::getAllocateUnchecked(RS->getStmt()));
+                             RefState::getAllocated(RS->getStmt()));
       }
       state = state->remove<ReallocPairs>(I.getKey());
     }

Modified: cfe/trunk/test/Analysis/malloc-annotations.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc-annotations.c?rev=158850&r1=158849&r2=158850&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/malloc-annotations.c (original)
+++ cfe/trunk/test/Analysis/malloc-annotations.c Wed Jun 20 15:57:46 2012
@@ -123,12 +123,12 @@
   free(p); // no-warning
 }
 
-// This case would inflict a double-free elsewhere.
-// However, this case is considered an analyzer bug since it causes false-positives.
+// This case inflicts a possible double-free.
+// TODO: Better error message.
 void af3() {
   int *p = my_malloc(12);
   my_hold(p);
-  free(p); // no-warning
+  free(p); // expected-warning{{Attempt to free released memory}}
 }
 
 int * af4() {





More information about the cfe-commits mailing list