MallocChecker.cpp revision 3d7c44e01d568e5d5c0fac9c6ccb3f080157ba19
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/StaticAnalyzer/Core/Checker.h"
18#include "clang/StaticAnalyzer/Core/CheckerManager.h"
19#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
20#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
21#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
22#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
23#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
24#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
25#include "clang/Basic/SourceManager.h"
26#include "llvm/ADT/ImmutableMap.h"
27#include "llvm/ADT/SmallString.h"
28#include "llvm/ADT/STLExtras.h"
29#include <climits>
30
31using namespace clang;
32using namespace ento;
33
34namespace {
35
36class RefState {
37  enum Kind { AllocateUnchecked, AllocateFailed, Released, Escaped,
38              Relinquished } K;
39  const Stmt *S;
40
41public:
42  RefState(Kind k, const Stmt *s) : K(k), S(s) {}
43
44  bool isAllocated() const { return K == AllocateUnchecked; }
45  bool isReleased() const { return K == Released; }
46
47  const Stmt *getStmt() const { return S; }
48
49  bool operator==(const RefState &X) const {
50    return K == X.K && S == X.S;
51  }
52
53  static RefState getAllocateUnchecked(const Stmt *s) {
54    return RefState(AllocateUnchecked, s);
55  }
56  static RefState getAllocateFailed() {
57    return RefState(AllocateFailed, 0);
58  }
59  static RefState getReleased(const Stmt *s) { return RefState(Released, s); }
60  static RefState getEscaped(const Stmt *s) { return RefState(Escaped, s); }
61  static RefState getRelinquished(const Stmt *s) {
62    return RefState(Relinquished, s);
63  }
64
65  void Profile(llvm::FoldingSetNodeID &ID) const {
66    ID.AddInteger(K);
67    ID.AddPointer(S);
68  }
69};
70
71struct ReallocPair {
72  SymbolRef ReallocatedSym;
73  bool IsFreeOnFailure;
74  ReallocPair(SymbolRef S, bool F) : ReallocatedSym(S), IsFreeOnFailure(F) {}
75  void Profile(llvm::FoldingSetNodeID &ID) const {
76    ID.AddInteger(IsFreeOnFailure);
77    ID.AddPointer(ReallocatedSym);
78  }
79  bool operator==(const ReallocPair &X) const {
80    return ReallocatedSym == X.ReallocatedSym &&
81           IsFreeOnFailure == X.IsFreeOnFailure;
82  }
83};
84
85typedef std::pair<const Stmt*, const MemRegion*> LeakInfo;
86
87class MallocChecker : public Checker<check::DeadSymbols,
88                                     check::EndPath,
89                                     check::PreStmt<ReturnStmt>,
90                                     check::PreStmt<CallExpr>,
91                                     check::PostStmt<CallExpr>,
92                                     check::Location,
93                                     check::Bind,
94                                     eval::Assume,
95                                     check::RegionChanges>
96{
97  mutable OwningPtr<BugType> BT_DoubleFree;
98  mutable OwningPtr<BugType> BT_Leak;
99  mutable OwningPtr<BugType> BT_UseFree;
100  mutable OwningPtr<BugType> BT_BadFree;
101  mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc,
102                         *II_valloc, *II_reallocf, *II_strndup, *II_strdup;
103
104public:
105  MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0),
106                    II_valloc(0), II_reallocf(0), II_strndup(0), II_strdup(0) {}
107
108  /// In pessimistic mode, the checker assumes that it does not know which
109  /// functions might free the memory.
110  struct ChecksFilter {
111    DefaultBool CMallocPessimistic;
112    DefaultBool CMallocOptimistic;
113  };
114
115  ChecksFilter Filter;
116
117  void checkPreStmt(const CallExpr *S, CheckerContext &C) const;
118  void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
119  void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
120  void checkEndPath(CheckerContext &C) const;
121  void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
122  ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
123                            bool Assumption) const;
124  void checkLocation(SVal l, bool isLoad, const Stmt *S,
125                     CheckerContext &C) const;
126  void checkBind(SVal location, SVal val, const Stmt*S,
127                 CheckerContext &C) const;
128  ProgramStateRef
129  checkRegionChanges(ProgramStateRef state,
130                     const StoreManager::InvalidatedSymbols *invalidated,
131                     ArrayRef<const MemRegion *> ExplicitRegions,
132                     ArrayRef<const MemRegion *> Regions,
133                     const CallOrObjCMessage *Call) const;
134  bool wantsRegionChangeUpdate(ProgramStateRef state) const {
135    return true;
136  }
137
138private:
139  void initIdentifierInfo(ASTContext &C) const;
140
141  /// Check if this is one of the functions which can allocate/reallocate memory
142  /// pointed to by one of its arguments.
143  bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const;
144
145  static ProgramStateRef MallocMemReturnsAttr(CheckerContext &C,
146                                              const CallExpr *CE,
147                                              const OwnershipAttr* Att);
148  static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
149                                     const Expr *SizeEx, SVal Init,
150                                     ProgramStateRef state) {
151    return MallocMemAux(C, CE,
152                        state->getSVal(SizeEx, C.getLocationContext()),
153                        Init, state);
154  }
155
156  static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
157                                     SVal SizeEx, SVal Init,
158                                     ProgramStateRef state);
159
160  /// Update the RefState to reflect the new memory allocation.
161  static ProgramStateRef MallocUpdateRefState(CheckerContext &C,
162                                              const CallExpr *CE,
163                                              ProgramStateRef state);
164
165  ProgramStateRef FreeMemAttr(CheckerContext &C, const CallExpr *CE,
166                              const OwnershipAttr* Att) const;
167  ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE,
168                                 ProgramStateRef state, unsigned Num,
169                                 bool Hold) const;
170
171  ProgramStateRef ReallocMem(CheckerContext &C, const CallExpr *CE,
172                             bool FreesMemOnFailure) const;
173  static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE);
174
175  bool checkEscape(SymbolRef Sym, const Stmt *S, CheckerContext &C) const;
176  bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
177                         const Stmt *S = 0) const;
178
179  /// Check if the function is not known to us. So, for example, we could
180  /// conservatively assume it can free/reallocate it's pointer arguments.
181  bool doesNotFreeMemory(const CallOrObjCMessage *Call,
182                         ProgramStateRef State) const;
183
184  static bool SummarizeValue(raw_ostream &os, SVal V);
185  static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
186  void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange range) const;
187
188  /// Find the location of the allocation for Sym on the path leading to the
189  /// exploded node N.
190  LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
191                             CheckerContext &C) const;
192
193  void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const;
194
195  /// The bug visitor which allows us to print extra diagnostics along the
196  /// BugReport path. For example, showing the allocation site of the leaked
197  /// region.
198  class MallocBugVisitor : public BugReporterVisitor {
199  protected:
200    enum NotificationMode {
201      Normal,
202      Complete,
203      ReallocationFailed
204    };
205
206    // The allocated region symbol tracked by the main analysis.
207    SymbolRef Sym;
208    NotificationMode Mode;
209
210  public:
211    MallocBugVisitor(SymbolRef S) : Sym(S), Mode(Normal) {}
212    virtual ~MallocBugVisitor() {}
213
214    void Profile(llvm::FoldingSetNodeID &ID) const {
215      static int X = 0;
216      ID.AddPointer(&X);
217      ID.AddPointer(Sym);
218    }
219
220    inline bool isAllocated(const RefState *S, const RefState *SPrev,
221                            const Stmt *Stmt) {
222      // Did not track -> allocated. Other state (released) -> allocated.
223      return (Stmt && isa<CallExpr>(Stmt) &&
224              (S && S->isAllocated()) && (!SPrev || !SPrev->isAllocated()));
225    }
226
227    inline bool isReleased(const RefState *S, const RefState *SPrev,
228                           const Stmt *Stmt) {
229      // Did not track -> released. Other state (allocated) -> released.
230      return (Stmt && isa<CallExpr>(Stmt) &&
231              (S && S->isReleased()) && (!SPrev || !SPrev->isReleased()));
232    }
233
234    inline bool isReallocFailedCheck(const RefState *S, const RefState *SPrev,
235                                     const Stmt *Stmt) {
236      // If the expression is not a call, and the state change is
237      // released -> allocated, it must be the realloc return value
238      // check. If we have to handle more cases here, it might be cleaner just
239      // to track this extra bit in the state itself.
240      return ((!Stmt || !isa<CallExpr>(Stmt)) &&
241              (S && S->isAllocated()) && (SPrev && !SPrev->isAllocated()));
242    }
243
244    PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
245                                   const ExplodedNode *PrevN,
246                                   BugReporterContext &BRC,
247                                   BugReport &BR);
248  private:
249    class StackHintGeneratorForReallocationFailed
250        : public StackHintGeneratorForSymbol {
251    public:
252      StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M)
253        : StackHintGeneratorForSymbol(S, M) {}
254
255      virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex) {
256        SmallString<200> buf;
257        llvm::raw_svector_ostream os(buf);
258
259        os << "Reallocation of ";
260        // Printed parameters start at 1, not 0.
261        printOrdinal(++ArgIndex, os);
262        os << " parameter failed";
263
264        return os.str();
265      }
266
267      virtual std::string getMessageForReturn(const CallExpr *CallExpr) {
268        return "Reallocation of returned value failed";
269      }
270    };
271  };
272};
273} // end anonymous namespace
274
275typedef llvm::ImmutableMap<SymbolRef, RefState> RegionStateTy;
276typedef llvm::ImmutableMap<SymbolRef, ReallocPair > ReallocMap;
277class RegionState {};
278class ReallocPairs {};
279namespace clang {
280namespace ento {
281  template <>
282  struct ProgramStateTrait<RegionState>
283    : public ProgramStatePartialTrait<RegionStateTy> {
284    static void *GDMIndex() { static int x; return &x; }
285  };
286
287  template <>
288  struct ProgramStateTrait<ReallocPairs>
289    : public ProgramStatePartialTrait<ReallocMap> {
290    static void *GDMIndex() { static int x; return &x; }
291  };
292}
293}
294
295namespace {
296class StopTrackingCallback : public SymbolVisitor {
297  ProgramStateRef state;
298public:
299  StopTrackingCallback(ProgramStateRef st) : state(st) {}
300  ProgramStateRef getState() const { return state; }
301
302  bool VisitSymbol(SymbolRef sym) {
303    state = state->remove<RegionState>(sym);
304    return true;
305  }
306};
307} // end anonymous namespace
308
309void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const {
310  if (!II_malloc)
311    II_malloc = &Ctx.Idents.get("malloc");
312  if (!II_free)
313    II_free = &Ctx.Idents.get("free");
314  if (!II_realloc)
315    II_realloc = &Ctx.Idents.get("realloc");
316  if (!II_reallocf)
317    II_reallocf = &Ctx.Idents.get("reallocf");
318  if (!II_calloc)
319    II_calloc = &Ctx.Idents.get("calloc");
320  if (!II_valloc)
321    II_valloc = &Ctx.Idents.get("valloc");
322  if (!II_strdup)
323    II_strdup = &Ctx.Idents.get("strdup");
324  if (!II_strndup)
325    II_strndup = &Ctx.Idents.get("strndup");
326}
327
328bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const {
329  if (!FD)
330    return false;
331  IdentifierInfo *FunI = FD->getIdentifier();
332  if (!FunI)
333    return false;
334
335  initIdentifierInfo(C);
336
337  if (FunI == II_malloc || FunI == II_free || FunI == II_realloc ||
338      FunI == II_reallocf || FunI == II_calloc || FunI == II_valloc ||
339      FunI == II_strdup || FunI == II_strndup)
340    return true;
341
342  if (Filter.CMallocOptimistic && FD->hasAttrs() &&
343      FD->specific_attr_begin<OwnershipAttr>() !=
344          FD->specific_attr_end<OwnershipAttr>())
345    return true;
346
347
348  return false;
349}
350
351void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
352  const FunctionDecl *FD = C.getCalleeDecl(CE);
353  if (!FD)
354    return;
355
356  initIdentifierInfo(C.getASTContext());
357  IdentifierInfo *FunI = FD->getIdentifier();
358  if (!FunI)
359    return;
360
361  ProgramStateRef State = C.getState();
362  if (FunI == II_malloc || FunI == II_valloc) {
363    State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
364  } else if (FunI == II_realloc) {
365    State = ReallocMem(C, CE, false);
366  } else if (FunI == II_reallocf) {
367    State = ReallocMem(C, CE, true);
368  } else if (FunI == II_calloc) {
369    State = CallocMem(C, CE);
370  } else if (FunI == II_free) {
371    State = FreeMemAux(C, CE, C.getState(), 0, false);
372  } else if (FunI == II_strdup) {
373    State = MallocUpdateRefState(C, CE, State);
374  } else if (FunI == II_strndup) {
375    State = MallocUpdateRefState(C, CE, State);
376  } else if (Filter.CMallocOptimistic) {
377    // Check all the attributes, if there are any.
378    // There can be multiple of these attributes.
379    if (FD->hasAttrs())
380      for (specific_attr_iterator<OwnershipAttr>
381          i = FD->specific_attr_begin<OwnershipAttr>(),
382          e = FD->specific_attr_end<OwnershipAttr>();
383          i != e; ++i) {
384        switch ((*i)->getOwnKind()) {
385        case OwnershipAttr::Returns:
386          State = MallocMemReturnsAttr(C, CE, *i);
387          break;
388        case OwnershipAttr::Takes:
389        case OwnershipAttr::Holds:
390          State = FreeMemAttr(C, CE, *i);
391          break;
392        }
393      }
394  }
395  C.addTransition(State);
396}
397
398ProgramStateRef MallocChecker::MallocMemReturnsAttr(CheckerContext &C,
399                                                    const CallExpr *CE,
400                                                    const OwnershipAttr* Att) {
401  if (Att->getModule() != "malloc")
402    return 0;
403
404  OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
405  if (I != E) {
406    return MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState());
407  }
408  return MallocMemAux(C, CE, UnknownVal(), UndefinedVal(), C.getState());
409}
410
411ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
412                                           const CallExpr *CE,
413                                           SVal Size, SVal Init,
414                                           ProgramStateRef state) {
415  // Get the return value.
416  SVal retVal = state->getSVal(CE, C.getLocationContext());
417
418  // We expect the malloc functions to return a pointer.
419  if (!isa<Loc>(retVal))
420    return 0;
421
422  // Fill the region with the initialization value.
423  state = state->bindDefault(retVal, Init);
424
425  // Set the region's extent equal to the Size parameter.
426  const SymbolicRegion *R =
427      dyn_cast_or_null<SymbolicRegion>(retVal.getAsRegion());
428  if (!R)
429    return 0;
430  if (isa<DefinedOrUnknownSVal>(Size)) {
431    SValBuilder &svalBuilder = C.getSValBuilder();
432    DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
433    DefinedOrUnknownSVal DefinedSize = cast<DefinedOrUnknownSVal>(Size);
434    DefinedOrUnknownSVal extentMatchesSize =
435        svalBuilder.evalEQ(state, Extent, DefinedSize);
436
437    state = state->assume(extentMatchesSize, true);
438    assert(state);
439  }
440
441  return MallocUpdateRefState(C, CE, state);
442}
443
444ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C,
445                                                    const CallExpr *CE,
446                                                    ProgramStateRef state) {
447  // Get the return value.
448  SVal retVal = state->getSVal(CE, C.getLocationContext());
449
450  // We expect the malloc functions to return a pointer.
451  if (!isa<Loc>(retVal))
452    return 0;
453
454  SymbolRef Sym = retVal.getAsLocSymbol();
455  assert(Sym);
456
457  // Set the symbol's state to Allocated.
458  return state->set<RegionState>(Sym, RefState::getAllocateUnchecked(CE));
459
460}
461
462ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C,
463                                           const CallExpr *CE,
464                                           const OwnershipAttr* Att) const {
465  if (Att->getModule() != "malloc")
466    return 0;
467
468  ProgramStateRef State = C.getState();
469
470  for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
471       I != E; ++I) {
472    ProgramStateRef StateI = FreeMemAux(C, CE, State, *I,
473                               Att->getOwnKind() == OwnershipAttr::Holds);
474    if (StateI)
475      State = StateI;
476  }
477  return State;
478}
479
480ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
481                                          const CallExpr *CE,
482                                          ProgramStateRef state,
483                                          unsigned Num,
484                                          bool Hold) const {
485  const Expr *ArgExpr = CE->getArg(Num);
486  SVal ArgVal = state->getSVal(ArgExpr, C.getLocationContext());
487  if (!isa<DefinedOrUnknownSVal>(ArgVal))
488    return 0;
489  DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(ArgVal);
490
491  // Check for null dereferences.
492  if (!isa<Loc>(location))
493    return 0;
494
495  // The explicit NULL case, no operation is performed.
496  ProgramStateRef notNullState, nullState;
497  llvm::tie(notNullState, nullState) = state->assume(location);
498  if (nullState && !notNullState)
499    return 0;
500
501  // Unknown values could easily be okay
502  // Undefined values are handled elsewhere
503  if (ArgVal.isUnknownOrUndef())
504    return 0;
505
506  const MemRegion *R = ArgVal.getAsRegion();
507
508  // Nonlocs can't be freed, of course.
509  // Non-region locations (labels and fixed addresses) also shouldn't be freed.
510  if (!R) {
511    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
512    return 0;
513  }
514
515  R = R->StripCasts();
516
517  // Blocks might show up as heap data, but should not be free()d
518  if (isa<BlockDataRegion>(R)) {
519    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
520    return 0;
521  }
522
523  const MemSpaceRegion *MS = R->getMemorySpace();
524
525  // Parameters, locals, statics, and globals shouldn't be freed.
526  if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
527    // FIXME: at the time this code was written, malloc() regions were
528    // represented by conjured symbols, which are all in UnknownSpaceRegion.
529    // This means that there isn't actually anything from HeapSpaceRegion
530    // that should be freed, even though we allow it here.
531    // Of course, free() can work on memory allocated outside the current
532    // function, so UnknownSpaceRegion is always a possibility.
533    // False negatives are better than false positives.
534
535    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
536    return 0;
537  }
538
539  const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R);
540  // Various cases could lead to non-symbol values here.
541  // For now, ignore them.
542  if (!SR)
543    return 0;
544
545  SymbolRef Sym = SR->getSymbol();
546  const RefState *RS = state->get<RegionState>(Sym);
547
548  // If the symbol has not been tracked, return. This is possible when free() is
549  // called on a pointer that does not get its pointee directly from malloc().
550  // Full support of this requires inter-procedural analysis.
551  if (!RS)
552    return 0;
553
554  // Check double free.
555  if (RS->isReleased()) {
556    if (ExplodedNode *N = C.generateSink()) {
557      if (!BT_DoubleFree)
558        BT_DoubleFree.reset(
559          new BugType("Double free", "Memory Error"));
560      BugReport *R = new BugReport(*BT_DoubleFree,
561                        "Attempt to free released memory", N);
562      R->addRange(ArgExpr->getSourceRange());
563      R->markInteresting(Sym);
564      R->addVisitor(new MallocBugVisitor(Sym));
565      C.EmitReport(R);
566    }
567    return 0;
568  }
569
570  // Normal free.
571  if (Hold)
572    return state->set<RegionState>(Sym, RefState::getRelinquished(CE));
573  return state->set<RegionState>(Sym, RefState::getReleased(CE));
574}
575
576bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
577  if (nonloc::ConcreteInt *IntVal = dyn_cast<nonloc::ConcreteInt>(&V))
578    os << "an integer (" << IntVal->getValue() << ")";
579  else if (loc::ConcreteInt *ConstAddr = dyn_cast<loc::ConcreteInt>(&V))
580    os << "a constant address (" << ConstAddr->getValue() << ")";
581  else if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&V))
582    os << "the address of the label '" << Label->getLabel()->getName() << "'";
583  else
584    return false;
585
586  return true;
587}
588
589bool MallocChecker::SummarizeRegion(raw_ostream &os,
590                                    const MemRegion *MR) {
591  switch (MR->getKind()) {
592  case MemRegion::FunctionTextRegionKind: {
593    const FunctionDecl *FD = cast<FunctionTextRegion>(MR)->getDecl();
594    if (FD)
595      os << "the address of the function '" << *FD << '\'';
596    else
597      os << "the address of a function";
598    return true;
599  }
600  case MemRegion::BlockTextRegionKind:
601    os << "block text";
602    return true;
603  case MemRegion::BlockDataRegionKind:
604    // FIXME: where the block came from?
605    os << "a block";
606    return true;
607  default: {
608    const MemSpaceRegion *MS = MR->getMemorySpace();
609
610    if (isa<StackLocalsSpaceRegion>(MS)) {
611      const VarRegion *VR = dyn_cast<VarRegion>(MR);
612      const VarDecl *VD;
613      if (VR)
614        VD = VR->getDecl();
615      else
616        VD = NULL;
617
618      if (VD)
619        os << "the address of the local variable '" << VD->getName() << "'";
620      else
621        os << "the address of a local stack variable";
622      return true;
623    }
624
625    if (isa<StackArgumentsSpaceRegion>(MS)) {
626      const VarRegion *VR = dyn_cast<VarRegion>(MR);
627      const VarDecl *VD;
628      if (VR)
629        VD = VR->getDecl();
630      else
631        VD = NULL;
632
633      if (VD)
634        os << "the address of the parameter '" << VD->getName() << "'";
635      else
636        os << "the address of a parameter";
637      return true;
638    }
639
640    if (isa<GlobalsSpaceRegion>(MS)) {
641      const VarRegion *VR = dyn_cast<VarRegion>(MR);
642      const VarDecl *VD;
643      if (VR)
644        VD = VR->getDecl();
645      else
646        VD = NULL;
647
648      if (VD) {
649        if (VD->isStaticLocal())
650          os << "the address of the static variable '" << VD->getName() << "'";
651        else
652          os << "the address of the global variable '" << VD->getName() << "'";
653      } else
654        os << "the address of a global variable";
655      return true;
656    }
657
658    return false;
659  }
660  }
661}
662
663void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
664                                  SourceRange range) const {
665  if (ExplodedNode *N = C.generateSink()) {
666    if (!BT_BadFree)
667      BT_BadFree.reset(new BugType("Bad free", "Memory Error"));
668
669    SmallString<100> buf;
670    llvm::raw_svector_ostream os(buf);
671
672    const MemRegion *MR = ArgVal.getAsRegion();
673    if (MR) {
674      while (const ElementRegion *ER = dyn_cast<ElementRegion>(MR))
675        MR = ER->getSuperRegion();
676
677      // Special case for alloca()
678      if (isa<AllocaRegion>(MR))
679        os << "Argument to free() was allocated by alloca(), not malloc()";
680      else {
681        os << "Argument to free() is ";
682        if (SummarizeRegion(os, MR))
683          os << ", which is not memory allocated by malloc()";
684        else
685          os << "not memory allocated by malloc()";
686      }
687    } else {
688      os << "Argument to free() is ";
689      if (SummarizeValue(os, ArgVal))
690        os << ", which is not memory allocated by malloc()";
691      else
692        os << "not memory allocated by malloc()";
693    }
694
695    BugReport *R = new BugReport(*BT_BadFree, os.str(), N);
696    R->markInteresting(MR);
697    R->addRange(range);
698    C.EmitReport(R);
699  }
700}
701
702ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
703                                          const CallExpr *CE,
704                                          bool FreesOnFail) const {
705  ProgramStateRef state = C.getState();
706  const Expr *arg0Expr = CE->getArg(0);
707  const LocationContext *LCtx = C.getLocationContext();
708  SVal Arg0Val = state->getSVal(arg0Expr, LCtx);
709  if (!isa<DefinedOrUnknownSVal>(Arg0Val))
710    return 0;
711  DefinedOrUnknownSVal arg0Val = cast<DefinedOrUnknownSVal>(Arg0Val);
712
713  SValBuilder &svalBuilder = C.getSValBuilder();
714
715  DefinedOrUnknownSVal PtrEQ =
716    svalBuilder.evalEQ(state, arg0Val, svalBuilder.makeNull());
717
718  // Get the size argument. If there is no size arg then give up.
719  const Expr *Arg1 = CE->getArg(1);
720  if (!Arg1)
721    return 0;
722
723  // Get the value of the size argument.
724  SVal Arg1ValG = state->getSVal(Arg1, LCtx);
725  if (!isa<DefinedOrUnknownSVal>(Arg1ValG))
726    return 0;
727  DefinedOrUnknownSVal Arg1Val = cast<DefinedOrUnknownSVal>(Arg1ValG);
728
729  // Compare the size argument to 0.
730  DefinedOrUnknownSVal SizeZero =
731    svalBuilder.evalEQ(state, Arg1Val,
732                       svalBuilder.makeIntValWithPtrWidth(0, false));
733
734  ProgramStateRef StatePtrIsNull, StatePtrNotNull;
735  llvm::tie(StatePtrIsNull, StatePtrNotNull) = state->assume(PtrEQ);
736  ProgramStateRef StateSizeIsZero, StateSizeNotZero;
737  llvm::tie(StateSizeIsZero, StateSizeNotZero) = state->assume(SizeZero);
738  // We only assume exceptional states if they are definitely true; if the
739  // state is under-constrained, assume regular realloc behavior.
740  bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull;
741  bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero;
742
743  // If the ptr is NULL and the size is not 0, the call is equivalent to
744  // malloc(size).
745  if ( PrtIsNull && !SizeIsZero) {
746    ProgramStateRef stateMalloc = MallocMemAux(C, CE, CE->getArg(1),
747                                               UndefinedVal(), StatePtrIsNull);
748    return stateMalloc;
749  }
750
751  if (PrtIsNull && SizeIsZero)
752    return 0;
753
754  // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size).
755  assert(!PrtIsNull);
756  SymbolRef FromPtr = arg0Val.getAsSymbol();
757  SVal RetVal = state->getSVal(CE, LCtx);
758  SymbolRef ToPtr = RetVal.getAsSymbol();
759  if (!FromPtr || !ToPtr)
760    return 0;
761
762  // If the size is 0, free the memory.
763  if (SizeIsZero)
764    if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero,0,false)){
765      // The semantics of the return value are:
766      // If size was equal to 0, either NULL or a pointer suitable to be passed
767      // to free() is returned.
768      stateFree = stateFree->set<ReallocPairs>(ToPtr,
769                                            ReallocPair(FromPtr, FreesOnFail));
770      C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
771      return stateFree;
772    }
773
774  // Default behavior.
775  if (ProgramStateRef stateFree = FreeMemAux(C, CE, state, 0, false)) {
776    // FIXME: We should copy the content of the original buffer.
777    ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
778                                                UnknownVal(), stateFree);
779    if (!stateRealloc)
780      return 0;
781    stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr,
782                                            ReallocPair(FromPtr, FreesOnFail));
783    C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
784    return stateRealloc;
785  }
786  return 0;
787}
788
789ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE){
790  ProgramStateRef state = C.getState();
791  SValBuilder &svalBuilder = C.getSValBuilder();
792  const LocationContext *LCtx = C.getLocationContext();
793  SVal count = state->getSVal(CE->getArg(0), LCtx);
794  SVal elementSize = state->getSVal(CE->getArg(1), LCtx);
795  SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, count, elementSize,
796                                        svalBuilder.getContext().getSizeType());
797  SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
798
799  return MallocMemAux(C, CE, TotalSize, zeroVal, state);
800}
801
802LeakInfo
803MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
804                                 CheckerContext &C) const {
805  const LocationContext *LeakContext = N->getLocationContext();
806  // Walk the ExplodedGraph backwards and find the first node that referred to
807  // the tracked symbol.
808  const ExplodedNode *AllocNode = N;
809  const MemRegion *ReferenceRegion = 0;
810
811  while (N) {
812    ProgramStateRef State = N->getState();
813    if (!State->get<RegionState>(Sym))
814      break;
815
816    // Find the most recent expression bound to the symbol in the current
817    // context.
818    ProgramPoint L = N->getLocation();
819    if (!ReferenceRegion) {
820      const MemRegion *MR = C.getLocationRegionIfPostStore(N);
821      if (MR) {
822          SVal Val = State->getSVal(MR);
823          if (Val.getAsLocSymbol() == Sym)
824            ReferenceRegion = MR;
825        }
826    }
827
828    // Allocation node, is the last node in the current context in which the
829    // symbol was tracked.
830    if (N->getLocationContext() == LeakContext)
831      AllocNode = N;
832    N = N->pred_empty() ? NULL : *(N->pred_begin());
833  }
834
835  ProgramPoint P = AllocNode->getLocation();
836  const Stmt *AllocationStmt = 0;
837  if (isa<StmtPoint>(P))
838    AllocationStmt = cast<StmtPoint>(P).getStmt();
839
840  return LeakInfo(AllocationStmt, ReferenceRegion);
841}
842
843void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
844                               CheckerContext &C) const {
845  assert(N);
846  if (!BT_Leak) {
847    BT_Leak.reset(new BugType("Memory leak", "Memory Error"));
848    // Leaks should not be reported if they are post-dominated by a sink:
849    // (1) Sinks are higher importance bugs.
850    // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
851    //     with __noreturn functions such as assert() or exit(). We choose not
852    //     to report leaks on such paths.
853    BT_Leak->setSuppressOnSink(true);
854  }
855
856  // Most bug reports are cached at the location where they occurred.
857  // With leaks, we want to unique them by the location where they were
858  // allocated, and only report a single path.
859  PathDiagnosticLocation LocUsedForUniqueing;
860  const Stmt *AllocStmt = 0;
861  const MemRegion *Region = 0;
862  llvm::tie(AllocStmt, Region) = getAllocationSite(N, Sym, C);
863  if (AllocStmt)
864    LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocStmt,
865                            C.getSourceManager(), N->getLocationContext());
866
867  SmallString<200> buf;
868  llvm::raw_svector_ostream os(buf);
869  os << "Memory is never released; potential leak";
870  if (Region) {
871    os << " of memory pointed to by '";
872    Region->dumpPretty(os);
873    os <<'\'';
874  }
875
876  BugReport *R = new BugReport(*BT_Leak, os.str(), N, LocUsedForUniqueing);
877  R->markInteresting(Sym);
878  // FIXME: This is a hack to make sure the MallocBugVisitor gets to look at
879  // the ExplodedNode chain first, in order to mark any failed realloc symbols
880  // as interesting for ConditionBRVisitor.
881  R->addVisitor(new ConditionBRVisitor());
882  R->addVisitor(new MallocBugVisitor(Sym));
883  C.EmitReport(R);
884}
885
886void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
887                                     CheckerContext &C) const
888{
889  if (!SymReaper.hasDeadSymbols())
890    return;
891
892  ProgramStateRef state = C.getState();
893  RegionStateTy RS = state->get<RegionState>();
894  RegionStateTy::Factory &F = state->get_context<RegionState>();
895
896  bool generateReport = false;
897  llvm::SmallVector<SymbolRef, 2> Errors;
898  for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
899    if (SymReaper.isDead(I->first)) {
900      if (I->second.isAllocated()) {
901        generateReport = true;
902        Errors.push_back(I->first);
903      }
904      // Remove the dead symbol from the map.
905      RS = F.remove(RS, I->first);
906
907    }
908  }
909
910  // Cleanup the Realloc Pairs Map.
911  ReallocMap RP = state->get<ReallocPairs>();
912  for (ReallocMap::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
913    if (SymReaper.isDead(I->first) ||
914        SymReaper.isDead(I->second.ReallocatedSym)) {
915      state = state->remove<ReallocPairs>(I->first);
916    }
917  }
918
919  // Generate leak node.
920  static SimpleProgramPointTag Tag("MallocChecker : DeadSymbolsLeak");
921  ExplodedNode *N = C.addTransition(C.getState(), C.getPredecessor(), &Tag);
922
923  if (generateReport) {
924    for (llvm::SmallVector<SymbolRef, 2>::iterator
925         I = Errors.begin(), E = Errors.end(); I != E; ++I) {
926      reportLeak(*I, N, C);
927    }
928  }
929  C.addTransition(state->set<RegionState>(RS), N);
930}
931
932void MallocChecker::checkEndPath(CheckerContext &C) const {
933  ProgramStateRef state = C.getState();
934  RegionStateTy M = state->get<RegionState>();
935
936  // If inside inlined call, skip it.
937  if (C.getLocationContext()->getParent() != 0)
938    return;
939
940  for (RegionStateTy::iterator I = M.begin(), E = M.end(); I != E; ++I) {
941    RefState RS = I->second;
942    if (RS.isAllocated()) {
943      ExplodedNode *N = C.addTransition(state);
944      if (N)
945        reportLeak(I->first, N, C);
946    }
947  }
948}
949
950bool MallocChecker::checkEscape(SymbolRef Sym, const Stmt *S,
951                                CheckerContext &C) const {
952  ProgramStateRef state = C.getState();
953  const RefState *RS = state->get<RegionState>(Sym);
954  if (!RS)
955    return false;
956
957  if (RS->isAllocated()) {
958    state = state->set<RegionState>(Sym, RefState::getEscaped(S));
959    C.addTransition(state);
960    return true;
961  }
962  return false;
963}
964
965void MallocChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
966  if (isMemFunction(C.getCalleeDecl(CE), C.getASTContext()))
967    return;
968
969  // Check use after free, when a freed pointer is passed to a call.
970  ProgramStateRef State = C.getState();
971  for (CallExpr::const_arg_iterator I = CE->arg_begin(),
972                                    E = CE->arg_end(); I != E; ++I) {
973    const Expr *A = *I;
974    if (A->getType().getTypePtr()->isAnyPointerType()) {
975      SymbolRef Sym = State->getSVal(A, C.getLocationContext()).getAsSymbol();
976      if (!Sym)
977        continue;
978      if (checkUseAfterFree(Sym, C, A))
979        return;
980    }
981  }
982}
983
984void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
985  const Expr *E = S->getRetValue();
986  if (!E)
987    return;
988
989  // Check if we are returning a symbol.
990  SVal RetVal = C.getState()->getSVal(E, C.getLocationContext());
991  SymbolRef Sym = RetVal.getAsSymbol();
992  if (!Sym)
993    // If we are returning a field of the allocated struct or an array element,
994    // the callee could still free the memory.
995    // TODO: This logic should be a part of generic symbol escape callback.
996    if (const MemRegion *MR = RetVal.getAsRegion())
997      if (isa<FieldRegion>(MR) || isa<ElementRegion>(MR))
998        if (const SymbolicRegion *BMR =
999              dyn_cast<SymbolicRegion>(MR->getBaseRegion()))
1000          Sym = BMR->getSymbol();
1001  if (!Sym)
1002    return;
1003
1004  // Check if we are returning freed memory.
1005  if (checkUseAfterFree(Sym, C, E))
1006    return;
1007
1008  // If this function body is not inlined, check if the symbol is escaping.
1009  if (C.getLocationContext()->getParent() == 0)
1010    checkEscape(Sym, E, C);
1011}
1012
1013bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
1014                                      const Stmt *S) const {
1015  assert(Sym);
1016  const RefState *RS = C.getState()->get<RegionState>(Sym);
1017  if (RS && RS->isReleased()) {
1018    if (ExplodedNode *N = C.generateSink()) {
1019      if (!BT_UseFree)
1020        BT_UseFree.reset(new BugType("Use-after-free", "Memory Error"));
1021
1022      BugReport *R = new BugReport(*BT_UseFree,
1023                                   "Use of memory after it is freed",N);
1024      if (S)
1025        R->addRange(S->getSourceRange());
1026      R->markInteresting(Sym);
1027      R->addVisitor(new MallocBugVisitor(Sym));
1028      C.EmitReport(R);
1029      return true;
1030    }
1031  }
1032  return false;
1033}
1034
1035// Check if the location is a freed symbolic region.
1036void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
1037                                  CheckerContext &C) const {
1038  SymbolRef Sym = l.getLocSymbolInBase();
1039  if (Sym)
1040    checkUseAfterFree(Sym, C);
1041}
1042
1043//===----------------------------------------------------------------------===//
1044// Check various ways a symbol can be invalidated.
1045// TODO: This logic (the next 3 functions) is copied/similar to the
1046// RetainRelease checker. We might want to factor this out.
1047//===----------------------------------------------------------------------===//
1048
1049// Stop tracking symbols when a value escapes as a result of checkBind.
1050// A value escapes in three possible cases:
1051// (1) we are binding to something that is not a memory region.
1052// (2) we are binding to a memregion that does not have stack storage
1053// (3) we are binding to a memregion with stack storage that the store
1054//     does not understand.
1055void MallocChecker::checkBind(SVal loc, SVal val, const Stmt *S,
1056                              CheckerContext &C) const {
1057  // Are we storing to something that causes the value to "escape"?
1058  bool escapes = true;
1059  ProgramStateRef state = C.getState();
1060
1061  if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&loc)) {
1062    escapes = !regionLoc->getRegion()->hasStackStorage();
1063
1064    if (!escapes) {
1065      // To test (3), generate a new state with the binding added.  If it is
1066      // the same state, then it escapes (since the store cannot represent
1067      // the binding).
1068      escapes = (state == (state->bindLoc(*regionLoc, val)));
1069    }
1070    if (!escapes) {
1071      // Case 4: We do not currently model what happens when a symbol is
1072      // assigned to a struct field, so be conservative here and let the symbol
1073      // go. TODO: This could definitely be improved upon.
1074      escapes = !isa<VarRegion>(regionLoc->getRegion());
1075    }
1076  }
1077
1078  // If our store can represent the binding and we aren't storing to something
1079  // that doesn't have local storage then just return and have the simulation
1080  // state continue as is.
1081  if (!escapes)
1082      return;
1083
1084  // Otherwise, find all symbols referenced by 'val' that we are tracking
1085  // and stop tracking them.
1086  state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
1087  C.addTransition(state);
1088}
1089
1090// If a symbolic region is assumed to NULL (or another constant), stop tracking
1091// it - assuming that allocation failed on this path.
1092ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state,
1093                                              SVal Cond,
1094                                              bool Assumption) const {
1095  RegionStateTy RS = state->get<RegionState>();
1096  for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
1097    // If the symbol is assumed to NULL or another constant, this will
1098    // return an APSInt*.
1099    if (state->getSymVal(I.getKey()))
1100      state = state->remove<RegionState>(I.getKey());
1101  }
1102
1103  // Realloc returns 0 when reallocation fails, which means that we should
1104  // restore the state of the pointer being reallocated.
1105  ReallocMap RP = state->get<ReallocPairs>();
1106  for (ReallocMap::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
1107    // If the symbol is assumed to NULL or another constant, this will
1108    // return an APSInt*.
1109    if (state->getSymVal(I.getKey())) {
1110      SymbolRef ReallocSym = I.getData().ReallocatedSym;
1111      const RefState *RS = state->get<RegionState>(ReallocSym);
1112      if (RS) {
1113        if (RS->isReleased() && ! I.getData().IsFreeOnFailure)
1114          state = state->set<RegionState>(ReallocSym,
1115                             RefState::getAllocateUnchecked(RS->getStmt()));
1116      }
1117      state = state->remove<ReallocPairs>(I.getKey());
1118    }
1119  }
1120
1121  return state;
1122}
1123
1124// Check if the function is known to us. So, for example, we could
1125// conservatively assume it can free/reallocate it's pointer arguments.
1126// (We assume that the pointers cannot escape through calls to system
1127// functions not handled by this checker.)
1128bool MallocChecker::doesNotFreeMemory(const CallOrObjCMessage *Call,
1129                                      ProgramStateRef State) const {
1130  if (!Call)
1131    return false;
1132
1133  // For now, assume that any C++ call can free memory.
1134  // TODO: If we want to be more optimistic here, we'll need to make sure that
1135  // regions escape to C++ containers. They seem to do that even now, but for
1136  // mysterious reasons.
1137  if (Call->isCXXCall())
1138    return false;
1139
1140  const Decl *D = Call->getDecl();
1141  if (!D)
1142    return false;
1143
1144  ASTContext &ASTC = State->getStateManager().getContext();
1145
1146  // If it's one of the allocation functions we can reason about, we model
1147  // its behavior explicitly.
1148  if (isa<FunctionDecl>(D) && isMemFunction(cast<FunctionDecl>(D), ASTC)) {
1149    return true;
1150  }
1151
1152  // If it's not a system call, assume it frees memory.
1153  SourceManager &SM = ASTC.getSourceManager();
1154  if (!SM.isInSystemHeader(D->getLocation()))
1155    return false;
1156
1157  // Process C/ObjC functions.
1158  if (const FunctionDecl *FD  = dyn_cast<FunctionDecl>(D)) {
1159    // White list the system functions whose arguments escape.
1160    const IdentifierInfo *II = FD->getIdentifier();
1161    if (!II)
1162      return true;
1163    StringRef FName = II->getName();
1164
1165    // White list thread local storage.
1166    if (FName.equals("pthread_setspecific"))
1167      return false;
1168
1169    // White list the 'XXXNoCopy' ObjC functions.
1170    if (FName.endswith("NoCopy")) {
1171      // Look for the deallocator argument. We know that the memory ownership
1172      // is not transfered only if the deallocator argument is
1173      // 'kCFAllocatorNull'.
1174      for (unsigned i = 1; i < Call->getNumArgs(); ++i) {
1175        const Expr *ArgE = Call->getArg(i)->IgnoreParenCasts();
1176        if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) {
1177          StringRef DeallocatorName = DE->getFoundDecl()->getName();
1178          if (DeallocatorName == "kCFAllocatorNull")
1179            return true;
1180        }
1181      }
1182      return false;
1183    }
1184
1185    // PR12101
1186    // Many CoreFoundation and CoreGraphics might allow a tracked object
1187    // to escape.
1188    if (Call->isCFCGAllowingEscape(FName))
1189      return false;
1190
1191    // Associating streams with malloced buffers. The pointer can escape if
1192    // 'closefn' is specified (and if that function does free memory).
1193    // Currently, we do not inspect the 'closefn' function (PR12101).
1194    if (FName == "funopen")
1195      if (Call->getNumArgs() >= 4 && !Call->getArgSVal(4).isConstant(0))
1196        return false;
1197
1198    // Do not warn on pointers passed to 'setbuf' when used with std streams,
1199    // these leaks might be intentional when setting the buffer for stdio.
1200    // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer
1201    if (FName == "setbuf" || FName =="setbuffer" ||
1202        FName == "setlinebuf" || FName == "setvbuf") {
1203      if (Call->getNumArgs() >= 1)
1204        if (const DeclRefExpr *Arg =
1205              dyn_cast<DeclRefExpr>(Call->getArg(0)->IgnoreParenCasts()))
1206          if (const VarDecl *D = dyn_cast<VarDecl>(Arg->getDecl()))
1207              if (D->getCanonicalDecl()->getName().find("std")
1208                                                   != StringRef::npos)
1209                return false;
1210    }
1211
1212    // A bunch of other functions, which take ownership of a pointer (See retain
1213    // release checker). Not all the parameters here are invalidated, but the
1214    // Malloc checker cannot differentiate between them. The right way of doing
1215    // this would be to implement a pointer escapes callback.
1216    if (FName == "CVPixelBufferCreateWithBytes" ||
1217        FName == "CGBitmapContextCreateWithData" ||
1218        FName == "CVPixelBufferCreateWithPlanarBytes") {
1219      return false;
1220    }
1221
1222    // Otherwise, assume that the function does not free memory.
1223    // Most system calls, do not free the memory.
1224    return true;
1225
1226  // Process ObjC functions.
1227  } else if (const ObjCMethodDecl * ObjCD = dyn_cast<ObjCMethodDecl>(D)) {
1228    Selector S = ObjCD->getSelector();
1229
1230    // White list the ObjC functions which do free memory.
1231    // - Anything containing 'freeWhenDone' param set to 1.
1232    //   Ex: dataWithBytesNoCopy:length:freeWhenDone.
1233    for (unsigned i = 1; i < S.getNumArgs(); ++i) {
1234      if (S.getNameForSlot(i).equals("freeWhenDone")) {
1235        if (Call->getArgSVal(i).isConstant(1))
1236          return false;
1237        else
1238          return true;
1239      }
1240    }
1241
1242    // If the first selector ends with NoCopy, assume that the ownership is
1243    // transfered as well.
1244    // Ex:  [NSData dataWithBytesNoCopy:bytes length:10];
1245    if (S.getNameForSlot(0).endswith("NoCopy")) {
1246      return false;
1247    }
1248
1249    // Otherwise, assume that the function does not free memory.
1250    // Most system calls, do not free the memory.
1251    return true;
1252  }
1253
1254  // Otherwise, assume that the function can free memory.
1255  return false;
1256
1257}
1258
1259// If the symbol we are tracking is invalidated, but not explicitly (ex: the &p
1260// escapes, when we are tracking p), do not track the symbol as we cannot reason
1261// about it anymore.
1262ProgramStateRef
1263MallocChecker::checkRegionChanges(ProgramStateRef State,
1264                            const StoreManager::InvalidatedSymbols *invalidated,
1265                                    ArrayRef<const MemRegion *> ExplicitRegions,
1266                                    ArrayRef<const MemRegion *> Regions,
1267                                    const CallOrObjCMessage *Call) const {
1268  if (!invalidated || invalidated->empty())
1269    return State;
1270  llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
1271
1272  // If it's a call which might free or reallocate memory, we assume that all
1273  // regions (explicit and implicit) escaped.
1274
1275  // Otherwise, whitelist explicit pointers; we still can track them.
1276  if (!Call || doesNotFreeMemory(Call, State)) {
1277    for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
1278        E = ExplicitRegions.end(); I != E; ++I) {
1279      if (const SymbolicRegion *R = (*I)->StripCasts()->getAs<SymbolicRegion>())
1280        WhitelistedSymbols.insert(R->getSymbol());
1281    }
1282  }
1283
1284  for (StoreManager::InvalidatedSymbols::const_iterator I=invalidated->begin(),
1285       E = invalidated->end(); I!=E; ++I) {
1286    SymbolRef sym = *I;
1287    if (WhitelistedSymbols.count(sym))
1288      continue;
1289    // The symbol escaped.
1290    if (const RefState *RS = State->get<RegionState>(sym))
1291      State = State->set<RegionState>(sym, RefState::getEscaped(RS->getStmt()));
1292  }
1293  return State;
1294}
1295
1296static SymbolRef findFailedReallocSymbol(ProgramStateRef currState,
1297                                         ProgramStateRef prevState) {
1298  ReallocMap currMap = currState->get<ReallocPairs>();
1299  ReallocMap prevMap = prevState->get<ReallocPairs>();
1300
1301  for (ReallocMap::iterator I = prevMap.begin(), E = prevMap.end();
1302       I != E; ++I) {
1303    SymbolRef sym = I.getKey();
1304    if (!currMap.lookup(sym))
1305      return sym;
1306  }
1307
1308  return NULL;
1309}
1310
1311PathDiagnosticPiece *
1312MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N,
1313                                           const ExplodedNode *PrevN,
1314                                           BugReporterContext &BRC,
1315                                           BugReport &BR) {
1316  ProgramStateRef state = N->getState();
1317  ProgramStateRef statePrev = PrevN->getState();
1318
1319  const RefState *RS = state->get<RegionState>(Sym);
1320  const RefState *RSPrev = statePrev->get<RegionState>(Sym);
1321  if (!RS && !RSPrev)
1322    return 0;
1323
1324  const Stmt *S = 0;
1325  const char *Msg = 0;
1326  StackHintGeneratorForSymbol *StackHint = 0;
1327
1328  // Retrieve the associated statement.
1329  ProgramPoint ProgLoc = N->getLocation();
1330  if (isa<StmtPoint>(ProgLoc))
1331    S = cast<StmtPoint>(ProgLoc).getStmt();
1332  // If an assumption was made on a branch, it should be caught
1333  // here by looking at the state transition.
1334  if (isa<BlockEdge>(ProgLoc)) {
1335    const CFGBlock *srcBlk = cast<BlockEdge>(ProgLoc).getSrc();
1336    S = srcBlk->getTerminator();
1337  }
1338  if (!S)
1339    return 0;
1340
1341  // Find out if this is an interesting point and what is the kind.
1342  if (Mode == Normal) {
1343    if (isAllocated(RS, RSPrev, S)) {
1344      Msg = "Memory is allocated";
1345      StackHint = new StackHintGeneratorForSymbol(Sym,
1346                                                  "Returned allocated memory");
1347    } else if (isReleased(RS, RSPrev, S)) {
1348      Msg = "Memory is released";
1349      StackHint = new StackHintGeneratorForSymbol(Sym,
1350                                                  "Returned released memory");
1351    } else if (isReallocFailedCheck(RS, RSPrev, S)) {
1352      Mode = ReallocationFailed;
1353      Msg = "Reallocation failed";
1354      StackHint = new StackHintGeneratorForReallocationFailed(Sym,
1355                                                       "Reallocation failed");
1356
1357      if (SymbolRef sym = findFailedReallocSymbol(state, statePrev))
1358        BR.markInteresting(sym);
1359    }
1360
1361  // We are in a special mode if a reallocation failed later in the path.
1362  } else if (Mode == ReallocationFailed) {
1363    // Generate a special diagnostic for the first realloc we find.
1364    if (!isAllocated(RS, RSPrev, S) && !isReleased(RS, RSPrev, S))
1365      return 0;
1366
1367    // Check that the name of the function is realloc.
1368    const CallExpr *CE = dyn_cast<CallExpr>(S);
1369    if (!CE)
1370      return 0;
1371    const FunctionDecl *funDecl = CE->getDirectCallee();
1372    if (!funDecl)
1373      return 0;
1374    StringRef FunName = funDecl->getName();
1375    if (!(FunName.equals("realloc") || FunName.equals("reallocf")))
1376      return 0;
1377    Msg = "Attempt to reallocate memory";
1378    StackHint = new StackHintGeneratorForSymbol(Sym,
1379                                                "Returned reallocated memory");
1380    Mode = Normal;
1381  }
1382
1383  if (!Msg)
1384    return 0;
1385  assert(StackHint);
1386
1387  // Generate the extra diagnostic.
1388  PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
1389                             N->getLocationContext());
1390  return new PathDiagnosticEventPiece(Pos, Msg, true, StackHint);
1391}
1392
1393
1394#define REGISTER_CHECKER(name) \
1395void ento::register##name(CheckerManager &mgr) {\
1396  registerCStringCheckerBasic(mgr); \
1397  mgr.registerChecker<MallocChecker>()->Filter.C##name = true;\
1398}
1399
1400REGISTER_CHECKER(MallocPessimistic)
1401REGISTER_CHECKER(MallocOptimistic)
1402