[cfe-commits] r98136 - in /cfe/trunk: include/clang/Checker/PathSensitive/SVals.h lib/Checker/MallocChecker.cpp lib/Checker/SVals.cpp test/Analysis/malloc.c

Zhongxing Xu xuzhongxing at gmail.com
Tue Mar 9 20:58:55 PST 2010


Author: zhongxingxu
Date: Tue Mar  9 22:58:55 2010
New Revision: 98136

URL: http://llvm.org/viewvc/llvm-project?rev=98136&view=rev
Log:
Add use-after-free check to MallocChecker.

Modified:
    cfe/trunk/include/clang/Checker/PathSensitive/SVals.h
    cfe/trunk/lib/Checker/MallocChecker.cpp
    cfe/trunk/lib/Checker/SVals.cpp
    cfe/trunk/test/Analysis/malloc.c

Modified: cfe/trunk/include/clang/Checker/PathSensitive/SVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/SVals.h?rev=98136&r1=98135&r2=98136&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/SVals.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/SVals.h Tue Mar  9 22:58:55 2010
@@ -112,6 +112,9 @@
   ///  wraps a symbol, return that SymbolRef.  Otherwise return a SymbolData*
   SymbolRef getAsLocSymbol() const;
 
+  /// Get the symbol in the SVal or its base region.
+  SymbolRef getLocSymbolInBase() const;
+
   /// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
   ///  Otherwise return a SymbolRef where 'isValid()' returns false.
   SymbolRef getAsSymbol() const;

Modified: cfe/trunk/lib/Checker/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/MallocChecker.cpp?rev=98136&r1=98135&r2=98136&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/MallocChecker.cpp (original)
+++ cfe/trunk/lib/Checker/MallocChecker.cpp Tue Mar  9 22:58:55 2010
@@ -57,17 +57,20 @@
 class MallocChecker : public CheckerVisitor<MallocChecker> {
   BuiltinBug *BT_DoubleFree;
   BuiltinBug *BT_Leak;
+  BuiltinBug *BT_UseFree;
   IdentifierInfo *II_malloc, *II_free, *II_realloc;
 
 public:
   MallocChecker() 
-    : BT_DoubleFree(0), BT_Leak(0), II_malloc(0), II_free(0), II_realloc(0) {}
+    : BT_DoubleFree(0), BT_Leak(0), BT_UseFree(0), 
+      II_malloc(0), II_free(0), II_realloc(0) {}
   static void *getTag();
   bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
   void EvalDeadSymbols(CheckerContext &C,const Stmt *S,SymbolReaper &SymReaper);
   void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
   void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S);
   const GRState *EvalAssume(const GRState *state, SVal Cond, bool Assumption);
+  void VisitLocation(CheckerContext &C, const Stmt *S, SVal l);
 
 private:
   void MallocMem(CheckerContext &C, const CallExpr *CE);
@@ -339,3 +342,22 @@
 
   return state;
 }
+
+// Check if the location is a freed symbolic region.
+void MallocChecker::VisitLocation(CheckerContext &C, const Stmt *S, SVal l) {
+  SymbolRef Sym = l.getLocSymbolInBase();
+  if (Sym) {
+    const RefState *RS = C.getState()->get<RegionState>(Sym);
+    if (RS)
+      if (RS->isReleased()) {
+        ExplodedNode *N = C.GenerateSink();
+        if (!BT_UseFree)
+          BT_UseFree = new BuiltinBug("Use dynamically allocated memory after"
+                                      " it is freed.");
+
+        BugReport *R = new BugReport(*BT_UseFree, BT_UseFree->getDescription(),
+                                     N);
+        C.EmitReport(R);
+      }
+  }
+}

Modified: cfe/trunk/lib/Checker/SVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/SVals.cpp?rev=98136&r1=98135&r2=98136&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/SVals.cpp (original)
+++ cfe/trunk/lib/Checker/SVals.cpp Tue Mar  9 22:58:55 2010
@@ -70,6 +70,25 @@
   return NULL;
 }
 
+/// Get the symbol in the SVal or its base region.
+SymbolRef SVal::getLocSymbolInBase() const {
+  const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this);
+
+  if (!X)
+    return 0;
+
+  const MemRegion *R = X->getRegion();
+
+  while (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
+    if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SR))
+      return SymR->getSymbol();
+    else
+      R = SR->getSuperRegion();
+  }
+
+  return 0;
+}
+
 /// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
 ///  Otherwise return 0.
 // FIXME: should we consider SymbolRef wrapped in CodeTextRegion?

Modified: cfe/trunk/test/Analysis/malloc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc.c?rev=98136&r1=98135&r2=98136&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/malloc.c (original)
+++ cfe/trunk/test/Analysis/malloc.c Tue Mar  9 22:58:55 2010
@@ -61,3 +61,9 @@
 void pr6293() {
   free(0);
 }
+
+void f7() {
+  char *x = (char*) malloc(4);
+  free(x);
+  x[0] = 'a'; // expected-warning{{Use dynamically allocated memory after it is freed.}}
+}





More information about the cfe-commits mailing list