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