MallocChecker.cpp revision 5d0ea6d62e076c776ddad028c4eb615783be1323
128c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar//=== MallocChecker.cpp - A malloc/free checker -------------------*- C++ -*--//
2fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar//
3fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar//                     The LLVM Compiler Infrastructure
4fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar//
5fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar// This file is distributed under the University of Illinois Open Source
6fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar// License. See LICENSE.TXT for details.
7fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar//
8fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar//===----------------------------------------------------------------------===//
9fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar//
1028c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar// This file defines malloc/free checker, which checks for potential memory
1128c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar// leaks, double free, and use-after-free problems.
12fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar//
1385f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola//===----------------------------------------------------------------------===//
14fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar
151f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "ClangSACheckers.h"
16fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar#include "clang/StaticAnalyzer/Core/Checker.h"
17fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar#include "clang/StaticAnalyzer/Core/CheckerManager.h"
18684c593d05db0bd277268fc9d8c05bce138c745aChris Lattner#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
19f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
2032a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
21fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
220eab5c4d85b4c4bb161bcdd959aa58a6f54415ccDaniel Dunbar#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
2385f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola#include "llvm/ADT/ImmutableMap.h"
24fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbarusing namespace clang;
2515d170709608e2f1efcada74c297c10c8c71fdcfDaniel Dunbarusing namespace ento;
2687392fde1f261fea161b48886fafbedddb18dcceDaniel Dunbar
274f3e7aa154577c86791908e73a9fec075fdea0baChris Lattnernamespace {
2885f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola
29fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbarclass RefState {
3028c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar  enum Kind { AllocateUnchecked, AllocateFailed, Released, Escaped,
319643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar              Relinquished } K;
3228c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar  const Stmt *S;
33fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar
3428c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbarpublic:
351aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar  RefState(Kind k, const Stmt *s) : K(k), S(s) {}
361aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar
371aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar  bool isAllocated() const { return K == AllocateUnchecked; }
385d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner  //bool isFailed() const { return K == AllocateFailed; }
395d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner  bool isReleased() const { return K == Released; }
40fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  //bool isEscaped() const { return K == Escaped; }
419643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  //bool isRelinquished() const { return K == Relinquished; }
42fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar
4328c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar  bool operator==(const RefState &X) const {
449643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    return K == X.K && S == X.S;
459643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  }
469643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
479643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  static RefState getAllocateUnchecked(const Stmt *s) {
48d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola    return RefState(AllocateUnchecked, s);
49d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola  }
5085f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola  static RefState getAllocateFailed() {
51fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar    return RefState(AllocateFailed, 0);
52159f527cb269002de85e671023b9231a2c8792e9Dan Gohman  }
539643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  static RefState getReleased(const Stmt *s) { return RefState(Released, s); }
54d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola  static RefState getEscaped(const Stmt *s) { return RefState(Escaped, s); }
55d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola  static RefState getRelinquished(const Stmt *s) {
5685f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola    return RefState(Relinquished, s);
57f230df9af4012f9510de664b6d62b128e26a5861Rafael Espindola  }
58fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar
599643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  void Profile(llvm::FoldingSetNodeID &ID) const {
609643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    ID.AddInteger(K);
61fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar    ID.AddPointer(S);
6228c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar  }
63fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar};
649643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
6587392fde1f261fea161b48886fafbedddb18dcceDaniel Dunbarclass RegionState {};
6687392fde1f261fea161b48886fafbedddb18dcceDaniel Dunbar
6787392fde1f261fea161b48886fafbedddb18dcceDaniel Dunbarclass MallocChecker : public Checker<eval::Call, check::DeadSymbols, check::EndPath, check::PreStmt<ReturnStmt>, check::Location,
688cb9a3b13f3226b7e741768b69d26ecd6b5231f1Chris Lattner                               check::Bind, eval::Assume> {
6987392fde1f261fea161b48886fafbedddb18dcceDaniel Dunbar  mutable llvm::OwningPtr<BuiltinBug> BT_DoubleFree;
7087392fde1f261fea161b48886fafbedddb18dcceDaniel Dunbar  mutable llvm::OwningPtr<BuiltinBug> BT_Leak;
7187392fde1f261fea161b48886fafbedddb18dcceDaniel Dunbar  mutable llvm::OwningPtr<BuiltinBug> BT_UseFree;
729643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  mutable llvm::OwningPtr<BuiltinBug> BT_UseRelinquished;
739643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  mutable llvm::OwningPtr<BuiltinBug> BT_BadFree;
749643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc;
75fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar
76fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbarpublic:
7715d170709608e2f1efcada74c297c10c8c71fdcfDaniel Dunbar  MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0) {}
78f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar
79f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar  bool evalCall(const CallExpr *CE, CheckerContext &C) const;
80f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar  void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
81fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  void checkEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng) const;
82d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola  void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
83d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola  const ProgramState *evalAssume(const ProgramState *state, SVal Cond,
84d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola                            bool Assumption) const;
8585f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola  void checkLocation(SVal l, bool isLoad, CheckerContext &C) const;
86d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola  void checkBind(SVal location, SVal val, CheckerContext &C) const;
87fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar
8815d170709608e2f1efcada74c297c10c8c71fdcfDaniel Dunbarprivate:
891aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar  static void MallocMem(CheckerContext &C, const CallExpr *CE);
9015d170709608e2f1efcada74c297c10c8c71fdcfDaniel Dunbar  static void MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
9115d170709608e2f1efcada74c297c10c8c71fdcfDaniel Dunbar                                   const OwnershipAttr* Att);
92f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar  static const ProgramState *MallocMemAux(CheckerContext &C, const CallExpr *CE,
9315d170709608e2f1efcada74c297c10c8c71fdcfDaniel Dunbar                                     const Expr *SizeEx, SVal Init,
9433a38a1b5a35acd15c867193bc2175f3d4e7b83dRafael Espindola                                     const ProgramState *state) {
9515d170709608e2f1efcada74c297c10c8c71fdcfDaniel Dunbar    return MallocMemAux(C, CE, state->getSVal(SizeEx), Init, state);
960eab5c4d85b4c4bb161bcdd959aa58a6f54415ccDaniel Dunbar  }
970eab5c4d85b4c4bb161bcdd959aa58a6f54415ccDaniel Dunbar  static const ProgramState *MallocMemAux(CheckerContext &C, const CallExpr *CE,
980eab5c4d85b4c4bb161bcdd959aa58a6f54415ccDaniel Dunbar                                     SVal SizeEx, SVal Init,
990eab5c4d85b4c4bb161bcdd959aa58a6f54415ccDaniel Dunbar                                     const ProgramState *state);
1000eab5c4d85b4c4bb161bcdd959aa58a6f54415ccDaniel Dunbar
1010eab5c4d85b4c4bb161bcdd959aa58a6f54415ccDaniel Dunbar  void FreeMem(CheckerContext &C, const CallExpr *CE) const;
1029643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  void FreeMemAttr(CheckerContext &C, const CallExpr *CE,
1039643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar                   const OwnershipAttr* Att) const;
10428c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar  const ProgramState *FreeMemAux(CheckerContext &C, const CallExpr *CE,
105fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar                           const ProgramState *state, unsigned Num, bool Hold) const;
106a0e36d55c495b3325805c659ac365b5faea84e34Daniel Dunbar
1078cb9a3b13f3226b7e741768b69d26ecd6b5231f1Chris Lattner  void ReallocMem(CheckerContext &C, const CallExpr *CE) const;
1088cb9a3b13f3226b7e741768b69d26ecd6b5231f1Chris Lattner  static void CallocMem(CheckerContext &C, const CallExpr *CE);
1098cb9a3b13f3226b7e741768b69d26ecd6b5231f1Chris Lattner
1108cb9a3b13f3226b7e741768b69d26ecd6b5231f1Chris Lattner  static bool SummarizeValue(raw_ostream &os, SVal V);
111fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
11228c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar  void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange range) const;
11328c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar};
114fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar} // end anonymous namespace
115fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar
116159f527cb269002de85e671023b9231a2c8792e9Dan Gohmantypedef llvm::ImmutableMap<SymbolRef, RefState> RegionStateTy;
11728c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar
1189643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbarnamespace clang {
1199643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbarnamespace ento {
1209643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  template <>
1219643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  struct ProgramStateTrait<RegionState>
1229643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    : public ProgramStatePartialTrait<RegionStateTy> {
1239643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    static void *GDMIndex() { static int x; return &x; }
1249643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  };
1259643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar}
1269643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar}
1279643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
1289643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbarbool MallocChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
129fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  const ProgramState *state = C.getState();
130fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  const Expr *Callee = CE->getCallee();
1319643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  SVal L = state->getSVal(Callee);
1329643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
1339643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  const FunctionDecl *FD = L.getAsFunctionDecl();
1349643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  if (!FD)
135fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar    return false;
13628c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar
137fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  ASTContext &Ctx = C.getASTContext();
138fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  if (!II_malloc)
13928c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar    II_malloc = &Ctx.Idents.get("malloc");
1401aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar  if (!II_free)
1411aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar    II_free = &Ctx.Idents.get("free");
1421aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar  if (!II_realloc)
1431aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar    II_realloc = &Ctx.Idents.get("realloc");
1441aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar  if (!II_calloc)
14528c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar    II_calloc = &Ctx.Idents.get("calloc");
1464e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar
1474e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  if (FD->getIdentifier() == II_malloc) {
1484e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar    MallocMem(C, CE);
1494e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar    return true;
1504e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  }
1514e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar
1524e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  if (FD->getIdentifier() == II_free) {
1534e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar    FreeMem(C, CE);
1544e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar    return true;
1554e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  }
1564e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar
157a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola  if (FD->getIdentifier() == II_realloc) {
1584e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar    ReallocMem(C, CE);
1594e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar    return true;
160b4d1721eff7b43577e5f2e53f885973fb6c43683Rafael Espindola  }
161a264f72d3fb9dec1427480fcf17ef3c746ea723aRafael Espindola
16218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola  if (FD->getIdentifier() == II_calloc) {
1630cf15d61b7e3bf53f5a99f58ada37b93bc039559Rafael Espindola    CallocMem(C, CE);
1646135a96792ca05f6366e5dbaee6208e84589c47fChris Lattner    return true;
1652c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  }
1662c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach
1672c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  // Check all the attributes, if there are any.
1682c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  // There can be multiple of these attributes.
1692c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  bool rv = false;
1702c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  if (FD->hasAttrs()) {
1712c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    for (specific_attr_iterator<OwnershipAttr>
172c67b1a3a76ea6ff642d30610cf63595ccb661e6bBob Wilson                  i = FD->specific_attr_begin<OwnershipAttr>(),
1731e61e69d401045c54b15815f15a0fdb3ca56a9b5Chris Lattner                  e = FD->specific_attr_end<OwnershipAttr>();
174a1000742d28f33dd8dd9858e64282e7749c0bd64Roman Divacky         i != e; ++i) {
175a1000742d28f33dd8dd9858e64282e7749c0bd64Roman Divacky      switch ((*i)->getOwnKind()) {
176a1000742d28f33dd8dd9858e64282e7749c0bd64Roman Divacky      case OwnershipAttr::Returns: {
1773507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes        MallocMemReturnsAttr(C, CE, *i);
1783507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes        rv = true;
1793507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes        break;
1803507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes      }
181e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes      case OwnershipAttr::Takes:
1823507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes      case OwnershipAttr::Holds: {
1833507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes        FreeMemAttr(C, CE, *i);
1843507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes        rv = true;
1853507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes        break;
1863faac0a78c7a70d3dcd2af102a132bb9da2d639cAkira Hatanaka      }
1873faac0a78c7a70d3dcd2af102a132bb9da2d639cAkira Hatanaka      default:
1883faac0a78c7a70d3dcd2af102a132bb9da2d639cAkira Hatanaka        break;
1893507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes      }
1903507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes    }
1913507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes  }
1923507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes  return rv;
1933507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes}
1943507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes
1953507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopesvoid MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) {
1963507d24547ce668c9a50c72b6748c0a303e295c1Bruno Cardoso Lopes  const ProgramState *state = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(),
1974e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar                                      C.getState());
1984e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  C.addTransition(state);
1994e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar}
2004e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar
2019643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbarvoid MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
202fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar                                         const OwnershipAttr* Att) {
2034e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  if (Att->getModule() != "malloc")
2044e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar    return;
2054e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar
2064e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
20799b4237c1647156f0e1d3d7e03efdab23ed79778Rafael Espindola  if (I != E) {
20899b4237c1647156f0e1d3d7e03efdab23ed79778Rafael Espindola    const ProgramState *state =
20999b4237c1647156f0e1d3d7e03efdab23ed79778Rafael Espindola        MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState());
210fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar    C.addTransition(state);
2119643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    return;
2129643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  }
2139643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  const ProgramState *state = MallocMemAux(C, CE, UnknownVal(), UndefinedVal(),
2149643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar                                        C.getState());
2154e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  C.addTransition(state);
2164e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar}
2174e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar
2184e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbarconst ProgramState *MallocChecker::MallocMemAux(CheckerContext &C,
2194e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar                                           const CallExpr *CE,
2204e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar                                           SVal Size, SVal Init,
2214e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar                                           const ProgramState *state) {
2224e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  unsigned Count = C.getCurrentBlockCount();
223c67b1a3a76ea6ff642d30610cf63595ccb661e6bBob Wilson  SValBuilder &svalBuilder = C.getSValBuilder();
2249643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
2259643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  // Set the return value.
2269643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  SVal retVal = svalBuilder.getConjuredSymbolVal(NULL, CE, CE->getType(), Count);
2279643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  state = state->BindExpr(CE, retVal);
2289643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
2299643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  // Fill the region with the initialization value.
2304e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  state = state->bindDefault(retVal, Init);
2314e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar
2324e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  // Set the region's extent equal to the Size parameter.
2334e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  const SymbolicRegion *R = cast<SymbolicRegion>(retVal.getAsRegion());
2344e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
2354e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  DefinedOrUnknownSVal DefinedSize = cast<DefinedOrUnknownSVal>(Size);
2364e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  DefinedOrUnknownSVal extentMatchesSize =
2374e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar    svalBuilder.evalEQ(state, Extent, DefinedSize);
2384e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar
2394e815f8a8cae6c846cdca52420046cab902865deDaniel Dunbar  state = state->assume(extentMatchesSize, true);
2409643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  assert(state);
2419643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
2429643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  SymbolRef Sym = retVal.getAsLocSymbol();
2439643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  assert(Sym);
244fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar
24528c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar  // Set the symbol's state to Allocated.
246fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  return state->set<RegionState>(Sym, RefState::getAllocateUnchecked(CE));
247fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar}
24828c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar
24928c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbarvoid MallocChecker::FreeMem(CheckerContext &C, const CallExpr *CE) const {
250fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  const ProgramState *state = FreeMemAux(C, CE, C.getState(), 0, false);
251fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar
2521aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar  if (state)
2531aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar    C.addTransition(state);
2541aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar}
2551aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar
256fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbarvoid MallocChecker::FreeMemAttr(CheckerContext &C, const CallExpr *CE,
257fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar                                const OwnershipAttr* Att) const {
258fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  if (Att->getModule() != "malloc")
259fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar    return;
2609643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
261fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
2629643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar       I != E; ++I) {
26328c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar    const ProgramState *state = FreeMemAux(C, CE, C.getState(), *I,
2649643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar                                      Att->getOwnKind() == OwnershipAttr::Holds);
2659643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    if (state)
2669643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      C.addTransition(state);
2679643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  }
2689643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar}
2699643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
2709643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbarconst ProgramState *MallocChecker::FreeMemAux(CheckerContext &C, const CallExpr *CE,
2719643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar                                         const ProgramState *state, unsigned Num,
2729643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar                                         bool Hold) const {
2739643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  const Expr *ArgExpr = CE->getArg(Num);
2749643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  SVal ArgVal = state->getSVal(ArgExpr);
2759643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
2769643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(ArgVal);
2779643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
2789643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  // Check for null dereferences.
279fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  if (!isa<Loc>(location))
2809643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    return state;
2819643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
2829643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  // FIXME: Technically using 'Assume' here can result in a path
2839643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  //  bifurcation.  In such cases we need to return two states, not just one.
2849643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  const ProgramState *notNullState, *nullState;
2859643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  llvm::tie(notNullState, nullState) = state->assume(location);
2869643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
287fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  // The explicit NULL case, no operation is performed.
2889643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  if (nullState && !notNullState)
289fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar    return nullState;
290fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar
2919643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  assert(notNullState);
2929643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
293fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  // Unknown values could easily be okay
2949643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  // Undefined values are handled elsewhere
2959643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  if (ArgVal.isUnknownOrUndef())
2969643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    return notNullState;
2979643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
298fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  const MemRegion *R = ArgVal.getAsRegion();
29928c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar
300fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  // Nonlocs can't be freed, of course.
301fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  // Non-region locations (labels and fixed addresses) also shouldn't be freed.
30228c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar  if (!R) {
30328c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
304fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar    return NULL;
305fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  }
3061aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar
3071aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar  R = R->StripCasts();
308036c130e90eb5c93b0dc0a70ad07b9343623c2a8Dan Gohman
3091aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar  // Blocks might show up as heap data, but should not be free()d
310036c130e90eb5c93b0dc0a70ad07b9343623c2a8Dan Gohman  if (isa<BlockDataRegion>(R)) {
311036c130e90eb5c93b0dc0a70ad07b9343623c2a8Dan Gohman    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
312036c130e90eb5c93b0dc0a70ad07b9343623c2a8Dan Gohman    return NULL;
313036c130e90eb5c93b0dc0a70ad07b9343623c2a8Dan Gohman  }
3141aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar
3151aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar  const MemSpaceRegion *MS = R->getMemorySpace();
316036c130e90eb5c93b0dc0a70ad07b9343623c2a8Dan Gohman
317036c130e90eb5c93b0dc0a70ad07b9343623c2a8Dan Gohman  // Parameters, locals, statics, and globals shouldn't be freed.
318036c130e90eb5c93b0dc0a70ad07b9343623c2a8Dan Gohman  if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
319036c130e90eb5c93b0dc0a70ad07b9343623c2a8Dan Gohman    // FIXME: at the time this code was written, malloc() regions were
320036c130e90eb5c93b0dc0a70ad07b9343623c2a8Dan Gohman    // represented by conjured symbols, which are all in UnknownSpaceRegion.
3211aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar    // This means that there isn't actually anything from HeapSpaceRegion
3221aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar    // that should be freed, even though we allow it here.
3231aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar    // Of course, free() can work on memory allocated outside the current
324036c130e90eb5c93b0dc0a70ad07b9343623c2a8Dan Gohman    // function, so UnknownSpaceRegion is always a possibility.
325036c130e90eb5c93b0dc0a70ad07b9343623c2a8Dan Gohman    // False negatives are better than false positives.
3261aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar
3271aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
328fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar    return NULL;
329fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  }
330fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar
331fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R);
3329643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  // Various cases could lead to non-symbol values here.
333fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  // For now, ignore them.
3349643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  if (!SR)
33528c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar    return notNullState;
3369643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
3379643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  SymbolRef Sym = SR->getSymbol();
3389643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  const RefState *RS = state->get<RegionState>(Sym);
3399643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
3409643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  // If the symbol has not been tracked, return. This is possible when free() is
3419643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  // called on a pointer that does not get its pointee directly from malloc().
3429643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  // Full support of this requires inter-procedural analysis.
3439643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  if (!RS)
3449643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    return notNullState;
3459643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
3469643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  // Check double free.
3479643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  if (RS->isReleased()) {
3489643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    if (ExplodedNode *N = C.generateSink()) {
3499643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      if (!BT_DoubleFree)
3509643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar        BT_DoubleFree.reset(
3519643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar          new BuiltinBug("Double free",
3529643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar                         "Try to free a memory block that has been released"));
3539643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      // FIXME: should find where it's freed last time.
3549643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      BugReport *R = new BugReport(*BT_DoubleFree,
3559643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar                                   BT_DoubleFree->getDescription(), N);
3569643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      C.EmitReport(R);
3579643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    }
3589643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    return NULL;
3599643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  }
3609643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
3619643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  // Normal free.
3629643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  if (Hold)
3639643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    return notNullState->set<RegionState>(Sym, RefState::getRelinquished(CE));
3649643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  return notNullState->set<RegionState>(Sym, RefState::getReleased(CE));
3659643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar}
3669643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
3679643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbarbool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
3689643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  if (nonloc::ConcreteInt *IntVal = dyn_cast<nonloc::ConcreteInt>(&V))
3699643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    os << "an integer (" << IntVal->getValue() << ")";
370fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar  else if (loc::ConcreteInt *ConstAddr = dyn_cast<loc::ConcreteInt>(&V))
3719643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    os << "a constant address (" << ConstAddr->getValue() << ")";
3729643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  else if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&V))
3739643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    os << "the address of the label '" << Label->getLabel()->getName() << "'";
3749643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  else
3759643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    return false;
3769643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
3779643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  return true;
3789643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar}
3799643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
3809643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbarbool MallocChecker::SummarizeRegion(raw_ostream &os,
3819643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar                                    const MemRegion *MR) {
3829643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  switch (MR->getKind()) {
3839643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  case MemRegion::FunctionTextRegionKind: {
3849643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    const FunctionDecl *FD = cast<FunctionTextRegion>(MR)->getDecl();
3859643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    if (FD)
3869643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      os << "the address of the function '" << FD << "'";
3879643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    else
3889643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      os << "the address of a function";
3899643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    return true;
3909643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  }
3919643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  case MemRegion::BlockTextRegionKind:
3929643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    os << "block text";
3939643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    return true;
3949643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  case MemRegion::BlockDataRegionKind:
3959643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    // FIXME: where the block came from?
3969643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    os << "a block";
3979643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    return true;
3989643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar  default: {
3999643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    const MemSpaceRegion *MS = MR->getMemorySpace();
4009643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
4019643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    switch (MS->getKind()) {
4029643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    case MemRegion::StackLocalsSpaceRegionKind: {
4039643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      const VarRegion *VR = dyn_cast<VarRegion>(MR);
4049643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      const VarDecl *VD;
4059643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      if (VR)
4069643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar        VD = VR->getDecl();
4079643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      else
4089643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar        VD = NULL;
4099643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar
4109643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      if (VD)
4119643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar        os << "the address of the local variable '" << VD->getName() << "'";
4129643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      else
4139643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar        os << "the address of a local stack variable";
4149643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      return true;
4159643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    }
4169643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    case MemRegion::StackArgumentsSpaceRegionKind: {
4179643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      const VarRegion *VR = dyn_cast<VarRegion>(MR);
4189643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      const VarDecl *VD;
419fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar      if (VR)
4209643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar        VD = VR->getDecl();
421fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar      else
422fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar        VD = NULL;
4231aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar
4249643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      if (VD)
4251aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar        os << "the address of the parameter '" << VD->getName() << "'";
4261aa14aac4198bca0f44e4adad42bf6238cbf9757Daniel Dunbar      else
4279643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar        os << "the address of a parameter";
4289643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      return true;
4299643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    }
430fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar    case MemRegion::NonStaticGlobalSpaceRegionKind:
4319643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar    case MemRegion::StaticGlobalSpaceRegionKind: {
4329643ac55142d40da404caa8e5fedfef2cd7b4afcDaniel Dunbar      const VarRegion *VR = dyn_cast<VarRegion>(MR);
433fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar      const VarDecl *VD;
43428c251b54b0b311749f07babe0f6909e71e877bcDaniel Dunbar      if (VR)
435fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar        VD = VR->getDecl();
436fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar      else
4375d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner        VD = NULL;
4385d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner
4395d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner      if (VD) {
4405d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner        if (VD->isStaticLocal())
4415d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner          os << "the address of the static variable '" << VD->getName() << "'";
4425d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner        else
443df9c4380ee7e60c1de5cae32685b113170b1faa2Chris Lattner          os << "the address of the global variable '" << VD->getName() << "'";
4445d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner      } else
4455d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner        os << "the address of a global variable";
446e3e7a369f20af66a96830d8bfe52668c9e2e1fa1Chris Lattner      return true;
4475d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner    }
448a0e36d55c495b3325805c659ac365b5faea84e34Daniel Dunbar    default:
4495d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner      return false;
450f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar    }
451a0e36d55c495b3325805c659ac365b5faea84e34Daniel Dunbar  }
4527597212abced110723f2fee985a7d60557c092ecEvan Cheng  }
4530eab5c4d85b4c4bb161bcdd959aa58a6f54415ccDaniel Dunbar}
4545d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner
4555d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattnervoid MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
4565d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner                                  SourceRange range) const {
4575d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner  if (ExplodedNode *N = C.generateSink()) {
4585d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner    if (!BT_BadFree)
4595d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner      BT_BadFree.reset(new BuiltinBug("Bad free"));
4605d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner
461fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar    llvm::SmallString<100> buf;
462fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar    llvm::raw_svector_ostream os(buf);
463fc6877aec9826fa830204d49eba7fac7412b841eDaniel Dunbar
464    const MemRegion *MR = ArgVal.getAsRegion();
465    if (MR) {
466      while (const ElementRegion *ER = dyn_cast<ElementRegion>(MR))
467        MR = ER->getSuperRegion();
468
469      // Special case for alloca()
470      if (isa<AllocaRegion>(MR))
471        os << "Argument to free() was allocated by alloca(), not malloc()";
472      else {
473        os << "Argument to free() is ";
474        if (SummarizeRegion(os, MR))
475          os << ", which is not memory allocated by malloc()";
476        else
477          os << "not memory allocated by malloc()";
478      }
479    } else {
480      os << "Argument to free() is ";
481      if (SummarizeValue(os, ArgVal))
482        os << ", which is not memory allocated by malloc()";
483      else
484        os << "not memory allocated by malloc()";
485    }
486
487    BugReport *R = new BugReport(*BT_BadFree, os.str(), N);
488    R->addRange(range);
489    C.EmitReport(R);
490  }
491}
492
493void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
494  const ProgramState *state = C.getState();
495  const Expr *arg0Expr = CE->getArg(0);
496  DefinedOrUnknownSVal arg0Val
497    = cast<DefinedOrUnknownSVal>(state->getSVal(arg0Expr));
498
499  SValBuilder &svalBuilder = C.getSValBuilder();
500
501  DefinedOrUnknownSVal PtrEQ =
502    svalBuilder.evalEQ(state, arg0Val, svalBuilder.makeNull());
503
504  // Get the size argument. If there is no size arg then give up.
505  const Expr *Arg1 = CE->getArg(1);
506  if (!Arg1)
507    return;
508
509  // Get the value of the size argument.
510  DefinedOrUnknownSVal Arg1Val =
511    cast<DefinedOrUnknownSVal>(state->getSVal(Arg1));
512
513  // Compare the size argument to 0.
514  DefinedOrUnknownSVal SizeZero =
515    svalBuilder.evalEQ(state, Arg1Val,
516                       svalBuilder.makeIntValWithPtrWidth(0, false));
517
518  // If the ptr is NULL and the size is not 0, the call is equivalent to
519  // malloc(size).
520  const ProgramState *stateEqual = state->assume(PtrEQ, true);
521  if (stateEqual && state->assume(SizeZero, false)) {
522    // Hack: set the NULL symbolic region to released to suppress false warning.
523    // In the future we should add more states for allocated regions, e.g.,
524    // CheckedNull, CheckedNonNull.
525
526    SymbolRef Sym = arg0Val.getAsLocSymbol();
527    if (Sym)
528      stateEqual = stateEqual->set<RegionState>(Sym, RefState::getReleased(CE));
529
530    const ProgramState *stateMalloc = MallocMemAux(C, CE, CE->getArg(1),
531                                              UndefinedVal(), stateEqual);
532    C.addTransition(stateMalloc);
533  }
534
535  if (const ProgramState *stateNotEqual = state->assume(PtrEQ, false)) {
536    // If the size is 0, free the memory.
537    if (const ProgramState *stateSizeZero = stateNotEqual->assume(SizeZero, true))
538      if (const ProgramState *stateFree =
539          FreeMemAux(C, CE, stateSizeZero, 0, false)) {
540
541        // Bind the return value to NULL because it is now free.
542        C.addTransition(stateFree->BindExpr(CE, svalBuilder.makeNull(), true));
543      }
544    if (const ProgramState *stateSizeNotZero = stateNotEqual->assume(SizeZero,false))
545      if (const ProgramState *stateFree = FreeMemAux(C, CE, stateSizeNotZero,
546                                                0, false)) {
547        // FIXME: We should copy the content of the original buffer.
548        const ProgramState *stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
549                                                   UnknownVal(), stateFree);
550        C.addTransition(stateRealloc);
551      }
552  }
553}
554
555void MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE) {
556  const ProgramState *state = C.getState();
557  SValBuilder &svalBuilder = C.getSValBuilder();
558
559  SVal count = state->getSVal(CE->getArg(0));
560  SVal elementSize = state->getSVal(CE->getArg(1));
561  SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, count, elementSize,
562                                        svalBuilder.getContext().getSizeType());
563  SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
564
565  C.addTransition(MallocMemAux(C, CE, TotalSize, zeroVal, state));
566}
567
568void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
569                                     CheckerContext &C) const
570{
571  if (!SymReaper.hasDeadSymbols())
572    return;
573
574  const ProgramState *state = C.getState();
575  RegionStateTy RS = state->get<RegionState>();
576  RegionStateTy::Factory &F = state->get_context<RegionState>();
577
578  bool generateReport = false;
579
580  for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
581    if (SymReaper.isDead(I->first)) {
582      if (I->second.isAllocated())
583        generateReport = true;
584
585      // Remove the dead symbol from the map.
586      RS = F.remove(RS, I->first);
587
588    }
589  }
590
591  ExplodedNode *N = C.generateNode(state->set<RegionState>(RS));
592
593  // FIXME: This does not handle when we have multiple leaks at a single
594  // place.
595  if (N && generateReport) {
596    if (!BT_Leak)
597      BT_Leak.reset(new BuiltinBug("Memory leak",
598              "Allocated memory never released. Potential memory leak."));
599    // FIXME: where it is allocated.
600    BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
601    C.EmitReport(R);
602  }
603}
604
605void MallocChecker::checkEndPath(EndOfFunctionNodeBuilder &B,
606                                 ExprEngine &Eng) const {
607  const ProgramState *state = B.getState();
608  RegionStateTy M = state->get<RegionState>();
609
610  for (RegionStateTy::iterator I = M.begin(), E = M.end(); I != E; ++I) {
611    RefState RS = I->second;
612    if (RS.isAllocated()) {
613      ExplodedNode *N = B.generateNode(state);
614      if (N) {
615        if (!BT_Leak)
616          BT_Leak.reset(new BuiltinBug("Memory leak",
617                    "Allocated memory never released. Potential memory leak."));
618        BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
619        Eng.getBugReporter().EmitReport(R);
620      }
621    }
622  }
623}
624
625void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
626  const Expr *retExpr = S->getRetValue();
627  if (!retExpr)
628    return;
629
630  const ProgramState *state = C.getState();
631
632  SymbolRef Sym = state->getSVal(retExpr).getAsSymbol();
633  if (!Sym)
634    return;
635
636  const RefState *RS = state->get<RegionState>(Sym);
637  if (!RS)
638    return;
639
640  // FIXME: check other cases.
641  if (RS->isAllocated())
642    state = state->set<RegionState>(Sym, RefState::getEscaped(S));
643
644  C.addTransition(state);
645}
646
647const ProgramState *MallocChecker::evalAssume(const ProgramState *state, SVal Cond,
648                                         bool Assumption) const {
649  // If a symblic region is assumed to NULL, set its state to AllocateFailed.
650  // FIXME: should also check symbols assumed to non-null.
651
652  RegionStateTy RS = state->get<RegionState>();
653
654  for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
655    // If the symbol is assumed to NULL, this will return an APSInt*.
656    if (state->getSymVal(I.getKey()))
657      state = state->set<RegionState>(I.getKey(),RefState::getAllocateFailed());
658  }
659
660  return state;
661}
662
663// Check if the location is a freed symbolic region.
664void MallocChecker::checkLocation(SVal l, bool isLoad,CheckerContext &C) const {
665  SymbolRef Sym = l.getLocSymbolInBase();
666  if (Sym) {
667    const RefState *RS = C.getState()->get<RegionState>(Sym);
668    if (RS && RS->isReleased()) {
669      if (ExplodedNode *N = C.generateNode()) {
670        if (!BT_UseFree)
671          BT_UseFree.reset(new BuiltinBug("Use dynamically allocated memory "
672                                          "after it is freed."));
673
674        BugReport *R = new BugReport(*BT_UseFree, BT_UseFree->getDescription(),
675                                     N);
676        C.EmitReport(R);
677      }
678    }
679  }
680}
681
682void MallocChecker::checkBind(SVal location, SVal val,CheckerContext &C) const {
683  // The PreVisitBind implements the same algorithm as already used by the
684  // Objective C ownership checker: if the pointer escaped from this scope by
685  // assignment, let it go.  However, assigning to fields of a stack-storage
686  // structure does not transfer ownership.
687
688  const ProgramState *state = C.getState();
689  DefinedOrUnknownSVal l = cast<DefinedOrUnknownSVal>(location);
690
691  // Check for null dereferences.
692  if (!isa<Loc>(l))
693    return;
694
695  // Before checking if the state is null, check if 'val' has a RefState.
696  // Only then should we check for null and bifurcate the state.
697  SymbolRef Sym = val.getLocSymbolInBase();
698  if (Sym) {
699    if (const RefState *RS = state->get<RegionState>(Sym)) {
700      // If ptr is NULL, no operation is performed.
701      const ProgramState *notNullState, *nullState;
702      llvm::tie(notNullState, nullState) = state->assume(l);
703
704      // Generate a transition for 'nullState' to record the assumption
705      // that the state was null.
706      if (nullState)
707        C.addTransition(nullState);
708
709      if (!notNullState)
710        return;
711
712      if (RS->isAllocated()) {
713        // Something we presently own is being assigned somewhere.
714        const MemRegion *AR = location.getAsRegion();
715        if (!AR)
716          return;
717        AR = AR->StripCasts()->getBaseRegion();
718        do {
719          // If it is on the stack, we still own it.
720          if (AR->hasStackNonParametersStorage())
721            break;
722
723          // If the state can't represent this binding, we still own it.
724          if (notNullState == (notNullState->bindLoc(cast<Loc>(location),
725                                                     UnknownVal())))
726            break;
727
728          // We no longer own this pointer.
729          notNullState =
730            notNullState->set<RegionState>(Sym,
731                                        RefState::getRelinquished(C.getStmt()));
732        }
733        while (false);
734      }
735      C.addTransition(notNullState);
736    }
737  }
738}
739
740void ento::registerMallocChecker(CheckerManager &mgr) {
741  mgr.registerChecker<MallocChecker>();
742}
743