MallocChecker.cpp revision 2de19edab6001d2c17720d02fe0760b9b452192a
1//=== MallocChecker.cpp - A malloc/free checker -------------------*- C++ -*--//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines malloc/free checker, which checks for potential memory
11// leaks, double free, and use-after-free problems.
12//
13//===----------------------------------------------------------------------===//
14
15#include "ClangSACheckers.h"
16#include "InterCheckerAPI.h"
17#include "clang/AST/Attr.h"
18#include "clang/Basic/SourceManager.h"
19#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
20#include "clang/StaticAnalyzer/Core/Checker.h"
21#include "clang/StaticAnalyzer/Core/CheckerManager.h"
22#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
23#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
24#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
25#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
26#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
27#include "llvm/ADT/ImmutableMap.h"
28#include "llvm/ADT/STLExtras.h"
29#include "llvm/ADT/SmallString.h"
30#include "llvm/ADT/StringExtras.h"
31#include <climits>
32
33using namespace clang;
34using namespace ento;
35
36namespace {
37
38class RefState {
39  enum Kind { // Reference to allocated memory.
40              Allocated,
41              // Reference to released/freed memory.
42              Released,
43              // The responsibility for freeing resources has transfered from
44              // this reference. A relinquished symbol should not be freed.
45              Relinquished } K;
46  const Stmt *S;
47
48public:
49  RefState(Kind k, const Stmt *s) : K(k), S(s) {}
50
51  bool isAllocated() const { return K == Allocated; }
52  bool isReleased() const { return K == Released; }
53  bool isRelinquished() const { return K == Relinquished; }
54
55  const Stmt *getStmt() const { return S; }
56
57  bool operator==(const RefState &X) const {
58    return K == X.K && S == X.S;
59  }
60
61  static RefState getAllocated(const Stmt *s) {
62    return RefState(Allocated, s);
63  }
64  static RefState getReleased(const Stmt *s) { return RefState(Released, s); }
65  static RefState getRelinquished(const Stmt *s) {
66    return RefState(Relinquished, s);
67  }
68
69  void Profile(llvm::FoldingSetNodeID &ID) const {
70    ID.AddInteger(K);
71    ID.AddPointer(S);
72  }
73
74  void dump(raw_ostream &OS) const {
75    static const char *Table[] = {
76      "Allocated",
77      "Released",
78      "Relinquished"
79    };
80    OS << Table[(unsigned) K];
81  }
82
83  LLVM_ATTRIBUTE_USED void dump() const {
84    dump(llvm::errs());
85  }
86};
87
88enum ReallocPairKind {
89  RPToBeFreedAfterFailure,
90  // The symbol has been freed when reallocation failed.
91  RPIsFreeOnFailure,
92  // The symbol does not need to be freed after reallocation fails.
93  RPDoNotTrackAfterFailure
94};
95
96/// \class ReallocPair
97/// \brief Stores information about the symbol being reallocated by a call to
98/// 'realloc' to allow modeling failed reallocation later in the path.
99struct ReallocPair {
100  // \brief The symbol which realloc reallocated.
101  SymbolRef ReallocatedSym;
102  ReallocPairKind Kind;
103
104  ReallocPair(SymbolRef S, ReallocPairKind K) :
105    ReallocatedSym(S), Kind(K) {}
106  void Profile(llvm::FoldingSetNodeID &ID) const {
107    ID.AddInteger(Kind);
108    ID.AddPointer(ReallocatedSym);
109  }
110  bool operator==(const ReallocPair &X) const {
111    return ReallocatedSym == X.ReallocatedSym &&
112           Kind == X.Kind;
113  }
114};
115
116typedef std::pair<const ExplodedNode*, const MemRegion*> LeakInfo;
117
118class MallocChecker : public Checker<check::DeadSymbols,
119                                     check::PointerEscape,
120                                     check::PreStmt<ReturnStmt>,
121                                     check::PreStmt<CallExpr>,
122                                     check::PostStmt<CallExpr>,
123                                     check::PostStmt<CXXNewExpr>,
124                                     check::PreStmt<CXXDeleteExpr>,
125                                     check::PostStmt<BlockExpr>,
126                                     check::PostObjCMessage,
127                                     check::Location,
128                                     eval::Assume>
129{
130  mutable OwningPtr<BugType> BT_DoubleFree;
131  mutable OwningPtr<BugType> BT_Leak;
132  mutable OwningPtr<BugType> BT_UseFree;
133  mutable OwningPtr<BugType> BT_BadFree;
134  mutable OwningPtr<BugType> BT_OffsetFree;
135  mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc,
136                         *II_valloc, *II_reallocf, *II_strndup, *II_strdup;
137
138public:
139  MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0),
140                    II_valloc(0), II_reallocf(0), II_strndup(0), II_strdup(0) {}
141
142  /// In pessimistic mode, the checker assumes that it does not know which
143  /// functions might free the memory.
144  struct ChecksFilter {
145    DefaultBool CMallocPessimistic;
146    DefaultBool CMallocOptimistic;
147    DefaultBool CNewDeleteChecker;
148  };
149
150  ChecksFilter Filter;
151
152  void checkPreStmt(const CallExpr *S, CheckerContext &C) const;
153  void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
154  void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const;
155  void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
156  void checkPostObjCMessage(const ObjCMethodCall &Call, CheckerContext &C) const;
157  void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
158  void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
159  void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
160  ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
161                            bool Assumption) const;
162  void checkLocation(SVal l, bool isLoad, const Stmt *S,
163                     CheckerContext &C) const;
164
165  ProgramStateRef checkPointerEscape(ProgramStateRef State,
166                                    const InvalidatedSymbols &Escaped,
167                                    const CallEvent *Call,
168                                    PointerEscapeKind Kind) const;
169
170  void printState(raw_ostream &Out, ProgramStateRef State,
171                  const char *NL, const char *Sep) const;
172
173private:
174  void initIdentifierInfo(ASTContext &C) const;
175
176  ///@{
177  /// Check if this is one of the functions which can allocate/reallocate memory
178  /// pointed to by one of its arguments.
179  bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const;
180  bool isFreeFunction(const FunctionDecl *FD, ASTContext &C) const;
181  bool isAllocationFunction(const FunctionDecl *FD, ASTContext &C) const;
182  bool isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const;
183  ///@}
184  static ProgramStateRef MallocMemReturnsAttr(CheckerContext &C,
185                                              const CallExpr *CE,
186                                              const OwnershipAttr* Att);
187  static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
188                                     const Expr *SizeEx, SVal Init,
189                                     ProgramStateRef state) {
190    return MallocMemAux(C, CE,
191                        state->getSVal(SizeEx, C.getLocationContext()),
192                        Init, state);
193  }
194
195  static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
196                                     SVal SizeEx, SVal Init,
197                                     ProgramStateRef state);
198
199  /// Update the RefState to reflect the new memory allocation.
200  static ProgramStateRef MallocUpdateRefState(CheckerContext &C,
201                                              const Expr *E,
202                                              ProgramStateRef state);
203
204  ProgramStateRef FreeMemAttr(CheckerContext &C, const CallExpr *CE,
205                              const OwnershipAttr* Att) const;
206  ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE,
207                             ProgramStateRef state, unsigned Num,
208                             bool Hold,
209                             bool &ReleasedAllocated,
210                             bool ReturnsNullOnFailure = false) const;
211  ProgramStateRef FreeMemAux(CheckerContext &C, const Expr *Arg,
212                             const Expr *ParentExpr,
213                             ProgramStateRef State,
214                             bool Hold,
215                             bool &ReleasedAllocated,
216                             bool ReturnsNullOnFailure = false) const;
217
218  ProgramStateRef ReallocMem(CheckerContext &C, const CallExpr *CE,
219                             bool FreesMemOnFailure) const;
220  static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE);
221
222  ///\brief Check if the memory associated with this symbol was released.
223  bool isReleased(SymbolRef Sym, CheckerContext &C) const;
224
225  bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const;
226
227  /// Check if the function is known not to free memory, or if it is
228  /// "interesting" and should be modeled explicitly.
229  ///
230  /// We assume that pointers do not escape through calls to system functions
231  /// not handled by this checker.
232  bool doesNotFreeMemOrInteresting(const CallEvent *Call,
233                                   ProgramStateRef State) const;
234
235  static bool SummarizeValue(raw_ostream &os, SVal V);
236  static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
237  void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange Range) const;
238  void ReportBadDealloc(CheckerContext &C, SourceRange Range,
239                        const Expr *DeallocExpr, const RefState *RS) const;
240  void ReportOffsetFree(CheckerContext &C, SVal ArgVal, SourceRange Range)const;
241  void ReportUseAfterFree(CheckerContext &C, SourceRange Range,
242                          SymbolRef Sym) const;
243  void ReportDoubleFree(CheckerContext &C, SourceRange Range, bool Released,
244                        SymbolRef Sym, SymbolRef PrevSym) const;
245
246  /// Find the location of the allocation for Sym on the path leading to the
247  /// exploded node N.
248  LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
249                             CheckerContext &C) const;
250
251  void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const;
252
253  /// The bug visitor which allows us to print extra diagnostics along the
254  /// BugReport path. For example, showing the allocation site of the leaked
255  /// region.
256  class MallocBugVisitor : public BugReporterVisitorImpl<MallocBugVisitor> {
257  protected:
258    enum NotificationMode {
259      Normal,
260      ReallocationFailed
261    };
262
263    // The allocated region symbol tracked by the main analysis.
264    SymbolRef Sym;
265
266    // The mode we are in, i.e. what kind of diagnostics will be emitted.
267    NotificationMode Mode;
268
269    // A symbol from when the primary region should have been reallocated.
270    SymbolRef FailedReallocSymbol;
271
272    bool IsLeak;
273
274  public:
275    MallocBugVisitor(SymbolRef S, bool isLeak = false)
276       : Sym(S), Mode(Normal), FailedReallocSymbol(0), IsLeak(isLeak) {}
277
278    virtual ~MallocBugVisitor() {}
279
280    void Profile(llvm::FoldingSetNodeID &ID) const {
281      static int X = 0;
282      ID.AddPointer(&X);
283      ID.AddPointer(Sym);
284    }
285
286    inline bool isAllocated(const RefState *S, const RefState *SPrev,
287                            const Stmt *Stmt) {
288      // Did not track -> allocated. Other state (released) -> allocated.
289      return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXNewExpr>(Stmt)) &&
290              (S && S->isAllocated()) && (!SPrev || !SPrev->isAllocated()));
291    }
292
293    inline bool isReleased(const RefState *S, const RefState *SPrev,
294                           const Stmt *Stmt) {
295      // Did not track -> released. Other state (allocated) -> released.
296      return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXDeleteExpr>(Stmt)) &&
297              (S && S->isReleased()) && (!SPrev || !SPrev->isReleased()));
298    }
299
300    inline bool isRelinquished(const RefState *S, const RefState *SPrev,
301                               const Stmt *Stmt) {
302      // Did not track -> relinquished. Other state (allocated) -> relinquished.
303      return (Stmt && (isa<CallExpr>(Stmt) || isa<ObjCMessageExpr>(Stmt) ||
304                                              isa<ObjCPropertyRefExpr>(Stmt)) &&
305              (S && S->isRelinquished()) &&
306              (!SPrev || !SPrev->isRelinquished()));
307    }
308
309    inline bool isReallocFailedCheck(const RefState *S, const RefState *SPrev,
310                                     const Stmt *Stmt) {
311      // If the expression is not a call, and the state change is
312      // released -> allocated, it must be the realloc return value
313      // check. If we have to handle more cases here, it might be cleaner just
314      // to track this extra bit in the state itself.
315      return ((!Stmt || !isa<CallExpr>(Stmt)) &&
316              (S && S->isAllocated()) && (SPrev && !SPrev->isAllocated()));
317    }
318
319    PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
320                                   const ExplodedNode *PrevN,
321                                   BugReporterContext &BRC,
322                                   BugReport &BR);
323
324    PathDiagnosticPiece* getEndPath(BugReporterContext &BRC,
325                                    const ExplodedNode *EndPathNode,
326                                    BugReport &BR) {
327      if (!IsLeak)
328        return 0;
329
330      PathDiagnosticLocation L =
331        PathDiagnosticLocation::createEndOfPath(EndPathNode,
332                                                BRC.getSourceManager());
333      // Do not add the statement itself as a range in case of leak.
334      return new PathDiagnosticEventPiece(L, BR.getDescription(), false);
335    }
336
337  private:
338    class StackHintGeneratorForReallocationFailed
339        : public StackHintGeneratorForSymbol {
340    public:
341      StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M)
342        : StackHintGeneratorForSymbol(S, M) {}
343
344      virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex) {
345        // Printed parameters start at 1, not 0.
346        ++ArgIndex;
347
348        SmallString<200> buf;
349        llvm::raw_svector_ostream os(buf);
350
351        os << "Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex)
352           << " parameter failed";
353
354        return os.str();
355      }
356
357      virtual std::string getMessageForReturn(const CallExpr *CallExpr) {
358        return "Reallocation of returned value failed";
359      }
360    };
361  };
362};
363} // end anonymous namespace
364
365REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState)
366REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair)
367
368// A map from the freed symbol to the symbol representing the return value of
369// the free function.
370REGISTER_MAP_WITH_PROGRAMSTATE(FreeReturnValue, SymbolRef, SymbolRef)
371
372namespace {
373class StopTrackingCallback : public SymbolVisitor {
374  ProgramStateRef state;
375public:
376  StopTrackingCallback(ProgramStateRef st) : state(st) {}
377  ProgramStateRef getState() const { return state; }
378
379  bool VisitSymbol(SymbolRef sym) {
380    state = state->remove<RegionState>(sym);
381    return true;
382  }
383};
384} // end anonymous namespace
385
386void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const {
387  if (II_malloc)
388    return;
389  II_malloc = &Ctx.Idents.get("malloc");
390  II_free = &Ctx.Idents.get("free");
391  II_realloc = &Ctx.Idents.get("realloc");
392  II_reallocf = &Ctx.Idents.get("reallocf");
393  II_calloc = &Ctx.Idents.get("calloc");
394  II_valloc = &Ctx.Idents.get("valloc");
395  II_strdup = &Ctx.Idents.get("strdup");
396  II_strndup = &Ctx.Idents.get("strndup");
397}
398
399bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const {
400  if (isFreeFunction(FD, C))
401    return true;
402
403  if (isAllocationFunction(FD, C))
404    return true;
405
406  if (isStandardNewDelete(FD, C))
407    return true;
408
409  return false;
410}
411
412bool MallocChecker::isAllocationFunction(const FunctionDecl *FD,
413                                         ASTContext &C) const {
414  if (!FD)
415    return false;
416
417  if (FD->getKind() == Decl::Function) {
418    IdentifierInfo *FunI = FD->getIdentifier();
419    initIdentifierInfo(C);
420
421    if (FunI == II_malloc || FunI == II_realloc ||
422        FunI == II_reallocf || FunI == II_calloc || FunI == II_valloc ||
423        FunI == II_strdup || FunI == II_strndup)
424      return true;
425  }
426
427  if (Filter.CMallocOptimistic && FD->hasAttrs())
428    for (specific_attr_iterator<OwnershipAttr>
429           i = FD->specific_attr_begin<OwnershipAttr>(),
430           e = FD->specific_attr_end<OwnershipAttr>();
431           i != e; ++i)
432      if ((*i)->getOwnKind() == OwnershipAttr::Returns)
433        return true;
434  return false;
435}
436
437bool MallocChecker::isFreeFunction(const FunctionDecl *FD, ASTContext &C) const {
438  if (!FD)
439    return false;
440
441  if (FD->getKind() == Decl::Function) {
442    IdentifierInfo *FunI = FD->getIdentifier();
443    initIdentifierInfo(C);
444
445    if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf)
446      return true;
447  }
448
449  if (Filter.CMallocOptimistic && FD->hasAttrs())
450    for (specific_attr_iterator<OwnershipAttr>
451           i = FD->specific_attr_begin<OwnershipAttr>(),
452           e = FD->specific_attr_end<OwnershipAttr>();
453           i != e; ++i)
454      if ((*i)->getOwnKind() == OwnershipAttr::Takes ||
455          (*i)->getOwnKind() == OwnershipAttr::Holds)
456        return true;
457  return false;
458}
459
460bool MallocChecker::isStandardNewDelete(const FunctionDecl *FD,
461                                        ASTContext &C) const {
462  if (!FD)
463    return false;
464
465  OverloadedOperatorKind Kind = FD->getOverloadedOperator();
466  if (Kind != OO_New && Kind != OO_Array_New &&
467      Kind != OO_Delete && Kind != OO_Array_Delete)
468    return false;
469
470  // Skip custom new operators.
471  if (!FD->isImplicit() &&
472      !C.getSourceManager().isInSystemHeader(FD->getLocStart()))
473    return false;
474
475  // Return true if tested operator is a standard placement nothrow operator.
476  if (FD->getNumParams() == 2) {
477    QualType T = FD->getParamDecl(1)->getType();
478    if (const IdentifierInfo *II = T.getBaseTypeIdentifier())
479      return II->getName().equals("nothrow_t");
480  }
481
482  // Skip placement operators.
483  if (FD->getNumParams() != 1 || FD->isVariadic())
484    return false;
485
486  // One of the standard new/new[]/delete/delete[] non-placement operators.
487  return true;
488}
489
490void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
491  if (C.wasInlined)
492    return;
493
494  const FunctionDecl *FD = C.getCalleeDecl(CE);
495  if (!FD)
496    return;
497
498  ProgramStateRef State = C.getState();
499  bool ReleasedAllocatedMemory = false;
500
501  if (FD->getKind() == Decl::Function) {
502    initIdentifierInfo(C.getASTContext());
503    IdentifierInfo *FunI = FD->getIdentifier();
504
505    if (Filter.CMallocOptimistic || Filter.CMallocPessimistic) {
506      if (FunI == II_malloc || FunI == II_valloc) {
507        if (CE->getNumArgs() < 1)
508          return;
509        State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
510      } else if (FunI == II_realloc) {
511        State = ReallocMem(C, CE, false);
512      } else if (FunI == II_reallocf) {
513        State = ReallocMem(C, CE, true);
514      } else if (FunI == II_calloc) {
515        State = CallocMem(C, CE);
516      } else if (FunI == II_free) {
517        State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
518      } else if (FunI == II_strdup) {
519        State = MallocUpdateRefState(C, CE, State);
520      } else if (FunI == II_strndup) {
521        State = MallocUpdateRefState(C, CE, State);
522      }
523    }
524
525    if (Filter.CNewDeleteChecker) {
526      if (isStandardNewDelete(FD, C.getASTContext())) {
527        // Process direct calls to operator new/new[]/delete/delete[] functions
528        // as distinct from new/new[]/delete/delete[] expressions that are
529        // processed by the checkPostStmt callbacks for CXXNewExpr and
530        // CXXDeleteExpr.
531        OverloadedOperatorKind K = FD->getOverloadedOperator();
532        if (K == OO_New)
533          State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
534        else if (K == OO_Array_New)
535          State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
536        else if (K == OO_Delete || K == OO_Array_Delete)
537          State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
538        else
539          llvm_unreachable("not a new/delete operator");
540      }
541    }
542  }
543
544  if (Filter.CMallocOptimistic) {
545    // Check all the attributes, if there are any.
546    // There can be multiple of these attributes.
547    if (FD->hasAttrs())
548      for (specific_attr_iterator<OwnershipAttr>
549          i = FD->specific_attr_begin<OwnershipAttr>(),
550          e = FD->specific_attr_end<OwnershipAttr>();
551          i != e; ++i) {
552        switch ((*i)->getOwnKind()) {
553        case OwnershipAttr::Returns:
554          State = MallocMemReturnsAttr(C, CE, *i);
555          break;
556        case OwnershipAttr::Takes:
557        case OwnershipAttr::Holds:
558          State = FreeMemAttr(C, CE, *i);
559          break;
560        }
561      }
562  }
563  C.addTransition(State);
564}
565
566void MallocChecker::checkPostStmt(const CXXNewExpr *NE,
567                                  CheckerContext &C) const {
568
569  if (NE->getNumPlacementArgs())
570    for (CXXNewExpr::const_arg_iterator I = NE->placement_arg_begin(),
571         E = NE->placement_arg_end(); I != E; ++I)
572      if (SymbolRef Sym = C.getSVal(*I).getAsSymbol())
573        checkUseAfterFree(Sym, C, *I);
574
575  if (!Filter.CNewDeleteChecker)
576    return;
577
578  if (!isStandardNewDelete(NE->getOperatorNew(), C.getASTContext()))
579    return;
580
581  ProgramStateRef State = C.getState();
582  // The return value from operator new is bound to a specified initialization
583  // value (if any) and we don't want to loose this value. So we call
584  // MallocUpdateRefState() instead of MallocMemAux() which breakes the
585  // existing binding.
586  State = MallocUpdateRefState(C, NE, State);
587  C.addTransition(State);
588}
589
590void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE,
591                                 CheckerContext &C) const {
592
593  if (!Filter.CNewDeleteChecker) {
594    if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol())
595      checkUseAfterFree(Sym, C, DE->getArgument());
596
597    return;
598  }
599
600  if (!isStandardNewDelete(DE->getOperatorDelete(), C.getASTContext()))
601    return;
602
603  ProgramStateRef State = C.getState();
604  bool ReleasedAllocated;
605  State = FreeMemAux(C, DE->getArgument(), DE, State,
606                     /*Hold*/false, ReleasedAllocated);
607
608  C.addTransition(State);
609}
610
611static bool isKnownDeallocObjCMethodName(const ObjCMethodCall &Call) {
612  // If the first selector piece is one of the names below, assume that the
613  // object takes ownership of the memory, promising to eventually deallocate it
614  // with free().
615  // Ex:  [NSData dataWithBytesNoCopy:bytes length:10];
616  // (...unless a 'freeWhenDone' parameter is false, but that's checked later.)
617  StringRef FirstSlot = Call.getSelector().getNameForSlot(0);
618  if (FirstSlot == "dataWithBytesNoCopy" ||
619      FirstSlot == "initWithBytesNoCopy" ||
620      FirstSlot == "initWithCharactersNoCopy")
621    return true;
622
623  return false;
624}
625
626static Optional<bool> getFreeWhenDoneArg(const ObjCMethodCall &Call) {
627  Selector S = Call.getSelector();
628
629  // FIXME: We should not rely on fully-constrained symbols being folded.
630  for (unsigned i = 1; i < S.getNumArgs(); ++i)
631    if (S.getNameForSlot(i).equals("freeWhenDone"))
632      return !Call.getArgSVal(i).isZeroConstant();
633
634  return None;
635}
636
637void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call,
638                                         CheckerContext &C) const {
639  if (C.wasInlined)
640    return;
641
642  if (!isKnownDeallocObjCMethodName(Call))
643    return;
644
645  if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(Call))
646    if (!*FreeWhenDone)
647      return;
648
649  bool ReleasedAllocatedMemory;
650  ProgramStateRef State = FreeMemAux(C, Call.getArgExpr(0),
651                                     Call.getOriginExpr(), C.getState(),
652                                     /*Hold=*/true, ReleasedAllocatedMemory,
653                                     /*RetNullOnFailure=*/true);
654
655  C.addTransition(State);
656}
657
658ProgramStateRef MallocChecker::MallocMemReturnsAttr(CheckerContext &C,
659                                                    const CallExpr *CE,
660                                                    const OwnershipAttr* Att) {
661  if (Att->getModule() != "malloc")
662    return 0;
663
664  OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
665  if (I != E) {
666    return MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState());
667  }
668  return MallocMemAux(C, CE, UnknownVal(), UndefinedVal(), C.getState());
669}
670
671ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
672                                           const CallExpr *CE,
673                                           SVal Size, SVal Init,
674                                           ProgramStateRef state) {
675
676  // Bind the return value to the symbolic value from the heap region.
677  // TODO: We could rewrite post visit to eval call; 'malloc' does not have
678  // side effects other than what we model here.
679  unsigned Count = C.blockCount();
680  SValBuilder &svalBuilder = C.getSValBuilder();
681  const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
682  DefinedSVal RetVal = svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count)
683      .castAs<DefinedSVal>();
684  state = state->BindExpr(CE, C.getLocationContext(), RetVal);
685
686  // We expect the malloc functions to return a pointer.
687  if (!RetVal.getAs<Loc>())
688    return 0;
689
690  // Fill the region with the initialization value.
691  state = state->bindDefault(RetVal, Init);
692
693  // Set the region's extent equal to the Size parameter.
694  const SymbolicRegion *R =
695      dyn_cast_or_null<SymbolicRegion>(RetVal.getAsRegion());
696  if (!R)
697    return 0;
698  if (Optional<DefinedOrUnknownSVal> DefinedSize =
699          Size.getAs<DefinedOrUnknownSVal>()) {
700    SValBuilder &svalBuilder = C.getSValBuilder();
701    DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
702    DefinedOrUnknownSVal extentMatchesSize =
703        svalBuilder.evalEQ(state, Extent, *DefinedSize);
704
705    state = state->assume(extentMatchesSize, true);
706    assert(state);
707  }
708
709  return MallocUpdateRefState(C, CE, state);
710}
711
712ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C,
713                                                    const Expr *E,
714                                                    ProgramStateRef state) {
715  // Get the return value.
716  SVal retVal = state->getSVal(E, C.getLocationContext());
717
718  // We expect the malloc functions to return a pointer.
719  if (!retVal.getAs<Loc>())
720    return 0;
721
722  SymbolRef Sym = retVal.getAsLocSymbol();
723  assert(Sym);
724
725  // Set the symbol's state to Allocated.
726  return state->set<RegionState>(Sym, RefState::getAllocated(E));
727
728}
729
730ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C,
731                                           const CallExpr *CE,
732                                           const OwnershipAttr* Att) const {
733  if (Att->getModule() != "malloc")
734    return 0;
735
736  ProgramStateRef State = C.getState();
737  bool ReleasedAllocated = false;
738
739  for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
740       I != E; ++I) {
741    ProgramStateRef StateI = FreeMemAux(C, CE, State, *I,
742                               Att->getOwnKind() == OwnershipAttr::Holds,
743                               ReleasedAllocated);
744    if (StateI)
745      State = StateI;
746  }
747  return State;
748}
749
750ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
751                                          const CallExpr *CE,
752                                          ProgramStateRef state,
753                                          unsigned Num,
754                                          bool Hold,
755                                          bool &ReleasedAllocated,
756                                          bool ReturnsNullOnFailure) const {
757  if (CE->getNumArgs() < (Num + 1))
758    return 0;
759
760  return FreeMemAux(C, CE->getArg(Num), CE, state, Hold,
761                    ReleasedAllocated, ReturnsNullOnFailure);
762}
763
764/// Checks if the previous call to free on the given symbol failed - if free
765/// failed, returns true. Also, returns the corresponding return value symbol.
766static bool didPreviousFreeFail(ProgramStateRef State,
767                                SymbolRef Sym, SymbolRef &RetStatusSymbol) {
768  const SymbolRef *Ret = State->get<FreeReturnValue>(Sym);
769  if (Ret) {
770    assert(*Ret && "We should not store the null return symbol");
771    ConstraintManager &CMgr = State->getConstraintManager();
772    ConditionTruthVal FreeFailed = CMgr.isNull(State, *Ret);
773    RetStatusSymbol = *Ret;
774    return FreeFailed.isConstrainedTrue();
775  }
776  return false;
777}
778
779ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
780                                          const Expr *ArgExpr,
781                                          const Expr *ParentExpr,
782                                          ProgramStateRef State,
783                                          bool Hold,
784                                          bool &ReleasedAllocated,
785                                          bool ReturnsNullOnFailure) const {
786
787  SVal ArgVal = State->getSVal(ArgExpr, C.getLocationContext());
788  if (!ArgVal.getAs<DefinedOrUnknownSVal>())
789    return 0;
790  DefinedOrUnknownSVal location = ArgVal.castAs<DefinedOrUnknownSVal>();
791
792  // Check for null dereferences.
793  if (!location.getAs<Loc>())
794    return 0;
795
796  // The explicit NULL case, no operation is performed.
797  ProgramStateRef notNullState, nullState;
798  llvm::tie(notNullState, nullState) = State->assume(location);
799  if (nullState && !notNullState)
800    return 0;
801
802  // Unknown values could easily be okay
803  // Undefined values are handled elsewhere
804  if (ArgVal.isUnknownOrUndef())
805    return 0;
806
807  const MemRegion *R = ArgVal.getAsRegion();
808
809  // Nonlocs can't be freed, of course.
810  // Non-region locations (labels and fixed addresses) also shouldn't be freed.
811  if (!R) {
812    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
813    return 0;
814  }
815
816  R = R->StripCasts();
817
818  // Blocks might show up as heap data, but should not be free()d
819  if (isa<BlockDataRegion>(R)) {
820    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
821    return 0;
822  }
823
824  const MemSpaceRegion *MS = R->getMemorySpace();
825
826  // Parameters, locals, statics, globals, and memory returned by alloca()
827  // shouldn't be freed.
828  if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
829    // FIXME: at the time this code was written, malloc() regions were
830    // represented by conjured symbols, which are all in UnknownSpaceRegion.
831    // This means that there isn't actually anything from HeapSpaceRegion
832    // that should be freed, even though we allow it here.
833    // Of course, free() can work on memory allocated outside the current
834    // function, so UnknownSpaceRegion is always a possibility.
835    // False negatives are better than false positives.
836
837    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
838    return 0;
839  }
840
841  const SymbolicRegion *SrBase = dyn_cast<SymbolicRegion>(R->getBaseRegion());
842  // Various cases could lead to non-symbol values here.
843  // For now, ignore them.
844  if (!SrBase)
845    return 0;
846
847  SymbolRef SymBase = SrBase->getSymbol();
848  const RefState *RsBase = State->get<RegionState>(SymBase);
849  SymbolRef PreviousRetStatusSymbol = 0;
850
851  // Check double free.
852  if (RsBase &&
853      (RsBase->isReleased() || RsBase->isRelinquished()) &&
854      !didPreviousFreeFail(State, SymBase, PreviousRetStatusSymbol)) {
855    ReportDoubleFree(C, ParentExpr->getSourceRange(), RsBase->isReleased(),
856                     SymBase, PreviousRetStatusSymbol);
857    return 0;
858  }
859
860  // Check if the memory location being freed is the actual location
861  // allocated, or an offset.
862  RegionOffset Offset = R->getAsOffset();
863  if (RsBase && RsBase->isAllocated() &&
864      Offset.isValid() &&
865      !Offset.hasSymbolicOffset() &&
866      Offset.getOffset() != 0) {
867    ReportOffsetFree(C, ArgVal, ArgExpr->getSourceRange());
868    return 0;
869  }
870
871  ReleasedAllocated = (RsBase != 0);
872
873  // Clean out the info on previous call to free return info.
874  State = State->remove<FreeReturnValue>(SymBase);
875
876  // Keep track of the return value. If it is NULL, we will know that free
877  // failed.
878  if (ReturnsNullOnFailure) {
879    SVal RetVal = C.getSVal(ParentExpr);
880    SymbolRef RetStatusSymbol = RetVal.getAsSymbol();
881    if (RetStatusSymbol) {
882      C.getSymbolManager().addSymbolDependency(SymBase, RetStatusSymbol);
883      State = State->set<FreeReturnValue>(SymBase, RetStatusSymbol);
884    }
885  }
886
887  // Normal free.
888  if (Hold) {
889    return State->set<RegionState>(SymBase,
890                                   RefState::getRelinquished(ParentExpr));
891  }
892  return State->set<RegionState>(SymBase, RefState::getReleased(ParentExpr));
893}
894
895bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
896  if (Optional<nonloc::ConcreteInt> IntVal = V.getAs<nonloc::ConcreteInt>())
897    os << "an integer (" << IntVal->getValue() << ")";
898  else if (Optional<loc::ConcreteInt> ConstAddr = V.getAs<loc::ConcreteInt>())
899    os << "a constant address (" << ConstAddr->getValue() << ")";
900  else if (Optional<loc::GotoLabel> Label = V.getAs<loc::GotoLabel>())
901    os << "the address of the label '" << Label->getLabel()->getName() << "'";
902  else
903    return false;
904
905  return true;
906}
907
908bool MallocChecker::SummarizeRegion(raw_ostream &os,
909                                    const MemRegion *MR) {
910  switch (MR->getKind()) {
911  case MemRegion::FunctionTextRegionKind: {
912    const NamedDecl *FD = cast<FunctionTextRegion>(MR)->getDecl();
913    if (FD)
914      os << "the address of the function '" << *FD << '\'';
915    else
916      os << "the address of a function";
917    return true;
918  }
919  case MemRegion::BlockTextRegionKind:
920    os << "block text";
921    return true;
922  case MemRegion::BlockDataRegionKind:
923    // FIXME: where the block came from?
924    os << "a block";
925    return true;
926  default: {
927    const MemSpaceRegion *MS = MR->getMemorySpace();
928
929    if (isa<StackLocalsSpaceRegion>(MS)) {
930      const VarRegion *VR = dyn_cast<VarRegion>(MR);
931      const VarDecl *VD;
932      if (VR)
933        VD = VR->getDecl();
934      else
935        VD = NULL;
936
937      if (VD)
938        os << "the address of the local variable '" << VD->getName() << "'";
939      else
940        os << "the address of a local stack variable";
941      return true;
942    }
943
944    if (isa<StackArgumentsSpaceRegion>(MS)) {
945      const VarRegion *VR = dyn_cast<VarRegion>(MR);
946      const VarDecl *VD;
947      if (VR)
948        VD = VR->getDecl();
949      else
950        VD = NULL;
951
952      if (VD)
953        os << "the address of the parameter '" << VD->getName() << "'";
954      else
955        os << "the address of a parameter";
956      return true;
957    }
958
959    if (isa<GlobalsSpaceRegion>(MS)) {
960      const VarRegion *VR = dyn_cast<VarRegion>(MR);
961      const VarDecl *VD;
962      if (VR)
963        VD = VR->getDecl();
964      else
965        VD = NULL;
966
967      if (VD) {
968        if (VD->isStaticLocal())
969          os << "the address of the static variable '" << VD->getName() << "'";
970        else
971          os << "the address of the global variable '" << VD->getName() << "'";
972      } else
973        os << "the address of a global variable";
974      return true;
975    }
976
977    return false;
978  }
979  }
980}
981
982void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
983                                  SourceRange Range) const {
984  if (ExplodedNode *N = C.generateSink()) {
985    if (!BT_BadFree)
986      BT_BadFree.reset(new BugType("Bad free", "Memory Error"));
987
988    SmallString<100> buf;
989    llvm::raw_svector_ostream os(buf);
990
991    const MemRegion *MR = ArgVal.getAsRegion();
992    if (MR) {
993      while (const ElementRegion *ER = dyn_cast<ElementRegion>(MR))
994        MR = ER->getSuperRegion();
995
996      // Special case for alloca()
997      if (isa<AllocaRegion>(MR))
998        os << "Argument to free() was allocated by alloca(), not malloc()";
999      else {
1000        os << "Argument to free() is ";
1001        if (SummarizeRegion(os, MR))
1002          os << ", which is not memory allocated by malloc()";
1003        else
1004          os << "not memory allocated by malloc()";
1005      }
1006    } else {
1007      os << "Argument to free() is ";
1008      if (SummarizeValue(os, ArgVal))
1009        os << ", which is not memory allocated by malloc()";
1010      else
1011        os << "not memory allocated by malloc()";
1012    }
1013
1014    BugReport *R = new BugReport(*BT_BadFree, os.str(), N);
1015    R->markInteresting(MR);
1016    R->addRange(Range);
1017    C.emitReport(R);
1018  }
1019}
1020
1021void MallocChecker::ReportOffsetFree(CheckerContext &C, SVal ArgVal,
1022                                     SourceRange Range) const {
1023  ExplodedNode *N = C.generateSink();
1024  if (N == NULL)
1025    return;
1026
1027  if (!BT_OffsetFree)
1028    BT_OffsetFree.reset(new BugType("Offset free", "Memory Error"));
1029
1030  SmallString<100> buf;
1031  llvm::raw_svector_ostream os(buf);
1032
1033  const MemRegion *MR = ArgVal.getAsRegion();
1034  assert(MR && "Only MemRegion based symbols can have offset free errors");
1035
1036  RegionOffset Offset = MR->getAsOffset();
1037  assert((Offset.isValid() &&
1038          !Offset.hasSymbolicOffset() &&
1039          Offset.getOffset() != 0) &&
1040         "Only symbols with a valid offset can have offset free errors");
1041
1042  int offsetBytes = Offset.getOffset() / C.getASTContext().getCharWidth();
1043
1044  os << "Argument to free() is offset by "
1045     << offsetBytes
1046     << " "
1047     << ((abs(offsetBytes) > 1) ? "bytes" : "byte")
1048     << " from the start of memory allocated by malloc()";
1049
1050  BugReport *R = new BugReport(*BT_OffsetFree, os.str(), N);
1051  R->markInteresting(MR->getBaseRegion());
1052  R->addRange(Range);
1053  C.emitReport(R);
1054}
1055
1056void MallocChecker::ReportUseAfterFree(CheckerContext &C, SourceRange Range,
1057                                       SymbolRef Sym) const {
1058
1059  if (ExplodedNode *N = C.generateSink()) {
1060    if (!BT_UseFree)
1061      BT_UseFree.reset(new BugType("Use-after-free", "Memory Error"));
1062
1063    BugReport *R = new BugReport(*BT_UseFree,
1064                                 "Use of memory after it is freed", N);
1065
1066    R->markInteresting(Sym);
1067    R->addRange(Range);
1068    R->addVisitor(new MallocBugVisitor(Sym));
1069    C.emitReport(R);
1070  }
1071}
1072
1073void MallocChecker::ReportDoubleFree(CheckerContext &C, SourceRange Range,
1074                                     bool Released, SymbolRef Sym,
1075                                     SymbolRef PrevSym) const {
1076
1077  if (ExplodedNode *N = C.generateSink()) {
1078    if (!BT_DoubleFree)
1079      BT_DoubleFree.reset(new BugType("Double free", "Memory Error"));
1080
1081    BugReport *R = new BugReport(*BT_DoubleFree,
1082      (Released ? "Attempt to free released memory"
1083                : "Attempt to free non-owned memory"),
1084      N);
1085    R->addRange(Range);
1086    R->markInteresting(Sym);
1087    if (PrevSym)
1088      R->markInteresting(PrevSym);
1089    R->addVisitor(new MallocBugVisitor(Sym));
1090    C.emitReport(R);
1091  }
1092}
1093
1094ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
1095                                          const CallExpr *CE,
1096                                          bool FreesOnFail) const {
1097  if (CE->getNumArgs() < 2)
1098    return 0;
1099
1100  ProgramStateRef state = C.getState();
1101  const Expr *arg0Expr = CE->getArg(0);
1102  const LocationContext *LCtx = C.getLocationContext();
1103  SVal Arg0Val = state->getSVal(arg0Expr, LCtx);
1104  if (!Arg0Val.getAs<DefinedOrUnknownSVal>())
1105    return 0;
1106  DefinedOrUnknownSVal arg0Val = Arg0Val.castAs<DefinedOrUnknownSVal>();
1107
1108  SValBuilder &svalBuilder = C.getSValBuilder();
1109
1110  DefinedOrUnknownSVal PtrEQ =
1111    svalBuilder.evalEQ(state, arg0Val, svalBuilder.makeNull());
1112
1113  // Get the size argument. If there is no size arg then give up.
1114  const Expr *Arg1 = CE->getArg(1);
1115  if (!Arg1)
1116    return 0;
1117
1118  // Get the value of the size argument.
1119  SVal Arg1ValG = state->getSVal(Arg1, LCtx);
1120  if (!Arg1ValG.getAs<DefinedOrUnknownSVal>())
1121    return 0;
1122  DefinedOrUnknownSVal Arg1Val = Arg1ValG.castAs<DefinedOrUnknownSVal>();
1123
1124  // Compare the size argument to 0.
1125  DefinedOrUnknownSVal SizeZero =
1126    svalBuilder.evalEQ(state, Arg1Val,
1127                       svalBuilder.makeIntValWithPtrWidth(0, false));
1128
1129  ProgramStateRef StatePtrIsNull, StatePtrNotNull;
1130  llvm::tie(StatePtrIsNull, StatePtrNotNull) = state->assume(PtrEQ);
1131  ProgramStateRef StateSizeIsZero, StateSizeNotZero;
1132  llvm::tie(StateSizeIsZero, StateSizeNotZero) = state->assume(SizeZero);
1133  // We only assume exceptional states if they are definitely true; if the
1134  // state is under-constrained, assume regular realloc behavior.
1135  bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull;
1136  bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero;
1137
1138  // If the ptr is NULL and the size is not 0, the call is equivalent to
1139  // malloc(size).
1140  if ( PrtIsNull && !SizeIsZero) {
1141    ProgramStateRef stateMalloc = MallocMemAux(C, CE, CE->getArg(1),
1142                                               UndefinedVal(), StatePtrIsNull);
1143    return stateMalloc;
1144  }
1145
1146  if (PrtIsNull && SizeIsZero)
1147    return 0;
1148
1149  // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size).
1150  assert(!PrtIsNull);
1151  SymbolRef FromPtr = arg0Val.getAsSymbol();
1152  SVal RetVal = state->getSVal(CE, LCtx);
1153  SymbolRef ToPtr = RetVal.getAsSymbol();
1154  if (!FromPtr || !ToPtr)
1155    return 0;
1156
1157  bool ReleasedAllocated = false;
1158
1159  // If the size is 0, free the memory.
1160  if (SizeIsZero)
1161    if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero, 0,
1162                                               false, ReleasedAllocated)){
1163      // The semantics of the return value are:
1164      // If size was equal to 0, either NULL or a pointer suitable to be passed
1165      // to free() is returned. We just free the input pointer and do not add
1166      // any constrains on the output pointer.
1167      return stateFree;
1168    }
1169
1170  // Default behavior.
1171  if (ProgramStateRef stateFree =
1172        FreeMemAux(C, CE, state, 0, false, ReleasedAllocated)) {
1173
1174    ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
1175                                                UnknownVal(), stateFree);
1176    if (!stateRealloc)
1177      return 0;
1178
1179    ReallocPairKind Kind = RPToBeFreedAfterFailure;
1180    if (FreesOnFail)
1181      Kind = RPIsFreeOnFailure;
1182    else if (!ReleasedAllocated)
1183      Kind = RPDoNotTrackAfterFailure;
1184
1185    // Record the info about the reallocated symbol so that we could properly
1186    // process failed reallocation.
1187    stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr,
1188                                                   ReallocPair(FromPtr, Kind));
1189    // The reallocated symbol should stay alive for as long as the new symbol.
1190    C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
1191    return stateRealloc;
1192  }
1193  return 0;
1194}
1195
1196ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE){
1197  if (CE->getNumArgs() < 2)
1198    return 0;
1199
1200  ProgramStateRef state = C.getState();
1201  SValBuilder &svalBuilder = C.getSValBuilder();
1202  const LocationContext *LCtx = C.getLocationContext();
1203  SVal count = state->getSVal(CE->getArg(0), LCtx);
1204  SVal elementSize = state->getSVal(CE->getArg(1), LCtx);
1205  SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, count, elementSize,
1206                                        svalBuilder.getContext().getSizeType());
1207  SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
1208
1209  return MallocMemAux(C, CE, TotalSize, zeroVal, state);
1210}
1211
1212LeakInfo
1213MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
1214                                 CheckerContext &C) const {
1215  const LocationContext *LeakContext = N->getLocationContext();
1216  // Walk the ExplodedGraph backwards and find the first node that referred to
1217  // the tracked symbol.
1218  const ExplodedNode *AllocNode = N;
1219  const MemRegion *ReferenceRegion = 0;
1220
1221  while (N) {
1222    ProgramStateRef State = N->getState();
1223    if (!State->get<RegionState>(Sym))
1224      break;
1225
1226    // Find the most recent expression bound to the symbol in the current
1227    // context.
1228    if (!ReferenceRegion) {
1229      if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) {
1230        SVal Val = State->getSVal(MR);
1231        if (Val.getAsLocSymbol() == Sym)
1232          ReferenceRegion = MR;
1233      }
1234    }
1235
1236    // Allocation node, is the last node in the current context in which the
1237    // symbol was tracked.
1238    if (N->getLocationContext() == LeakContext)
1239      AllocNode = N;
1240    N = N->pred_empty() ? NULL : *(N->pred_begin());
1241  }
1242
1243  return LeakInfo(AllocNode, ReferenceRegion);
1244}
1245
1246void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
1247                               CheckerContext &C) const {
1248  assert(N);
1249  if (!BT_Leak) {
1250    BT_Leak.reset(new BugType("Memory leak", "Memory Error"));
1251    // Leaks should not be reported if they are post-dominated by a sink:
1252    // (1) Sinks are higher importance bugs.
1253    // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
1254    //     with __noreturn functions such as assert() or exit(). We choose not
1255    //     to report leaks on such paths.
1256    BT_Leak->setSuppressOnSink(true);
1257  }
1258
1259  // Most bug reports are cached at the location where they occurred.
1260  // With leaks, we want to unique them by the location where they were
1261  // allocated, and only report a single path.
1262  PathDiagnosticLocation LocUsedForUniqueing;
1263  const ExplodedNode *AllocNode = 0;
1264  const MemRegion *Region = 0;
1265  llvm::tie(AllocNode, Region) = getAllocationSite(N, Sym, C);
1266
1267  ProgramPoint P = AllocNode->getLocation();
1268  const Stmt *AllocationStmt = 0;
1269  if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
1270    AllocationStmt = Exit->getCalleeContext()->getCallSite();
1271  else if (Optional<StmtPoint> SP = P.getAs<StmtPoint>())
1272    AllocationStmt = SP->getStmt();
1273  if (AllocationStmt)
1274    LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocationStmt,
1275                                              C.getSourceManager(),
1276                                              AllocNode->getLocationContext());
1277
1278  SmallString<200> buf;
1279  llvm::raw_svector_ostream os(buf);
1280  os << "Memory is never released; potential leak";
1281  if (Region && Region->canPrintPretty()) {
1282    os << " of memory pointed to by '";
1283    Region->printPretty(os);
1284    os << '\'';
1285  }
1286
1287  BugReport *R = new BugReport(*BT_Leak, os.str(), N,
1288                               LocUsedForUniqueing,
1289                               AllocNode->getLocationContext()->getDecl());
1290  R->markInteresting(Sym);
1291  R->addVisitor(new MallocBugVisitor(Sym, true));
1292  C.emitReport(R);
1293}
1294
1295void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
1296                                     CheckerContext &C) const
1297{
1298  if (!SymReaper.hasDeadSymbols())
1299    return;
1300
1301  ProgramStateRef state = C.getState();
1302  RegionStateTy RS = state->get<RegionState>();
1303  RegionStateTy::Factory &F = state->get_context<RegionState>();
1304
1305  SmallVector<SymbolRef, 2> Errors;
1306  for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
1307    if (SymReaper.isDead(I->first)) {
1308      if (I->second.isAllocated())
1309        Errors.push_back(I->first);
1310      // Remove the dead symbol from the map.
1311      RS = F.remove(RS, I->first);
1312
1313    }
1314  }
1315
1316  // Cleanup the Realloc Pairs Map.
1317  ReallocPairsTy RP = state->get<ReallocPairs>();
1318  for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
1319    if (SymReaper.isDead(I->first) ||
1320        SymReaper.isDead(I->second.ReallocatedSym)) {
1321      state = state->remove<ReallocPairs>(I->first);
1322    }
1323  }
1324
1325  // Cleanup the FreeReturnValue Map.
1326  FreeReturnValueTy FR = state->get<FreeReturnValue>();
1327  for (FreeReturnValueTy::iterator I = FR.begin(), E = FR.end(); I != E; ++I) {
1328    if (SymReaper.isDead(I->first) ||
1329        SymReaper.isDead(I->second)) {
1330      state = state->remove<FreeReturnValue>(I->first);
1331    }
1332  }
1333
1334  // Generate leak node.
1335  ExplodedNode *N = C.getPredecessor();
1336  if (!Errors.empty()) {
1337    static SimpleProgramPointTag Tag("MallocChecker : DeadSymbolsLeak");
1338    N = C.addTransition(C.getState(), C.getPredecessor(), &Tag);
1339    for (SmallVector<SymbolRef, 2>::iterator
1340        I = Errors.begin(), E = Errors.end(); I != E; ++I) {
1341      reportLeak(*I, N, C);
1342    }
1343  }
1344
1345  C.addTransition(state->set<RegionState>(RS), N);
1346}
1347
1348void MallocChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
1349  // We will check for double free in the post visit.
1350  if ((Filter.CMallocOptimistic || Filter.CMallocPessimistic) &&
1351      isFreeFunction(C.getCalleeDecl(CE), C.getASTContext()))
1352    return;
1353
1354  if (Filter.CNewDeleteChecker &&
1355      isStandardNewDelete(C.getCalleeDecl(CE), C.getASTContext()))
1356    return;
1357
1358  // Check use after free, when a freed pointer is passed to a call.
1359  ProgramStateRef State = C.getState();
1360  for (CallExpr::const_arg_iterator I = CE->arg_begin(),
1361                                    E = CE->arg_end(); I != E; ++I) {
1362    const Expr *A = *I;
1363    if (A->getType().getTypePtr()->isAnyPointerType()) {
1364      SymbolRef Sym = C.getSVal(A).getAsSymbol();
1365      if (!Sym)
1366        continue;
1367      if (checkUseAfterFree(Sym, C, A))
1368        return;
1369    }
1370  }
1371}
1372
1373void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
1374  const Expr *E = S->getRetValue();
1375  if (!E)
1376    return;
1377
1378  // Check if we are returning a symbol.
1379  ProgramStateRef State = C.getState();
1380  SVal RetVal = State->getSVal(E, C.getLocationContext());
1381  SymbolRef Sym = RetVal.getAsSymbol();
1382  if (!Sym)
1383    // If we are returning a field of the allocated struct or an array element,
1384    // the callee could still free the memory.
1385    // TODO: This logic should be a part of generic symbol escape callback.
1386    if (const MemRegion *MR = RetVal.getAsRegion())
1387      if (isa<FieldRegion>(MR) || isa<ElementRegion>(MR))
1388        if (const SymbolicRegion *BMR =
1389              dyn_cast<SymbolicRegion>(MR->getBaseRegion()))
1390          Sym = BMR->getSymbol();
1391
1392  // Check if we are returning freed memory.
1393  if (Sym)
1394    checkUseAfterFree(Sym, C, E);
1395}
1396
1397// TODO: Blocks should be either inlined or should call invalidate regions
1398// upon invocation. After that's in place, special casing here will not be
1399// needed.
1400void MallocChecker::checkPostStmt(const BlockExpr *BE,
1401                                  CheckerContext &C) const {
1402
1403  // Scan the BlockDecRefExprs for any object the retain count checker
1404  // may be tracking.
1405  if (!BE->getBlockDecl()->hasCaptures())
1406    return;
1407
1408  ProgramStateRef state = C.getState();
1409  const BlockDataRegion *R =
1410    cast<BlockDataRegion>(state->getSVal(BE,
1411                                         C.getLocationContext()).getAsRegion());
1412
1413  BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
1414                                            E = R->referenced_vars_end();
1415
1416  if (I == E)
1417    return;
1418
1419  SmallVector<const MemRegion*, 10> Regions;
1420  const LocationContext *LC = C.getLocationContext();
1421  MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager();
1422
1423  for ( ; I != E; ++I) {
1424    const VarRegion *VR = I.getCapturedRegion();
1425    if (VR->getSuperRegion() == R) {
1426      VR = MemMgr.getVarRegion(VR->getDecl(), LC);
1427    }
1428    Regions.push_back(VR);
1429  }
1430
1431  state =
1432    state->scanReachableSymbols<StopTrackingCallback>(Regions.data(),
1433                                    Regions.data() + Regions.size()).getState();
1434  C.addTransition(state);
1435}
1436
1437bool MallocChecker::isReleased(SymbolRef Sym, CheckerContext &C) const {
1438  assert(Sym);
1439  const RefState *RS = C.getState()->get<RegionState>(Sym);
1440  return (RS && RS->isReleased());
1441}
1442
1443bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
1444                                      const Stmt *S) const {
1445
1446  if (isReleased(Sym, C)) {
1447    ReportUseAfterFree(C, S->getSourceRange(), Sym);
1448    return true;
1449  }
1450
1451  return false;
1452}
1453
1454// Check if the location is a freed symbolic region.
1455void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
1456                                  CheckerContext &C) const {
1457  SymbolRef Sym = l.getLocSymbolInBase();
1458  if (Sym)
1459    checkUseAfterFree(Sym, C, S);
1460}
1461
1462// If a symbolic region is assumed to NULL (or another constant), stop tracking
1463// it - assuming that allocation failed on this path.
1464ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state,
1465                                              SVal Cond,
1466                                              bool Assumption) const {
1467  RegionStateTy RS = state->get<RegionState>();
1468  for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
1469    // If the symbol is assumed to be NULL, remove it from consideration.
1470    ConstraintManager &CMgr = state->getConstraintManager();
1471    ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
1472    if (AllocFailed.isConstrainedTrue())
1473      state = state->remove<RegionState>(I.getKey());
1474  }
1475
1476  // Realloc returns 0 when reallocation fails, which means that we should
1477  // restore the state of the pointer being reallocated.
1478  ReallocPairsTy RP = state->get<ReallocPairs>();
1479  for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
1480    // If the symbol is assumed to be NULL, remove it from consideration.
1481    ConstraintManager &CMgr = state->getConstraintManager();
1482    ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
1483    if (!AllocFailed.isConstrainedTrue())
1484      continue;
1485
1486    SymbolRef ReallocSym = I.getData().ReallocatedSym;
1487    if (const RefState *RS = state->get<RegionState>(ReallocSym)) {
1488      if (RS->isReleased()) {
1489        if (I.getData().Kind == RPToBeFreedAfterFailure)
1490          state = state->set<RegionState>(ReallocSym,
1491              RefState::getAllocated(RS->getStmt()));
1492        else if (I.getData().Kind == RPDoNotTrackAfterFailure)
1493          state = state->remove<RegionState>(ReallocSym);
1494        else
1495          assert(I.getData().Kind == RPIsFreeOnFailure);
1496      }
1497    }
1498    state = state->remove<ReallocPairs>(I.getKey());
1499  }
1500
1501  return state;
1502}
1503
1504bool MallocChecker::doesNotFreeMemOrInteresting(const CallEvent *Call,
1505                                                ProgramStateRef State) const {
1506  assert(Call);
1507
1508  // For now, assume that any C++ call can free memory.
1509  // TODO: If we want to be more optimistic here, we'll need to make sure that
1510  // regions escape to C++ containers. They seem to do that even now, but for
1511  // mysterious reasons.
1512  if (!(isa<FunctionCall>(Call) || isa<ObjCMethodCall>(Call)))
1513    return false;
1514
1515  // Check Objective-C messages by selector name.
1516  if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) {
1517    // If it's not a framework call, or if it takes a callback, assume it
1518    // can free memory.
1519    if (!Call->isInSystemHeader() || Call->hasNonZeroCallbackArg())
1520      return false;
1521
1522    // If it's a method we know about, handle it explicitly post-call.
1523    // This should happen before the "freeWhenDone" check below.
1524    if (isKnownDeallocObjCMethodName(*Msg))
1525      return true;
1526
1527    // If there's a "freeWhenDone" parameter, but the method isn't one we know
1528    // about, we can't be sure that the object will use free() to deallocate the
1529    // memory, so we can't model it explicitly. The best we can do is use it to
1530    // decide whether the pointer escapes.
1531    if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(*Msg))
1532      return !*FreeWhenDone;
1533
1534    // If the first selector piece ends with "NoCopy", and there is no
1535    // "freeWhenDone" parameter set to zero, we know ownership is being
1536    // transferred. Again, though, we can't be sure that the object will use
1537    // free() to deallocate the memory, so we can't model it explicitly.
1538    StringRef FirstSlot = Msg->getSelector().getNameForSlot(0);
1539    if (FirstSlot.endswith("NoCopy"))
1540      return false;
1541
1542    // If the first selector starts with addPointer, insertPointer,
1543    // or replacePointer, assume we are dealing with NSPointerArray or similar.
1544    // This is similar to C++ containers (vector); we still might want to check
1545    // that the pointers get freed by following the container itself.
1546    if (FirstSlot.startswith("addPointer") ||
1547        FirstSlot.startswith("insertPointer") ||
1548        FirstSlot.startswith("replacePointer")) {
1549      return false;
1550    }
1551
1552    // Otherwise, assume that the method does not free memory.
1553    // Most framework methods do not free memory.
1554    return true;
1555  }
1556
1557  // At this point the only thing left to handle is straight function calls.
1558  const FunctionDecl *FD = cast<FunctionCall>(Call)->getDecl();
1559  if (!FD)
1560    return false;
1561
1562  ASTContext &ASTC = State->getStateManager().getContext();
1563
1564  // If it's one of the allocation functions we can reason about, we model
1565  // its behavior explicitly.
1566  if (isMemFunction(FD, ASTC))
1567    return true;
1568
1569  // If it's not a system call, assume it frees memory.
1570  if (!Call->isInSystemHeader())
1571    return false;
1572
1573  // White list the system functions whose arguments escape.
1574  const IdentifierInfo *II = FD->getIdentifier();
1575  if (!II)
1576    return false;
1577  StringRef FName = II->getName();
1578
1579  // White list the 'XXXNoCopy' CoreFoundation functions.
1580  // We specifically check these before
1581  if (FName.endswith("NoCopy")) {
1582    // Look for the deallocator argument. We know that the memory ownership
1583    // is not transferred only if the deallocator argument is
1584    // 'kCFAllocatorNull'.
1585    for (unsigned i = 1; i < Call->getNumArgs(); ++i) {
1586      const Expr *ArgE = Call->getArgExpr(i)->IgnoreParenCasts();
1587      if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) {
1588        StringRef DeallocatorName = DE->getFoundDecl()->getName();
1589        if (DeallocatorName == "kCFAllocatorNull")
1590          return true;
1591      }
1592    }
1593    return false;
1594  }
1595
1596  // Associating streams with malloced buffers. The pointer can escape if
1597  // 'closefn' is specified (and if that function does free memory),
1598  // but it will not if closefn is not specified.
1599  // Currently, we do not inspect the 'closefn' function (PR12101).
1600  if (FName == "funopen")
1601    if (Call->getNumArgs() >= 4 && Call->getArgSVal(4).isConstant(0))
1602      return true;
1603
1604  // Do not warn on pointers passed to 'setbuf' when used with std streams,
1605  // these leaks might be intentional when setting the buffer for stdio.
1606  // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer
1607  if (FName == "setbuf" || FName =="setbuffer" ||
1608      FName == "setlinebuf" || FName == "setvbuf") {
1609    if (Call->getNumArgs() >= 1) {
1610      const Expr *ArgE = Call->getArgExpr(0)->IgnoreParenCasts();
1611      if (const DeclRefExpr *ArgDRE = dyn_cast<DeclRefExpr>(ArgE))
1612        if (const VarDecl *D = dyn_cast<VarDecl>(ArgDRE->getDecl()))
1613          if (D->getCanonicalDecl()->getName().find("std") != StringRef::npos)
1614            return false;
1615    }
1616  }
1617
1618  // A bunch of other functions which either take ownership of a pointer or
1619  // wrap the result up in a struct or object, meaning it can be freed later.
1620  // (See RetainCountChecker.) Not all the parameters here are invalidated,
1621  // but the Malloc checker cannot differentiate between them. The right way
1622  // of doing this would be to implement a pointer escapes callback.
1623  if (FName == "CGBitmapContextCreate" ||
1624      FName == "CGBitmapContextCreateWithData" ||
1625      FName == "CVPixelBufferCreateWithBytes" ||
1626      FName == "CVPixelBufferCreateWithPlanarBytes" ||
1627      FName == "OSAtomicEnqueue") {
1628    return false;
1629  }
1630
1631  // Handle cases where we know a buffer's /address/ can escape.
1632  // Note that the above checks handle some special cases where we know that
1633  // even though the address escapes, it's still our responsibility to free the
1634  // buffer.
1635  if (Call->argumentsMayEscape())
1636    return false;
1637
1638  // Otherwise, assume that the function does not free memory.
1639  // Most system calls do not free the memory.
1640  return true;
1641}
1642
1643ProgramStateRef MallocChecker::checkPointerEscape(ProgramStateRef State,
1644                                             const InvalidatedSymbols &Escaped,
1645                                             const CallEvent *Call,
1646                                             PointerEscapeKind Kind) const {
1647  // If we know that the call does not free memory, or we want to process the
1648  // call later, keep tracking the top level arguments.
1649  if ((Kind == PSK_DirectEscapeOnCall ||
1650       Kind == PSK_IndirectEscapeOnCall) &&
1651      doesNotFreeMemOrInteresting(Call, State)) {
1652    return State;
1653  }
1654
1655  for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
1656                                          E = Escaped.end();
1657                                          I != E; ++I) {
1658    SymbolRef sym = *I;
1659
1660    if (const RefState *RS = State->get<RegionState>(sym)) {
1661      if (RS->isAllocated())
1662        State = State->remove<RegionState>(sym);
1663    }
1664  }
1665  return State;
1666}
1667
1668static SymbolRef findFailedReallocSymbol(ProgramStateRef currState,
1669                                         ProgramStateRef prevState) {
1670  ReallocPairsTy currMap = currState->get<ReallocPairs>();
1671  ReallocPairsTy prevMap = prevState->get<ReallocPairs>();
1672
1673  for (ReallocPairsTy::iterator I = prevMap.begin(), E = prevMap.end();
1674       I != E; ++I) {
1675    SymbolRef sym = I.getKey();
1676    if (!currMap.lookup(sym))
1677      return sym;
1678  }
1679
1680  return NULL;
1681}
1682
1683PathDiagnosticPiece *
1684MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N,
1685                                           const ExplodedNode *PrevN,
1686                                           BugReporterContext &BRC,
1687                                           BugReport &BR) {
1688  ProgramStateRef state = N->getState();
1689  ProgramStateRef statePrev = PrevN->getState();
1690
1691  const RefState *RS = state->get<RegionState>(Sym);
1692  const RefState *RSPrev = statePrev->get<RegionState>(Sym);
1693  if (!RS)
1694    return 0;
1695
1696  const Stmt *S = 0;
1697  const char *Msg = 0;
1698  StackHintGeneratorForSymbol *StackHint = 0;
1699
1700  // Retrieve the associated statement.
1701  ProgramPoint ProgLoc = N->getLocation();
1702  if (Optional<StmtPoint> SP = ProgLoc.getAs<StmtPoint>()) {
1703    S = SP->getStmt();
1704  } else if (Optional<CallExitEnd> Exit = ProgLoc.getAs<CallExitEnd>()) {
1705    S = Exit->getCalleeContext()->getCallSite();
1706  } else if (Optional<BlockEdge> Edge = ProgLoc.getAs<BlockEdge>()) {
1707    // If an assumption was made on a branch, it should be caught
1708    // here by looking at the state transition.
1709    S = Edge->getSrc()->getTerminator();
1710  }
1711
1712  if (!S)
1713    return 0;
1714
1715  // FIXME: We will eventually need to handle non-statement-based events
1716  // (__attribute__((cleanup))).
1717
1718  // Find out if this is an interesting point and what is the kind.
1719  if (Mode == Normal) {
1720    if (isAllocated(RS, RSPrev, S)) {
1721      Msg = "Memory is allocated";
1722      StackHint = new StackHintGeneratorForSymbol(Sym,
1723                                                  "Returned allocated memory");
1724    } else if (isReleased(RS, RSPrev, S)) {
1725      Msg = "Memory is released";
1726      StackHint = new StackHintGeneratorForSymbol(Sym,
1727                                                  "Returned released memory");
1728    } else if (isRelinquished(RS, RSPrev, S)) {
1729      Msg = "Memory ownership is transfered";
1730      StackHint = new StackHintGeneratorForSymbol(Sym, "");
1731    } else if (isReallocFailedCheck(RS, RSPrev, S)) {
1732      Mode = ReallocationFailed;
1733      Msg = "Reallocation failed";
1734      StackHint = new StackHintGeneratorForReallocationFailed(Sym,
1735                                                       "Reallocation failed");
1736
1737      if (SymbolRef sym = findFailedReallocSymbol(state, statePrev)) {
1738        // Is it possible to fail two reallocs WITHOUT testing in between?
1739        assert((!FailedReallocSymbol || FailedReallocSymbol == sym) &&
1740          "We only support one failed realloc at a time.");
1741        BR.markInteresting(sym);
1742        FailedReallocSymbol = sym;
1743      }
1744    }
1745
1746  // We are in a special mode if a reallocation failed later in the path.
1747  } else if (Mode == ReallocationFailed) {
1748    assert(FailedReallocSymbol && "No symbol to look for.");
1749
1750    // Is this is the first appearance of the reallocated symbol?
1751    if (!statePrev->get<RegionState>(FailedReallocSymbol)) {
1752      // We're at the reallocation point.
1753      Msg = "Attempt to reallocate memory";
1754      StackHint = new StackHintGeneratorForSymbol(Sym,
1755                                                 "Returned reallocated memory");
1756      FailedReallocSymbol = NULL;
1757      Mode = Normal;
1758    }
1759  }
1760
1761  if (!Msg)
1762    return 0;
1763  assert(StackHint);
1764
1765  // Generate the extra diagnostic.
1766  PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
1767                             N->getLocationContext());
1768  return new PathDiagnosticEventPiece(Pos, Msg, true, StackHint);
1769}
1770
1771void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State,
1772                               const char *NL, const char *Sep) const {
1773
1774  RegionStateTy RS = State->get<RegionState>();
1775
1776  if (!RS.isEmpty()) {
1777    Out << Sep << "MallocChecker:" << NL;
1778    for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
1779      I.getKey()->dumpToStream(Out);
1780      Out << " : ";
1781      I.getData().dump(Out);
1782      Out << NL;
1783    }
1784  }
1785}
1786
1787#define REGISTER_CHECKER(name) \
1788void ento::register##name(CheckerManager &mgr) {\
1789  registerCStringCheckerBasic(mgr); \
1790  mgr.registerChecker<MallocChecker>()->Filter.C##name = true;\
1791}
1792
1793REGISTER_CHECKER(MallocPessimistic)
1794REGISTER_CHECKER(MallocOptimistic)
1795REGISTER_CHECKER(NewDeleteChecker)
1796