MallocChecker.cpp revision da04677092c7b08fe7438f82a8636dcc8c6e9683
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//=== MallocChecker.cpp - A malloc/free checker -------------------*- C++ -*--//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file defines malloc/free checker, which checks for potential memory
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// leaks, double free, and use-after-free problems.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ClangSACheckers.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/Checker.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/CheckerManager.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/ImmutableMap.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/SmallString.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/STLExtras.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace clang;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace ento;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RefState {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum Kind { AllocateUnchecked, AllocateFailed, Released, Escaped,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              Relinquished } K;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Stmt *S;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RefState(Kind k, const Stmt *s) : K(k), S(s) {}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool isAllocated() const { return K == AllocateUnchecked; }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //bool isFailed() const { return K == AllocateFailed; }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool isReleased() const { return K == Released; }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //bool isEscaped() const { return K == Escaped; }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //bool isRelinquished() const { return K == Relinquished; }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool operator==(const RefState &X) const {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return K == X.K && S == X.S;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static RefState getAllocateUnchecked(const Stmt *s) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return RefState(AllocateUnchecked, s);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static RefState getAllocateFailed() {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return RefState(AllocateFailed, 0);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static RefState getReleased(const Stmt *s) { return RefState(Released, s); }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static RefState getEscaped(const Stmt *s) { return RefState(Escaped, s); }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static RefState getRelinquished(const Stmt *s) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return RefState(Relinquished, s);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Profile(llvm::FoldingSetNodeID &ID) const {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ID.AddInteger(K);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ID.AddPointer(S);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RegionState {};
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MallocChecker : public Checker<check::DeadSymbols,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     check::EndPath,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     check::PreStmt<ReturnStmt>,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     check::PostStmt<CallExpr>,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     check::Location,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     check::Bind,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     eval::Assume,
763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     check::RegionChanges>
773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  mutable OwningPtr<BuiltinBug> BT_DoubleFree;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutable OwningPtr<BuiltinBug> BT_Leak;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutable OwningPtr<BuiltinBug> BT_UseFree;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutable OwningPtr<BuiltinBug> BT_UseRelinquished;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutable OwningPtr<BuiltinBug> BT_BadFree;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0) {}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// In pessimistic mode, the checker assumes that it does not know which
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// functions might free the memory.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct ChecksFilter {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DefaultBool CMallocPessimistic;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DefaultBool CMallocOptimistic;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChecksFilter Filter;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void initIdentifierInfo(CheckerContext &C) const;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void checkEndPath(CheckerContext &C) const;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            bool Assumption) const;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void checkLocation(SVal l, bool isLoad, const Stmt *S,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     CheckerContext &C) const;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void checkBind(SVal location, SVal val, const Stmt*S,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 CheckerContext &C) const;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProgramStateRef
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  checkRegionChanges(ProgramStateRef state,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const StoreManager::InvalidatedSymbols *invalidated,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     ArrayRef<const MemRegion *> ExplicitRegions,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     ArrayRef<const MemRegion *> Regions) const;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool wantsRegionChangeUpdate(ProgramStateRef state) const {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private:
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void MallocMem(CheckerContext &C, const CallExpr *CE);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const OwnershipAttr* Att);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const Expr *SizeEx, SVal Init,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ProgramStateRef state) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return MallocMemAux(C, CE,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        state->getSVal(SizeEx, C.getLocationContext()),
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        Init, state);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     SVal SizeEx, SVal Init,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ProgramStateRef state);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FreeMem(CheckerContext &C, const CallExpr *CE) const;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FreeMemAttr(CheckerContext &C, const CallExpr *CE,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const OwnershipAttr* Att) const;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 ProgramStateRef state, unsigned Num,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 bool Hold) const;
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void ReallocMem(CheckerContext &C, const CallExpr *CE) const;
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  static void CallocMem(CheckerContext &C, const CallExpr *CE);
1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool checkEscape(SymbolRef Sym, const Stmt *S, CheckerContext &C) const;
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const Stmt *S = 0) const;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool SummarizeValue(raw_ostream &os, SVal V);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange range) const;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// The bug visitor which allows us to print extra diagnostics along the
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// BugReport path. For example, showing the allocation site of the leaked
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// region.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class MallocBugVisitor : public BugReporterVisitor {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protected:
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The allocated region symbol tracked by the main analysis.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SymbolRef Sym;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public:
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MallocBugVisitor(SymbolRef S) : Sym(S) {}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~MallocBugVisitor() {}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Profile(llvm::FoldingSetNodeID &ID) const {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static int X = 0;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ID.AddPointer(&X);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ID.AddPointer(Sym);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inline bool isAllocated(const RefState *S, const RefState *SPrev) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Did not track -> allocated. Other state (released) -> allocated.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ((S && S->isAllocated()) && (!SPrev || !SPrev->isAllocated()));
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inline bool isReleased(const RefState *S, const RefState *SPrev) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Did not track -> released. Other state (allocated) -> released.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ((S && S->isReleased()) && (!SPrev || !SPrev->isReleased()));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
181    PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
182                                   const ExplodedNode *PrevN,
183                                   BugReporterContext &BRC,
184                                   BugReport &BR);
185  };
186};
187} // end anonymous namespace
188
189typedef llvm::ImmutableMap<SymbolRef, RefState> RegionStateTy;
190
191namespace clang {
192namespace ento {
193  template <>
194  struct ProgramStateTrait<RegionState>
195    : public ProgramStatePartialTrait<RegionStateTy> {
196    static void *GDMIndex() { static int x; return &x; }
197  };
198}
199}
200
201namespace {
202class StopTrackingCallback : public SymbolVisitor {
203  ProgramStateRef state;
204public:
205  StopTrackingCallback(ProgramStateRef st) : state(st) {}
206  ProgramStateRef getState() const { return state; }
207
208  bool VisitSymbol(SymbolRef sym) {
209    state = state->remove<RegionState>(sym);
210    return true;
211  }
212};
213} // end anonymous namespace
214
215void MallocChecker::initIdentifierInfo(CheckerContext &C) const {
216  ASTContext &Ctx = C.getASTContext();
217  if (!II_malloc)
218    II_malloc = &Ctx.Idents.get("malloc");
219  if (!II_free)
220    II_free = &Ctx.Idents.get("free");
221  if (!II_realloc)
222    II_realloc = &Ctx.Idents.get("realloc");
223  if (!II_calloc)
224    II_calloc = &Ctx.Idents.get("calloc");
225}
226
227void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
228  const FunctionDecl *FD = C.getCalleeDecl(CE);
229  if (!FD)
230    return;
231  initIdentifierInfo(C);
232
233  if (FD->getIdentifier() == II_malloc) {
234    MallocMem(C, CE);
235    return;
236  }
237  if (FD->getIdentifier() == II_realloc) {
238    ReallocMem(C, CE);
239    return;
240  }
241
242  if (FD->getIdentifier() == II_calloc) {
243    CallocMem(C, CE);
244    return;
245  }
246
247  if (FD->getIdentifier() == II_free) {
248    FreeMem(C, CE);
249    return;
250  }
251
252  if (Filter.CMallocOptimistic)
253  // Check all the attributes, if there are any.
254  // There can be multiple of these attributes.
255  if (FD->hasAttrs()) {
256    for (specific_attr_iterator<OwnershipAttr>
257                  i = FD->specific_attr_begin<OwnershipAttr>(),
258                  e = FD->specific_attr_end<OwnershipAttr>();
259         i != e; ++i) {
260      switch ((*i)->getOwnKind()) {
261      case OwnershipAttr::Returns: {
262        MallocMemReturnsAttr(C, CE, *i);
263        break;
264      }
265      case OwnershipAttr::Takes:
266      case OwnershipAttr::Holds: {
267        FreeMemAttr(C, CE, *i);
268        break;
269      }
270      }
271    }
272  }
273
274  if (Filter.CMallocPessimistic) {
275    ProgramStateRef State = C.getState();
276    // The pointer might escape through a function call.
277    for (CallExpr::const_arg_iterator I = CE->arg_begin(),
278                                      E = CE->arg_end(); I != E; ++I) {
279      const Expr *A = *I;
280      if (A->getType().getTypePtr()->isAnyPointerType()) {
281        SymbolRef Sym = State->getSVal(A, C.getLocationContext()).getAsSymbol();
282        if (!Sym)
283          continue;
284        checkEscape(Sym, A, C);
285        checkUseAfterFree(Sym, C, A);
286      }
287    }
288  }
289}
290
291void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) {
292  ProgramStateRef state = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(),
293                                      C.getState());
294  C.addTransition(state);
295}
296
297void MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
298                                         const OwnershipAttr* Att) {
299  if (Att->getModule() != "malloc")
300    return;
301
302  OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
303  if (I != E) {
304    ProgramStateRef state =
305        MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState());
306    C.addTransition(state);
307    return;
308  }
309  ProgramStateRef state = MallocMemAux(C, CE, UnknownVal(), UndefinedVal(),
310                                        C.getState());
311  C.addTransition(state);
312}
313
314ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
315                                           const CallExpr *CE,
316                                           SVal Size, SVal Init,
317                                           ProgramStateRef state) {
318  SValBuilder &svalBuilder = C.getSValBuilder();
319
320  // Get the return value.
321  SVal retVal = state->getSVal(CE, C.getLocationContext());
322
323  // Fill the region with the initialization value.
324  state = state->bindDefault(retVal, Init);
325
326  // Set the region's extent equal to the Size parameter.
327  const SymbolicRegion *R =
328      dyn_cast_or_null<SymbolicRegion>(retVal.getAsRegion());
329  if (!R || !isa<DefinedOrUnknownSVal>(Size))
330    return 0;
331
332  DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
333  DefinedOrUnknownSVal DefinedSize = cast<DefinedOrUnknownSVal>(Size);
334  DefinedOrUnknownSVal extentMatchesSize =
335    svalBuilder.evalEQ(state, Extent, DefinedSize);
336
337  state = state->assume(extentMatchesSize, true);
338  assert(state);
339
340  SymbolRef Sym = retVal.getAsLocSymbol();
341  assert(Sym);
342
343  // Set the symbol's state to Allocated.
344  return state->set<RegionState>(Sym, RefState::getAllocateUnchecked(CE));
345}
346
347void MallocChecker::FreeMem(CheckerContext &C, const CallExpr *CE) const {
348  ProgramStateRef state = FreeMemAux(C, CE, C.getState(), 0, false);
349
350  if (state)
351    C.addTransition(state);
352}
353
354void MallocChecker::FreeMemAttr(CheckerContext &C, const CallExpr *CE,
355                                const OwnershipAttr* Att) const {
356  if (Att->getModule() != "malloc")
357    return;
358
359  for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
360       I != E; ++I) {
361    ProgramStateRef state =
362      FreeMemAux(C, CE, C.getState(), *I,
363                 Att->getOwnKind() == OwnershipAttr::Holds);
364    if (state)
365      C.addTransition(state);
366  }
367}
368
369ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
370                                          const CallExpr *CE,
371                                          ProgramStateRef state,
372                                          unsigned Num,
373                                          bool Hold) const {
374  const Expr *ArgExpr = CE->getArg(Num);
375  SVal ArgVal = state->getSVal(ArgExpr, C.getLocationContext());
376  if (!isa<DefinedOrUnknownSVal>(ArgVal))
377    return 0;
378  DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(ArgVal);
379
380  // Check for null dereferences.
381  if (!isa<Loc>(location))
382    return 0;
383
384  // FIXME: Technically using 'Assume' here can result in a path
385  //  bifurcation.  In such cases we need to return two states, not just one.
386  ProgramStateRef notNullState, nullState;
387  llvm::tie(notNullState, nullState) = state->assume(location);
388
389  // The explicit NULL case, no operation is performed.
390  if (nullState && !notNullState)
391    return 0;
392
393  assert(notNullState);
394
395  // Unknown values could easily be okay
396  // Undefined values are handled elsewhere
397  if (ArgVal.isUnknownOrUndef())
398    return 0;
399
400  const MemRegion *R = ArgVal.getAsRegion();
401
402  // Nonlocs can't be freed, of course.
403  // Non-region locations (labels and fixed addresses) also shouldn't be freed.
404  if (!R) {
405    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
406    return 0;
407  }
408
409  R = R->StripCasts();
410
411  // Blocks might show up as heap data, but should not be free()d
412  if (isa<BlockDataRegion>(R)) {
413    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
414    return 0;
415  }
416
417  const MemSpaceRegion *MS = R->getMemorySpace();
418
419  // Parameters, locals, statics, and globals shouldn't be freed.
420  if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
421    // FIXME: at the time this code was written, malloc() regions were
422    // represented by conjured symbols, which are all in UnknownSpaceRegion.
423    // This means that there isn't actually anything from HeapSpaceRegion
424    // that should be freed, even though we allow it here.
425    // Of course, free() can work on memory allocated outside the current
426    // function, so UnknownSpaceRegion is always a possibility.
427    // False negatives are better than false positives.
428
429    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
430    return 0;
431  }
432
433  const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R);
434  // Various cases could lead to non-symbol values here.
435  // For now, ignore them.
436  if (!SR)
437    return 0;
438
439  SymbolRef Sym = SR->getSymbol();
440  const RefState *RS = state->get<RegionState>(Sym);
441
442  // If the symbol has not been tracked, return. This is possible when free() is
443  // called on a pointer that does not get its pointee directly from malloc().
444  // Full support of this requires inter-procedural analysis.
445  if (!RS)
446    return 0;
447
448  // Check double free.
449  if (RS->isReleased()) {
450    if (ExplodedNode *N = C.generateSink()) {
451      if (!BT_DoubleFree)
452        BT_DoubleFree.reset(
453          new BuiltinBug("Double free",
454                         "Try to free a memory block that has been released"));
455      BugReport *R = new BugReport(*BT_DoubleFree,
456                                   BT_DoubleFree->getDescription(), N);
457      R->addVisitor(new MallocBugVisitor(Sym));
458      C.EmitReport(R);
459    }
460    return 0;
461  }
462
463  // Normal free.
464  if (Hold)
465    return notNullState->set<RegionState>(Sym, RefState::getRelinquished(CE));
466  return notNullState->set<RegionState>(Sym, RefState::getReleased(CE));
467}
468
469bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
470  if (nonloc::ConcreteInt *IntVal = dyn_cast<nonloc::ConcreteInt>(&V))
471    os << "an integer (" << IntVal->getValue() << ")";
472  else if (loc::ConcreteInt *ConstAddr = dyn_cast<loc::ConcreteInt>(&V))
473    os << "a constant address (" << ConstAddr->getValue() << ")";
474  else if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&V))
475    os << "the address of the label '" << Label->getLabel()->getName() << "'";
476  else
477    return false;
478
479  return true;
480}
481
482bool MallocChecker::SummarizeRegion(raw_ostream &os,
483                                    const MemRegion *MR) {
484  switch (MR->getKind()) {
485  case MemRegion::FunctionTextRegionKind: {
486    const FunctionDecl *FD = cast<FunctionTextRegion>(MR)->getDecl();
487    if (FD)
488      os << "the address of the function '" << *FD << '\'';
489    else
490      os << "the address of a function";
491    return true;
492  }
493  case MemRegion::BlockTextRegionKind:
494    os << "block text";
495    return true;
496  case MemRegion::BlockDataRegionKind:
497    // FIXME: where the block came from?
498    os << "a block";
499    return true;
500  default: {
501    const MemSpaceRegion *MS = MR->getMemorySpace();
502
503    if (isa<StackLocalsSpaceRegion>(MS)) {
504      const VarRegion *VR = dyn_cast<VarRegion>(MR);
505      const VarDecl *VD;
506      if (VR)
507        VD = VR->getDecl();
508      else
509        VD = NULL;
510
511      if (VD)
512        os << "the address of the local variable '" << VD->getName() << "'";
513      else
514        os << "the address of a local stack variable";
515      return true;
516    }
517
518    if (isa<StackArgumentsSpaceRegion>(MS)) {
519      const VarRegion *VR = dyn_cast<VarRegion>(MR);
520      const VarDecl *VD;
521      if (VR)
522        VD = VR->getDecl();
523      else
524        VD = NULL;
525
526      if (VD)
527        os << "the address of the parameter '" << VD->getName() << "'";
528      else
529        os << "the address of a parameter";
530      return true;
531    }
532
533    if (isa<GlobalsSpaceRegion>(MS)) {
534      const VarRegion *VR = dyn_cast<VarRegion>(MR);
535      const VarDecl *VD;
536      if (VR)
537        VD = VR->getDecl();
538      else
539        VD = NULL;
540
541      if (VD) {
542        if (VD->isStaticLocal())
543          os << "the address of the static variable '" << VD->getName() << "'";
544        else
545          os << "the address of the global variable '" << VD->getName() << "'";
546      } else
547        os << "the address of a global variable";
548      return true;
549    }
550
551    return false;
552  }
553  }
554}
555
556void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
557                                  SourceRange range) const {
558  if (ExplodedNode *N = C.generateSink()) {
559    if (!BT_BadFree)
560      BT_BadFree.reset(new BuiltinBug("Bad free"));
561
562    SmallString<100> buf;
563    llvm::raw_svector_ostream os(buf);
564
565    const MemRegion *MR = ArgVal.getAsRegion();
566    if (MR) {
567      while (const ElementRegion *ER = dyn_cast<ElementRegion>(MR))
568        MR = ER->getSuperRegion();
569
570      // Special case for alloca()
571      if (isa<AllocaRegion>(MR))
572        os << "Argument to free() was allocated by alloca(), not malloc()";
573      else {
574        os << "Argument to free() is ";
575        if (SummarizeRegion(os, MR))
576          os << ", which is not memory allocated by malloc()";
577        else
578          os << "not memory allocated by malloc()";
579      }
580    } else {
581      os << "Argument to free() is ";
582      if (SummarizeValue(os, ArgVal))
583        os << ", which is not memory allocated by malloc()";
584      else
585        os << "not memory allocated by malloc()";
586    }
587
588    BugReport *R = new BugReport(*BT_BadFree, os.str(), N);
589    R->addRange(range);
590    C.EmitReport(R);
591  }
592}
593
594void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
595  ProgramStateRef state = C.getState();
596  const Expr *arg0Expr = CE->getArg(0);
597  const LocationContext *LCtx = C.getLocationContext();
598  SVal Arg0Val = state->getSVal(arg0Expr, LCtx);
599  if (!isa<DefinedOrUnknownSVal>(Arg0Val))
600    return;
601  DefinedOrUnknownSVal arg0Val = cast<DefinedOrUnknownSVal>(Arg0Val);
602
603  SValBuilder &svalBuilder = C.getSValBuilder();
604
605  DefinedOrUnknownSVal PtrEQ =
606    svalBuilder.evalEQ(state, arg0Val, svalBuilder.makeNull());
607
608  // Get the size argument. If there is no size arg then give up.
609  const Expr *Arg1 = CE->getArg(1);
610  if (!Arg1)
611    return;
612
613  // Get the value of the size argument.
614  SVal Arg1ValG = state->getSVal(Arg1, LCtx);
615  if (!isa<DefinedOrUnknownSVal>(Arg1ValG))
616    return;
617  DefinedOrUnknownSVal Arg1Val = cast<DefinedOrUnknownSVal>(Arg1ValG);
618
619  // Compare the size argument to 0.
620  DefinedOrUnknownSVal SizeZero =
621    svalBuilder.evalEQ(state, Arg1Val,
622                       svalBuilder.makeIntValWithPtrWidth(0, false));
623
624  // If the ptr is NULL and the size is not 0, the call is equivalent to
625  // malloc(size).
626  ProgramStateRef stateEqual = state->assume(PtrEQ, true);
627  if (stateEqual && state->assume(SizeZero, false)) {
628    // Hack: set the NULL symbolic region to released to suppress false warning.
629    // In the future we should add more states for allocated regions, e.g.,
630    // CheckedNull, CheckedNonNull.
631
632    SymbolRef Sym = arg0Val.getAsLocSymbol();
633    if (Sym)
634      stateEqual = stateEqual->set<RegionState>(Sym, RefState::getReleased(CE));
635
636    ProgramStateRef stateMalloc = MallocMemAux(C, CE, CE->getArg(1),
637                                              UndefinedVal(), stateEqual);
638    C.addTransition(stateMalloc);
639  }
640
641  if (ProgramStateRef stateNotEqual = state->assume(PtrEQ, false)) {
642    // If the size is 0, free the memory.
643    if (ProgramStateRef stateSizeZero =
644          stateNotEqual->assume(SizeZero, true))
645      if (ProgramStateRef stateFree =
646          FreeMemAux(C, CE, stateSizeZero, 0, false)) {
647
648        // Bind the return value to NULL because it is now free.
649        C.addTransition(stateFree->BindExpr(CE, LCtx,
650                                            svalBuilder.makeNull(), true));
651      }
652    if (ProgramStateRef stateSizeNotZero =
653          stateNotEqual->assume(SizeZero,false))
654      if (ProgramStateRef stateFree = FreeMemAux(C, CE, stateSizeNotZero,
655                                                0, false)) {
656        // FIXME: We should copy the content of the original buffer.
657        ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
658                                                   UnknownVal(), stateFree);
659        C.addTransition(stateRealloc);
660      }
661  }
662}
663
664void MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE) {
665  ProgramStateRef state = C.getState();
666  SValBuilder &svalBuilder = C.getSValBuilder();
667  const LocationContext *LCtx = C.getLocationContext();
668  SVal count = state->getSVal(CE->getArg(0), LCtx);
669  SVal elementSize = state->getSVal(CE->getArg(1), LCtx);
670  SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, count, elementSize,
671                                        svalBuilder.getContext().getSizeType());
672  SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
673
674  C.addTransition(MallocMemAux(C, CE, TotalSize, zeroVal, state));
675}
676
677void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
678                               CheckerContext &C) const {
679  assert(N);
680  if (!BT_Leak) {
681    BT_Leak.reset(new BuiltinBug("Memory leak",
682        "Allocated memory never released. Potential memory leak."));
683    // Leaks should not be reported if they are post-dominated by a sink:
684    // (1) Sinks are higher importance bugs.
685    // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
686    //     with __noreturn functions such as assert() or exit(). We choose not
687    //     to report leaks on such paths.
688    BT_Leak->setSuppressOnSink(true);
689  }
690
691  BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
692  R->addVisitor(new MallocBugVisitor(Sym));
693  C.EmitReport(R);
694}
695
696void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
697                                     CheckerContext &C) const
698{
699  if (!SymReaper.hasDeadSymbols())
700    return;
701
702  ProgramStateRef state = C.getState();
703  RegionStateTy RS = state->get<RegionState>();
704  RegionStateTy::Factory &F = state->get_context<RegionState>();
705
706  bool generateReport = false;
707  llvm::SmallVector<SymbolRef, 2> Errors;
708  for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
709    if (SymReaper.isDead(I->first)) {
710      if (I->second.isAllocated()) {
711        generateReport = true;
712        Errors.push_back(I->first);
713      }
714      // Remove the dead symbol from the map.
715      RS = F.remove(RS, I->first);
716
717    }
718  }
719
720  ExplodedNode *N = C.addTransition(state->set<RegionState>(RS));
721
722  if (N && generateReport) {
723    for (llvm::SmallVector<SymbolRef, 2>::iterator
724         I = Errors.begin(), E = Errors.end(); I != E; ++I) {
725      reportLeak(*I, N, C);
726    }
727  }
728}
729
730void MallocChecker::checkEndPath(CheckerContext &C) const {
731  ProgramStateRef state = C.getState();
732  RegionStateTy M = state->get<RegionState>();
733
734  for (RegionStateTy::iterator I = M.begin(), E = M.end(); I != E; ++I) {
735    RefState RS = I->second;
736    if (RS.isAllocated()) {
737      ExplodedNode *N = C.addTransition(state);
738      if (N)
739        reportLeak(I->first, N, C);
740    }
741  }
742}
743
744bool MallocChecker::checkEscape(SymbolRef Sym, const Stmt *S,
745                                CheckerContext &C) const {
746  ProgramStateRef state = C.getState();
747  const RefState *RS = state->get<RegionState>(Sym);
748  if (!RS)
749    return false;
750
751  if (RS->isAllocated()) {
752    state = state->set<RegionState>(Sym, RefState::getEscaped(S));
753    C.addTransition(state);
754    return true;
755  }
756  return false;
757}
758
759void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
760  const Expr *E = S->getRetValue();
761  if (!E)
762    return;
763  SymbolRef Sym = C.getState()->getSVal(E, C.getLocationContext()).getAsSymbol();
764  if (!Sym)
765    return;
766
767  checkEscape(Sym, S, C);
768}
769
770bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
771                                      const Stmt *S) const {
772  assert(Sym);
773  const RefState *RS = C.getState()->get<RegionState>(Sym);
774  if (RS && RS->isReleased()) {
775    if (ExplodedNode *N = C.addTransition()) {
776      if (!BT_UseFree)
777        BT_UseFree.reset(new BuiltinBug("Use of dynamically allocated memory "
778            "after it is freed."));
779
780      BugReport *R = new BugReport(*BT_UseFree, BT_UseFree->getDescription(),N);
781      if (S)
782        R->addRange(S->getSourceRange());
783      R->addVisitor(new MallocBugVisitor(Sym));
784      C.EmitReport(R);
785      return true;
786    }
787  }
788  return false;
789}
790
791// Check if the location is a freed symbolic region.
792void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
793                                  CheckerContext &C) const {
794  SymbolRef Sym = l.getLocSymbolInBase();
795  if (Sym)
796    checkUseAfterFree(Sym, C);
797}
798
799//===----------------------------------------------------------------------===//
800// Check various ways a symbol can be invalidated.
801// TODO: This logic (the next 3 functions) is copied/similar to the
802// RetainRelease checker. We might want to factor this out.
803//===----------------------------------------------------------------------===//
804
805// Stop tracking symbols when a value escapes as a result of checkBind.
806// A value escapes in three possible cases:
807// (1) we are binding to something that is not a memory region.
808// (2) we are binding to a memregion that does not have stack storage
809// (3) we are binding to a memregion with stack storage that the store
810//     does not understand.
811void MallocChecker::checkBind(SVal loc, SVal val, const Stmt *S,
812                              CheckerContext &C) const {
813  // Are we storing to something that causes the value to "escape"?
814  bool escapes = true;
815  ProgramStateRef state = C.getState();
816
817  if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&loc)) {
818    escapes = !regionLoc->getRegion()->hasStackStorage();
819
820    if (!escapes) {
821      // To test (3), generate a new state with the binding added.  If it is
822      // the same state, then it escapes (since the store cannot represent
823      // the binding).
824      escapes = (state == (state->bindLoc(*regionLoc, val)));
825    }
826  }
827
828  // If our store can represent the binding and we aren't storing to something
829  // that doesn't have local storage then just return and have the simulation
830  // state continue as is.
831  if (!escapes)
832      return;
833
834  // Otherwise, find all symbols referenced by 'val' that we are tracking
835  // and stop tracking them.
836  state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
837  C.addTransition(state);
838}
839
840// If a symbolic region is assumed to NULL (or another constant), stop tracking
841// it - assuming that allocation failed on this path.
842ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state,
843                                              SVal Cond,
844                                              bool Assumption) const {
845  RegionStateTy RS = state->get<RegionState>();
846
847  for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
848    // If the symbol is assumed to NULL or another constant, this will
849    // return an APSInt*.
850    if (state->getSymVal(I.getKey()))
851      state = state->remove<RegionState>(I.getKey());
852  }
853
854  return state;
855}
856
857// If the symbol we are tracking is invalidated, but not explicitly (ex: the &p
858// escapes, when we are tracking p), do not track the symbol as we cannot reason
859// about it anymore.
860ProgramStateRef
861MallocChecker::checkRegionChanges(ProgramStateRef state,
862                            const StoreManager::InvalidatedSymbols *invalidated,
863                                    ArrayRef<const MemRegion *> ExplicitRegions,
864                                    ArrayRef<const MemRegion *> Regions) const {
865  if (!invalidated)
866    return state;
867
868  llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
869  for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
870       E = ExplicitRegions.end(); I != E; ++I) {
871    if (const SymbolicRegion *SR = (*I)->StripCasts()->getAs<SymbolicRegion>())
872      WhitelistedSymbols.insert(SR->getSymbol());
873  }
874
875  for (StoreManager::InvalidatedSymbols::const_iterator I=invalidated->begin(),
876       E = invalidated->end(); I!=E; ++I) {
877    SymbolRef sym = *I;
878    if (WhitelistedSymbols.count(sym))
879      continue;
880    // Don't track the symbol.
881    state = state->remove<RegionState>(sym);
882  }
883  return state;
884}
885
886PathDiagnosticPiece *
887MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N,
888                                           const ExplodedNode *PrevN,
889                                           BugReporterContext &BRC,
890                                           BugReport &BR) {
891  const RefState *RS = N->getState()->get<RegionState>(Sym);
892  const RefState *RSPrev = PrevN->getState()->get<RegionState>(Sym);
893  if (!RS && !RSPrev)
894    return 0;
895
896  // We expect the interesting locations be StmtPoints corresponding to call
897  // expressions. We do not support indirect function calls as of now.
898  const CallExpr *CE = 0;
899  if (isa<StmtPoint>(N->getLocation()))
900    CE = dyn_cast<CallExpr>(cast<StmtPoint>(N->getLocation()).getStmt());
901  if (!CE)
902    return 0;
903  const FunctionDecl *funDecl = CE->getDirectCallee();
904  if (!funDecl)
905    return 0;
906
907  // Find out if this is an interesting point and what is the kind.
908  const char *Msg = 0;
909  if (isAllocated(RS, RSPrev))
910    Msg = "Memory is allocated here";
911  else if (isReleased(RS, RSPrev))
912    Msg = "Memory is released here";
913  if (!Msg)
914    return 0;
915
916  // Generate the extra diagnostic.
917  PathDiagnosticLocation Pos(CE, BRC.getSourceManager(),
918                             N->getLocationContext());
919  return new PathDiagnosticEventPiece(Pos, Msg);
920}
921
922
923#define REGISTER_CHECKER(name) \
924void ento::register##name(CheckerManager &mgr) {\
925  mgr.registerChecker<MallocChecker>()->Filter.C##name = true;\
926}
927
928REGISTER_CHECKER(MallocPessimistic)
929REGISTER_CHECKER(MallocOptimistic)
930