]> granicus.if.org Git - clang/commitdiff
Completely evaluate malloc/free in MallocChecker.cpp.
authorZhongxing Xu <xuzhongxing@gmail.com>
Fri, 11 Dec 2009 03:09:01 +0000 (03:09 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Fri, 11 Dec 2009 03:09:01 +0000 (03:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91100 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/MallocChecker.cpp

index 6fd43c11db3deeda36ae473fdc1d9d1557b8b3c1..f514f7ce1aa420d2ab47fbddde078459b4cdd1c9 100644 (file)
@@ -58,7 +58,7 @@ class MallocChecker : public CheckerVisitor<MallocChecker> {
 public:
   MallocChecker() : BT_DoubleFree(0), BT_Leak(0), II_malloc(0), II_free(0) {}
   static void *getTag();
-  void PostVisitCallExpr(CheckerContext &C, const CallExpr *CE);
+  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);
@@ -85,10 +85,14 @@ void *MallocChecker::getTag() {
   return &x;
 }
 
-void MallocChecker::PostVisitCallExpr(CheckerContext &C, const CallExpr *CE) {
-  const FunctionDecl *FD = CE->getDirectCallee();
+bool MallocChecker::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  const Expr *Callee = CE->getCallee();
+  SVal L = state->getSVal(Callee);
+
+  const FunctionDecl *FD = L.getAsFunctionDecl();
   if (!FD)
-    return;
+    return false;
 
   ASTContext &Ctx = C.getASTContext();
   if (!II_malloc)
@@ -98,19 +102,27 @@ void MallocChecker::PostVisitCallExpr(CheckerContext &C, const CallExpr *CE) {
 
   if (FD->getIdentifier() == II_malloc) {
     MallocMem(C, CE);
-    return;
+    return true;
   }
 
   if (FD->getIdentifier() == II_free) {
     FreeMem(C, CE);
-    return;
+    return true;
   }
+
+  return false;
 }
 
 void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) {
+  unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
+  ValueManager &ValMgr = C.getValueManager();
+
+  SVal RetVal = ValMgr.getConjuredSymbolVal(NULL, CE, CE->getType(), Count);
+
   const GRState *state = C.getState();
-  SVal CallVal = state->getSVal(CE);
-  SymbolRef Sym = CallVal.getAsLocSymbol();
+  state = state->BindExpr(CE, RetVal);
+  
+  SymbolRef Sym = RetVal.getAsLocSymbol();
   assert(Sym);
   // Set the symbol's state to Allocated.
   C.addTransition(state->set<RegionState>(Sym, RefState::getAllocated(CE)));