blob: 82a1aa22579c1fea27b8be3b103c0d65d2dd648a [file] [log] [blame]
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001//=== MallocChecker.cpp - A malloc/free checker -------------------*- C++ -*--//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines malloc/free checker, which checks for potential memory
11// leaks, double free, and use-after-free problems.
12//
13//===----------------------------------------------------------------------===//
14
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +000015#include "ClangSACheckers.h"
Anna Zakse56167e2012-02-17 22:35:31 +000016#include "InterCheckerAPI.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000017#include "clang/AST/Attr.h"
18#include "clang/Basic/SourceManager.h"
19#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
Argyrios Kyrtzidis6a5674f2011-03-01 01:16:21 +000020#include "clang/StaticAnalyzer/Core/Checker.h"
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +000021#include "clang/StaticAnalyzer/Core/CheckerManager.h"
Jordan Rose4f7df9b2012-07-26 21:39:41 +000022#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000023#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
Ted Kremenek001fd5b2011-08-15 22:09:50 +000024#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
25#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
Ted Kremenekf8cbac42011-02-10 01:03:03 +000026#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
Zhongxing Xu88cca6b2009-11-12 08:38:56 +000027#include "llvm/ADT/ImmutableMap.h"
Benjamin Kramer3307c5082012-02-04 12:31:12 +000028#include "llvm/ADT/STLExtras.h"
Benjamin Kramerea70eb32012-12-01 15:09:41 +000029#include "llvm/ADT/SmallString.h"
Jordan Rosec102b352012-09-22 01:24:42 +000030#include "llvm/ADT/StringExtras.h"
Anna Zaks199e8e52012-02-22 03:14:20 +000031#include <climits>
32
Zhongxing Xu88cca6b2009-11-12 08:38:56 +000033using namespace clang;
Ted Kremenek98857c92010-12-23 07:20:52 +000034using namespace ento;
Zhongxing Xu88cca6b2009-11-12 08:38:56 +000035
36namespace {
37
Anton Yartsev05789592013-03-28 17:05:19 +000038// Used to check correspondence between allocators and deallocators.
39enum AllocationFamily {
40 AF_None,
41 AF_Malloc,
42 AF_CXXNew,
43 AF_CXXNewArray
44};
45
Zhongxing Xu1239de12009-12-11 00:55:44 +000046class RefState {
Anna Zaks9050ffd2012-06-20 20:57:46 +000047 enum Kind { // Reference to allocated memory.
48 Allocated,
49 // Reference to released/freed memory.
50 Released,
Alp Toker5faf0c02013-12-02 03:50:25 +000051 // The responsibility for freeing resources has transferred from
Anna Zaks9050ffd2012-06-20 20:57:46 +000052 // this reference. A relinquished symbol should not be freed.
Anna Zaks93a21a82013-04-09 00:30:28 +000053 Relinquished,
54 // We are no longer guaranteed to have observed all manipulations
55 // of this pointer/memory. For example, it could have been
56 // passed as a parameter to an opaque function.
57 Escaped
58 };
Anton Yartsev05789592013-03-28 17:05:19 +000059
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000060 const Stmt *S;
Anton Yartsev05789592013-03-28 17:05:19 +000061 unsigned K : 2; // Kind enum, but stored as a bitfield.
62 unsigned Family : 30; // Rest of 32-bit word, currently just an allocation
63 // family.
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000064
Anton Yartsev05789592013-03-28 17:05:19 +000065 RefState(Kind k, const Stmt *s, unsigned family)
Anna Zaks93a21a82013-04-09 00:30:28 +000066 : S(s), K(k), Family(family) {
67 assert(family != AF_None);
68 }
Zhongxing Xu1239de12009-12-11 00:55:44 +000069public:
Anna Zaks9050ffd2012-06-20 20:57:46 +000070 bool isAllocated() const { return K == Allocated; }
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000071 bool isReleased() const { return K == Released; }
Anna Zaks9050ffd2012-06-20 20:57:46 +000072 bool isRelinquished() const { return K == Relinquished; }
Anna Zaks93a21a82013-04-09 00:30:28 +000073 bool isEscaped() const { return K == Escaped; }
74 AllocationFamily getAllocationFamily() const {
Anton Yartsev05789592013-03-28 17:05:19 +000075 return (AllocationFamily)Family;
76 }
Anna Zaksd56c8792012-02-13 18:05:39 +000077 const Stmt *getStmt() const { return S; }
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000078
79 bool operator==(const RefState &X) const {
Anton Yartsev05789592013-03-28 17:05:19 +000080 return K == X.K && S == X.S && Family == X.Family;
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000081 }
82
Anton Yartsev05789592013-03-28 17:05:19 +000083 static RefState getAllocated(unsigned family, const Stmt *s) {
84 return RefState(Allocated, s, family);
Zhongxing Xub0e15df2009-12-31 06:13:07 +000085 }
Anton Yartsev05789592013-03-28 17:05:19 +000086 static RefState getReleased(unsigned family, const Stmt *s) {
87 return RefState(Released, s, family);
88 }
89 static RefState getRelinquished(unsigned family, const Stmt *s) {
90 return RefState(Relinquished, s, family);
Ted Kremenek0bbf24d2010-08-06 21:12:55 +000091 }
Anna Zaks93a21a82013-04-09 00:30:28 +000092 static RefState getEscaped(const RefState *RS) {
93 return RefState(Escaped, RS->getStmt(), RS->getAllocationFamily());
94 }
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000095
96 void Profile(llvm::FoldingSetNodeID &ID) const {
97 ID.AddInteger(K);
98 ID.AddPointer(S);
Anton Yartsev05789592013-03-28 17:05:19 +000099 ID.AddInteger(Family);
Zhongxing Xu4668c7e2009-11-17 07:54:15 +0000100 }
Ted Kremenek6fcefb52013-01-03 01:30:12 +0000101
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000102 void dump(raw_ostream &OS) const {
Craig Topperd6d31ac2013-07-15 08:24:27 +0000103 static const char *const Table[] = {
Ted Kremenek6fcefb52013-01-03 01:30:12 +0000104 "Allocated",
105 "Released",
106 "Relinquished"
107 };
108 OS << Table[(unsigned) K];
109 }
110
Alp Tokeref6b0072014-01-04 13:47:14 +0000111 LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); }
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000112};
113
Anna Zaks75cfbb62012-09-12 22:57:34 +0000114enum ReallocPairKind {
115 RPToBeFreedAfterFailure,
116 // The symbol has been freed when reallocation failed.
117 RPIsFreeOnFailure,
118 // The symbol does not need to be freed after reallocation fails.
119 RPDoNotTrackAfterFailure
120};
121
Anna Zaksfe6eb672012-08-24 02:28:20 +0000122/// \class ReallocPair
123/// \brief Stores information about the symbol being reallocated by a call to
124/// 'realloc' to allow modeling failed reallocation later in the path.
Anna Zaksac068142012-02-15 00:11:25 +0000125struct ReallocPair {
Anna Zaksfe6eb672012-08-24 02:28:20 +0000126 // \brief The symbol which realloc reallocated.
Anna Zaksac068142012-02-15 00:11:25 +0000127 SymbolRef ReallocatedSym;
Anna Zaks75cfbb62012-09-12 22:57:34 +0000128 ReallocPairKind Kind;
Anna Zaksfe6eb672012-08-24 02:28:20 +0000129
Anna Zaks75cfbb62012-09-12 22:57:34 +0000130 ReallocPair(SymbolRef S, ReallocPairKind K) :
131 ReallocatedSym(S), Kind(K) {}
Anna Zaksac068142012-02-15 00:11:25 +0000132 void Profile(llvm::FoldingSetNodeID &ID) const {
Anna Zaks75cfbb62012-09-12 22:57:34 +0000133 ID.AddInteger(Kind);
Anna Zaksac068142012-02-15 00:11:25 +0000134 ID.AddPointer(ReallocatedSym);
135 }
136 bool operator==(const ReallocPair &X) const {
137 return ReallocatedSym == X.ReallocatedSym &&
Anna Zaks75cfbb62012-09-12 22:57:34 +0000138 Kind == X.Kind;
Anna Zaksac068142012-02-15 00:11:25 +0000139 }
140};
141
Anna Zaksa043d0c2013-01-08 00:25:29 +0000142typedef std::pair<const ExplodedNode*, const MemRegion*> LeakInfo;
Anna Zaksfc2e1532012-03-21 19:45:08 +0000143
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000144class MallocChecker : public Checker<check::DeadSymbols,
Anna Zaksdc154152012-12-20 00:38:25 +0000145 check::PointerEscape,
Anna Zaks333481b2013-03-28 23:15:29 +0000146 check::ConstPointerEscape,
Ted Kremenek778d2bb2012-01-04 23:48:37 +0000147 check::PreStmt<ReturnStmt>,
Anton Yartsevcb2ccd62013-04-10 22:21:41 +0000148 check::PreCall,
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000149 check::PostStmt<CallExpr>,
Anton Yartsev13df0362013-03-25 01:35:45 +0000150 check::PostStmt<CXXNewExpr>,
151 check::PreStmt<CXXDeleteExpr>,
Anna Zaks9fe80982012-03-22 00:57:20 +0000152 check::PostStmt<BlockExpr>,
Anna Zaks67291b92012-11-13 03:18:01 +0000153 check::PostObjCMessage,
Ted Kremenek778d2bb2012-01-04 23:48:37 +0000154 check::Location,
Anna Zaksdc154152012-12-20 00:38:25 +0000155 eval::Assume>
Ted Kremenek778d2bb2012-01-04 23:48:37 +0000156{
Anna Zaks546c49c2012-02-16 22:26:12 +0000157 mutable OwningPtr<BugType> BT_DoubleFree;
158 mutable OwningPtr<BugType> BT_Leak;
159 mutable OwningPtr<BugType> BT_UseFree;
160 mutable OwningPtr<BugType> BT_BadFree;
Anton Yartseve3377fb2013-04-04 23:46:29 +0000161 mutable OwningPtr<BugType> BT_MismatchedDealloc;
Anna Zaksc89ad072013-02-07 23:05:47 +0000162 mutable OwningPtr<BugType> BT_OffsetFree;
Anna Zaksd5157482012-02-15 00:11:22 +0000163 mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc,
Anna Zaks199e8e52012-02-22 03:14:20 +0000164 *II_valloc, *II_reallocf, *II_strndup, *II_strdup;
165
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000166public:
Anna Zaksd5157482012-02-15 00:11:22 +0000167 MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0),
Anna Zaks199e8e52012-02-22 03:14:20 +0000168 II_valloc(0), II_reallocf(0), II_strndup(0), II_strdup(0) {}
Anna Zakscd37bf42012-02-08 23:16:52 +0000169
170 /// In pessimistic mode, the checker assumes that it does not know which
171 /// functions might free the memory.
172 struct ChecksFilter {
173 DefaultBool CMallocPessimistic;
174 DefaultBool CMallocOptimistic;
Anton Yartsev13df0362013-03-25 01:35:45 +0000175 DefaultBool CNewDeleteChecker;
Jordan Rose26330562013-04-05 17:55:00 +0000176 DefaultBool CNewDeleteLeaksChecker;
Anton Yartsev05789592013-03-28 17:05:19 +0000177 DefaultBool CMismatchedDeallocatorChecker;
Anna Zakscd37bf42012-02-08 23:16:52 +0000178 };
179
180 ChecksFilter Filter;
181
Anton Yartsevcb2ccd62013-04-10 22:21:41 +0000182 void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000183 void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
Anton Yartsev13df0362013-03-25 01:35:45 +0000184 void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const;
185 void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
Anna Zaks67291b92012-11-13 03:18:01 +0000186 void checkPostObjCMessage(const ObjCMethodCall &Call, CheckerContext &C) const;
Anna Zaks9fe80982012-03-22 00:57:20 +0000187 void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +0000188 void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +0000189 void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
Ted Kremenek49b1e382012-01-26 21:29:00 +0000190 ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +0000191 bool Assumption) const;
Anna Zaks3e0f4152011-10-06 00:43:15 +0000192 void checkLocation(SVal l, bool isLoad, const Stmt *S,
193 CheckerContext &C) const;
Anna Zaksdc154152012-12-20 00:38:25 +0000194
195 ProgramStateRef checkPointerEscape(ProgramStateRef State,
196 const InvalidatedSymbols &Escaped,
Anna Zaksacdc13c2013-02-07 23:05:43 +0000197 const CallEvent *Call,
198 PointerEscapeKind Kind) const;
Anna Zaks333481b2013-03-28 23:15:29 +0000199 ProgramStateRef checkConstPointerEscape(ProgramStateRef State,
200 const InvalidatedSymbols &Escaped,
201 const CallEvent *Call,
202 PointerEscapeKind Kind) const;
Zhongxing Xub0e15df2009-12-31 06:13:07 +0000203
Anna Zaks263b7e02012-05-02 00:05:20 +0000204 void printState(raw_ostream &Out, ProgramStateRef State,
205 const char *NL, const char *Sep) const;
206
Zhongxing Xuc4902a52009-11-13 07:25:27 +0000207private:
Anna Zaks3d348342012-02-14 21:55:24 +0000208 void initIdentifierInfo(ASTContext &C) const;
209
Anton Yartsev05789592013-03-28 17:05:19 +0000210 /// \brief Determine family of a deallocation expression.
Anton Yartseve3377fb2013-04-04 23:46:29 +0000211 AllocationFamily getAllocationFamily(CheckerContext &C, const Stmt *S) const;
Anton Yartsev05789592013-03-28 17:05:19 +0000212
213 /// \brief Print names of allocators and deallocators.
214 ///
215 /// \returns true on success.
216 bool printAllocDeallocName(raw_ostream &os, CheckerContext &C,
217 const Expr *E) const;
218
219 /// \brief Print expected name of an allocator based on the deallocator's
220 /// family derived from the DeallocExpr.
221 void printExpectedAllocName(raw_ostream &os, CheckerContext &C,
222 const Expr *DeallocExpr) const;
223 /// \brief Print expected name of a deallocator based on the allocator's
224 /// family.
225 void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) const;
226
Jordan Rose613f3c02013-03-09 00:59:10 +0000227 ///@{
Anna Zaks3d348342012-02-14 21:55:24 +0000228 /// Check if this is one of the functions which can allocate/reallocate memory
229 /// pointed to by one of its arguments.
230 bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const;
Anna Zaks46d01602012-05-18 01:16:10 +0000231 bool isFreeFunction(const FunctionDecl *FD, ASTContext &C) const;
232 bool isAllocationFunction(const FunctionDecl *FD, ASTContext &C) const;
Anton Yartsev13df0362013-03-25 01:35:45 +0000233 bool isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const;
Jordan Rose613f3c02013-03-09 00:59:10 +0000234 ///@}
Richard Smith852e9ce2013-11-27 01:46:48 +0000235 ProgramStateRef MallocMemReturnsAttr(CheckerContext &C,
236 const CallExpr *CE,
237 const OwnershipAttr* Att) const;
Ted Kremenek49b1e382012-01-26 21:29:00 +0000238 static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +0000239 const Expr *SizeEx, SVal Init,
Anton Yartsev05789592013-03-28 17:05:19 +0000240 ProgramStateRef State,
241 AllocationFamily Family = AF_Malloc) {
Ted Kremenek632e3b72012-01-06 22:09:28 +0000242 return MallocMemAux(C, CE,
Anton Yartsev05789592013-03-28 17:05:19 +0000243 State->getSVal(SizeEx, C.getLocationContext()),
244 Init, State, Family);
Zhongxing Xu527ff6d2010-06-01 03:01:33 +0000245 }
Anna Zaks40a7eb32012-02-22 19:24:52 +0000246
Ted Kremenek49b1e382012-01-26 21:29:00 +0000247 static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +0000248 SVal SizeEx, SVal Init,
Anton Yartsev05789592013-03-28 17:05:19 +0000249 ProgramStateRef State,
250 AllocationFamily Family = AF_Malloc);
Zhongxing Xu527ff6d2010-06-01 03:01:33 +0000251
Anna Zaks40a7eb32012-02-22 19:24:52 +0000252 /// Update the RefState to reflect the new memory allocation.
Anton Yartsev05789592013-03-28 17:05:19 +0000253 static ProgramStateRef
254 MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State,
255 AllocationFamily Family = AF_Malloc);
Anna Zaks40a7eb32012-02-22 19:24:52 +0000256
257 ProgramStateRef FreeMemAttr(CheckerContext &C, const CallExpr *CE,
258 const OwnershipAttr* Att) const;
Ted Kremenek49b1e382012-01-26 21:29:00 +0000259 ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE,
Anna Zaks0d6989b2012-06-22 02:04:31 +0000260 ProgramStateRef state, unsigned Num,
Anna Zaksfe6eb672012-08-24 02:28:20 +0000261 bool Hold,
Anna Zaks67291b92012-11-13 03:18:01 +0000262 bool &ReleasedAllocated,
263 bool ReturnsNullOnFailure = false) const;
Anna Zaks0d6989b2012-06-22 02:04:31 +0000264 ProgramStateRef FreeMemAux(CheckerContext &C, const Expr *Arg,
265 const Expr *ParentExpr,
Anna Zaks67291b92012-11-13 03:18:01 +0000266 ProgramStateRef State,
Anna Zaksfe6eb672012-08-24 02:28:20 +0000267 bool Hold,
Anna Zaks67291b92012-11-13 03:18:01 +0000268 bool &ReleasedAllocated,
269 bool ReturnsNullOnFailure = false) const;
Zhongxing Xuc0484fa2009-12-12 12:29:38 +0000270
Anna Zaks40a7eb32012-02-22 19:24:52 +0000271 ProgramStateRef ReallocMem(CheckerContext &C, const CallExpr *CE,
272 bool FreesMemOnFailure) const;
273 static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE);
Jordy Rose3597b212010-06-07 19:32:37 +0000274
Anna Zaks46d01602012-05-18 01:16:10 +0000275 ///\brief Check if the memory associated with this symbol was released.
276 bool isReleased(SymbolRef Sym, CheckerContext &C) const;
277
Anton Yartsev13df0362013-03-25 01:35:45 +0000278 bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const;
Anna Zaksa1b227b2012-02-08 23:16:56 +0000279
Anna Zaksa4bc5e12013-05-31 23:47:32 +0000280 /// Check if the function is known free memory, or if it is
Jordan Rose613f3c02013-03-09 00:59:10 +0000281 /// "interesting" and should be modeled explicitly.
282 ///
Anna Zaks8ebeb642013-06-08 00:29:29 +0000283 /// \param [out] EscapingSymbol A function might not free memory in general,
284 /// but could be known to free a particular symbol. In this case, false is
Anna Zaksa4bc5e12013-05-31 23:47:32 +0000285 /// returned and the single escaping symbol is returned through the out
286 /// parameter.
287 ///
Jordan Rose613f3c02013-03-09 00:59:10 +0000288 /// We assume that pointers do not escape through calls to system functions
289 /// not handled by this checker.
Anna Zaks8ebeb642013-06-08 00:29:29 +0000290 bool mayFreeAnyEscapedMemoryOrIsModeledExplicitly(const CallEvent *Call,
Anna Zaksa4bc5e12013-05-31 23:47:32 +0000291 ProgramStateRef State,
292 SymbolRef &EscapingSymbol) const;
Anna Zaks3d348342012-02-14 21:55:24 +0000293
Anna Zaks333481b2013-03-28 23:15:29 +0000294 // Implementation of the checkPointerEscape callabcks.
295 ProgramStateRef checkPointerEscapeAux(ProgramStateRef State,
296 const InvalidatedSymbols &Escaped,
297 const CallEvent *Call,
298 PointerEscapeKind Kind,
299 bool(*CheckRefState)(const RefState*)) const;
300
Anton Yartsev1e2bc9b2013-04-11 00:05:20 +0000301 ///@{
302 /// Tells if a given family/call/symbol is tracked by the current checker.
303 bool isTrackedByCurrentChecker(AllocationFamily Family) const;
304 bool isTrackedByCurrentChecker(CheckerContext &C,
305 const Stmt *AllocDeallocStmt) const;
306 bool isTrackedByCurrentChecker(CheckerContext &C, SymbolRef Sym) const;
307 ///@}
Ted Kremenek5ef32db2011-08-12 23:37:29 +0000308 static bool SummarizeValue(raw_ostream &os, SVal V);
309 static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
Anton Yartsev05789592013-03-28 17:05:19 +0000310 void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
311 const Expr *DeallocExpr) const;
Anton Yartseve3377fb2013-04-04 23:46:29 +0000312 void ReportMismatchedDealloc(CheckerContext &C, SourceRange Range,
Anton Yartsevf0593d62013-04-05 11:25:10 +0000313 const Expr *DeallocExpr, const RefState *RS,
Anton Yartsevf5bccce2013-09-16 17:51:25 +0000314 SymbolRef Sym, bool OwnershipTransferred) const;
Anton Yartsev05789592013-03-28 17:05:19 +0000315 void ReportOffsetFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
316 const Expr *DeallocExpr,
317 const Expr *AllocExpr = 0) const;
Anton Yartsev59ed15b2013-03-13 14:39:10 +0000318 void ReportUseAfterFree(CheckerContext &C, SourceRange Range,
319 SymbolRef Sym) const;
320 void ReportDoubleFree(CheckerContext &C, SourceRange Range, bool Released,
Anton Yartsev6c2af432013-03-13 17:07:32 +0000321 SymbolRef Sym, SymbolRef PrevSym) const;
Anna Zaks2b5bb972012-02-09 06:25:51 +0000322
Anna Zaksdf901a42012-02-23 21:38:21 +0000323 /// Find the location of the allocation for Sym on the path leading to the
324 /// exploded node N.
Anna Zaksfc2e1532012-03-21 19:45:08 +0000325 LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
326 CheckerContext &C) const;
Anna Zaksdf901a42012-02-23 21:38:21 +0000327
Anna Zaksd3571e5a2012-02-11 21:02:40 +0000328 void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const;
329
Anna Zaks2b5bb972012-02-09 06:25:51 +0000330 /// The bug visitor which allows us to print extra diagnostics along the
331 /// BugReport path. For example, showing the allocation site of the leaked
332 /// region.
Jordy Rosef78877e2012-03-24 02:45:35 +0000333 class MallocBugVisitor : public BugReporterVisitorImpl<MallocBugVisitor> {
Anna Zaks2b5bb972012-02-09 06:25:51 +0000334 protected:
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000335 enum NotificationMode {
336 Normal,
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000337 ReallocationFailed
338 };
339
Anna Zaks2b5bb972012-02-09 06:25:51 +0000340 // The allocated region symbol tracked by the main analysis.
341 SymbolRef Sym;
342
Anna Zaks62cce9e2012-05-10 01:37:40 +0000343 // The mode we are in, i.e. what kind of diagnostics will be emitted.
344 NotificationMode Mode;
Jordy Rose21ff76e2012-03-24 03:15:09 +0000345
Anna Zaks62cce9e2012-05-10 01:37:40 +0000346 // A symbol from when the primary region should have been reallocated.
347 SymbolRef FailedReallocSymbol;
Jordy Rose21ff76e2012-03-24 03:15:09 +0000348
Anna Zaks62cce9e2012-05-10 01:37:40 +0000349 bool IsLeak;
350
351 public:
352 MallocBugVisitor(SymbolRef S, bool isLeak = false)
353 : Sym(S), Mode(Normal), FailedReallocSymbol(0), IsLeak(isLeak) {}
Jordy Rose21ff76e2012-03-24 03:15:09 +0000354
Anna Zaks2b5bb972012-02-09 06:25:51 +0000355 virtual ~MallocBugVisitor() {}
356
357 void Profile(llvm::FoldingSetNodeID &ID) const {
358 static int X = 0;
359 ID.AddPointer(&X);
360 ID.AddPointer(Sym);
361 }
362
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000363 inline bool isAllocated(const RefState *S, const RefState *SPrev,
364 const Stmt *Stmt) {
Anna Zaks2b5bb972012-02-09 06:25:51 +0000365 // Did not track -> allocated. Other state (released) -> allocated.
Anton Yartsev13df0362013-03-25 01:35:45 +0000366 return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXNewExpr>(Stmt)) &&
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000367 (S && S->isAllocated()) && (!SPrev || !SPrev->isAllocated()));
Anna Zaks2b5bb972012-02-09 06:25:51 +0000368 }
369
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000370 inline bool isReleased(const RefState *S, const RefState *SPrev,
371 const Stmt *Stmt) {
Anna Zaks2b5bb972012-02-09 06:25:51 +0000372 // Did not track -> released. Other state (allocated) -> released.
Anton Yartsev13df0362013-03-25 01:35:45 +0000373 return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXDeleteExpr>(Stmt)) &&
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000374 (S && S->isReleased()) && (!SPrev || !SPrev->isReleased()));
375 }
376
Anna Zaks0d6989b2012-06-22 02:04:31 +0000377 inline bool isRelinquished(const RefState *S, const RefState *SPrev,
378 const Stmt *Stmt) {
379 // Did not track -> relinquished. Other state (allocated) -> relinquished.
380 return (Stmt && (isa<CallExpr>(Stmt) || isa<ObjCMessageExpr>(Stmt) ||
381 isa<ObjCPropertyRefExpr>(Stmt)) &&
382 (S && S->isRelinquished()) &&
383 (!SPrev || !SPrev->isRelinquished()));
384 }
385
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000386 inline bool isReallocFailedCheck(const RefState *S, const RefState *SPrev,
387 const Stmt *Stmt) {
388 // If the expression is not a call, and the state change is
389 // released -> allocated, it must be the realloc return value
390 // check. If we have to handle more cases here, it might be cleaner just
391 // to track this extra bit in the state itself.
392 return ((!Stmt || !isa<CallExpr>(Stmt)) &&
393 (S && S->isAllocated()) && (SPrev && !SPrev->isAllocated()));
Anna Zaks2b5bb972012-02-09 06:25:51 +0000394 }
395
396 PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
397 const ExplodedNode *PrevN,
398 BugReporterContext &BRC,
399 BugReport &BR);
Anna Zaks62cce9e2012-05-10 01:37:40 +0000400
401 PathDiagnosticPiece* getEndPath(BugReporterContext &BRC,
402 const ExplodedNode *EndPathNode,
403 BugReport &BR) {
404 if (!IsLeak)
405 return 0;
406
407 PathDiagnosticLocation L =
408 PathDiagnosticLocation::createEndOfPath(EndPathNode,
409 BRC.getSourceManager());
410 // Do not add the statement itself as a range in case of leak.
411 return new PathDiagnosticEventPiece(L, BR.getDescription(), false);
412 }
413
Anna Zakscba4f292012-03-16 23:24:20 +0000414 private:
415 class StackHintGeneratorForReallocationFailed
416 : public StackHintGeneratorForSymbol {
417 public:
418 StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M)
419 : StackHintGeneratorForSymbol(S, M) {}
420
421 virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex) {
Jordan Rosec102b352012-09-22 01:24:42 +0000422 // Printed parameters start at 1, not 0.
423 ++ArgIndex;
424
Anna Zakscba4f292012-03-16 23:24:20 +0000425 SmallString<200> buf;
426 llvm::raw_svector_ostream os(buf);
427
Jordan Rosec102b352012-09-22 01:24:42 +0000428 os << "Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex)
429 << " parameter failed";
Anna Zakscba4f292012-03-16 23:24:20 +0000430
431 return os.str();
432 }
433
434 virtual std::string getMessageForReturn(const CallExpr *CallExpr) {
Anna Zaksa7f457a2012-03-16 23:44:28 +0000435 return "Reallocation of returned value failed";
Anna Zakscba4f292012-03-16 23:24:20 +0000436 }
437 };
Anna Zaks2b5bb972012-02-09 06:25:51 +0000438 };
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000439};
Kovarththanan Rajaratnam65c65662009-11-28 06:07:30 +0000440} // end anonymous namespace
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000441
Jordan Rose0c153cb2012-11-02 01:54:06 +0000442REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState)
443REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair)
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000444
Anna Zaks67291b92012-11-13 03:18:01 +0000445// A map from the freed symbol to the symbol representing the return value of
446// the free function.
447REGISTER_MAP_WITH_PROGRAMSTATE(FreeReturnValue, SymbolRef, SymbolRef)
448
Anna Zaksbb1ef902012-02-11 21:02:35 +0000449namespace {
450class StopTrackingCallback : public SymbolVisitor {
451 ProgramStateRef state;
452public:
453 StopTrackingCallback(ProgramStateRef st) : state(st) {}
454 ProgramStateRef getState() const { return state; }
455
456 bool VisitSymbol(SymbolRef sym) {
457 state = state->remove<RegionState>(sym);
458 return true;
459 }
460};
461} // end anonymous namespace
462
Anna Zaks3d348342012-02-14 21:55:24 +0000463void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const {
Anna Zaksb3436602012-05-18 22:47:40 +0000464 if (II_malloc)
465 return;
466 II_malloc = &Ctx.Idents.get("malloc");
467 II_free = &Ctx.Idents.get("free");
468 II_realloc = &Ctx.Idents.get("realloc");
469 II_reallocf = &Ctx.Idents.get("reallocf");
470 II_calloc = &Ctx.Idents.get("calloc");
471 II_valloc = &Ctx.Idents.get("valloc");
472 II_strdup = &Ctx.Idents.get("strdup");
473 II_strndup = &Ctx.Idents.get("strndup");
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000474}
475
Anna Zaks3d348342012-02-14 21:55:24 +0000476bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const {
Anna Zaks46d01602012-05-18 01:16:10 +0000477 if (isFreeFunction(FD, C))
478 return true;
479
480 if (isAllocationFunction(FD, C))
481 return true;
482
Anton Yartsev13df0362013-03-25 01:35:45 +0000483 if (isStandardNewDelete(FD, C))
484 return true;
485
Anna Zaks46d01602012-05-18 01:16:10 +0000486 return false;
487}
488
489bool MallocChecker::isAllocationFunction(const FunctionDecl *FD,
490 ASTContext &C) const {
Anna Zaksd1ff1cb2012-02-15 02:12:00 +0000491 if (!FD)
492 return false;
Anna Zaks46d01602012-05-18 01:16:10 +0000493
Jordan Rose6cd16c52012-07-10 23:13:01 +0000494 if (FD->getKind() == Decl::Function) {
495 IdentifierInfo *FunI = FD->getIdentifier();
496 initIdentifierInfo(C);
Anna Zaks3d348342012-02-14 21:55:24 +0000497
Jordan Rose6cd16c52012-07-10 23:13:01 +0000498 if (FunI == II_malloc || FunI == II_realloc ||
499 FunI == II_reallocf || FunI == II_calloc || FunI == II_valloc ||
500 FunI == II_strdup || FunI == II_strndup)
501 return true;
502 }
Anna Zaks3d348342012-02-14 21:55:24 +0000503
Anna Zaks46d01602012-05-18 01:16:10 +0000504 if (Filter.CMallocOptimistic && FD->hasAttrs())
505 for (specific_attr_iterator<OwnershipAttr>
506 i = FD->specific_attr_begin<OwnershipAttr>(),
507 e = FD->specific_attr_end<OwnershipAttr>();
508 i != e; ++i)
509 if ((*i)->getOwnKind() == OwnershipAttr::Returns)
510 return true;
511 return false;
512}
513
514bool MallocChecker::isFreeFunction(const FunctionDecl *FD, ASTContext &C) const {
515 if (!FD)
516 return false;
517
Jordan Rose6cd16c52012-07-10 23:13:01 +0000518 if (FD->getKind() == Decl::Function) {
519 IdentifierInfo *FunI = FD->getIdentifier();
520 initIdentifierInfo(C);
Anna Zaks46d01602012-05-18 01:16:10 +0000521
Jordan Rose6cd16c52012-07-10 23:13:01 +0000522 if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf)
523 return true;
524 }
Anna Zaks3d348342012-02-14 21:55:24 +0000525
Anna Zaks46d01602012-05-18 01:16:10 +0000526 if (Filter.CMallocOptimistic && FD->hasAttrs())
527 for (specific_attr_iterator<OwnershipAttr>
528 i = FD->specific_attr_begin<OwnershipAttr>(),
529 e = FD->specific_attr_end<OwnershipAttr>();
530 i != e; ++i)
531 if ((*i)->getOwnKind() == OwnershipAttr::Takes ||
532 (*i)->getOwnKind() == OwnershipAttr::Holds)
533 return true;
Anna Zaks3d348342012-02-14 21:55:24 +0000534 return false;
535}
536
Anton Yartsev8b662702013-03-28 16:10:38 +0000537// Tells if the callee is one of the following:
538// 1) A global non-placement new/delete operator function.
539// 2) A global placement operator function with the single placement argument
540// of type std::nothrow_t.
Anton Yartsev13df0362013-03-25 01:35:45 +0000541bool MallocChecker::isStandardNewDelete(const FunctionDecl *FD,
542 ASTContext &C) const {
543 if (!FD)
544 return false;
545
546 OverloadedOperatorKind Kind = FD->getOverloadedOperator();
547 if (Kind != OO_New && Kind != OO_Array_New &&
548 Kind != OO_Delete && Kind != OO_Array_Delete)
549 return false;
550
Anton Yartsev8b662702013-03-28 16:10:38 +0000551 // Skip all operator new/delete methods.
552 if (isa<CXXMethodDecl>(FD))
Anton Yartsev13df0362013-03-25 01:35:45 +0000553 return false;
554
555 // Return true if tested operator is a standard placement nothrow operator.
556 if (FD->getNumParams() == 2) {
557 QualType T = FD->getParamDecl(1)->getType();
558 if (const IdentifierInfo *II = T.getBaseTypeIdentifier())
559 return II->getName().equals("nothrow_t");
560 }
561
562 // Skip placement operators.
563 if (FD->getNumParams() != 1 || FD->isVariadic())
564 return false;
565
566 // One of the standard new/new[]/delete/delete[] non-placement operators.
567 return true;
568}
569
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000570void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
Jordan Rosed6e5fd52012-09-20 01:55:32 +0000571 if (C.wasInlined)
572 return;
573
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000574 const FunctionDecl *FD = C.getCalleeDecl(CE);
575 if (!FD)
576 return;
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000577
Anna Zaks40a7eb32012-02-22 19:24:52 +0000578 ProgramStateRef State = C.getState();
Anna Zaksfe6eb672012-08-24 02:28:20 +0000579 bool ReleasedAllocatedMemory = false;
Jordan Rose6cd16c52012-07-10 23:13:01 +0000580
581 if (FD->getKind() == Decl::Function) {
582 initIdentifierInfo(C.getASTContext());
583 IdentifierInfo *FunI = FD->getIdentifier();
584
Anton Yartseve3377fb2013-04-04 23:46:29 +0000585 if (FunI == II_malloc || FunI == II_valloc) {
586 if (CE->getNumArgs() < 1)
587 return;
588 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
589 } else if (FunI == II_realloc) {
590 State = ReallocMem(C, CE, false);
591 } else if (FunI == II_reallocf) {
592 State = ReallocMem(C, CE, true);
593 } else if (FunI == II_calloc) {
594 State = CallocMem(C, CE);
595 } else if (FunI == II_free) {
596 State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
597 } else if (FunI == II_strdup) {
598 State = MallocUpdateRefState(C, CE, State);
599 } else if (FunI == II_strndup) {
600 State = MallocUpdateRefState(C, CE, State);
Anton Yartsev13df0362013-03-25 01:35:45 +0000601 }
Anton Yartseve3377fb2013-04-04 23:46:29 +0000602 else if (isStandardNewDelete(FD, C.getASTContext())) {
603 // Process direct calls to operator new/new[]/delete/delete[] functions
604 // as distinct from new/new[]/delete/delete[] expressions that are
605 // processed by the checkPostStmt callbacks for CXXNewExpr and
606 // CXXDeleteExpr.
607 OverloadedOperatorKind K = FD->getOverloadedOperator();
608 if (K == OO_New)
609 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
610 AF_CXXNew);
611 else if (K == OO_Array_New)
612 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
613 AF_CXXNewArray);
614 else if (K == OO_Delete || K == OO_Array_Delete)
615 State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
616 else
617 llvm_unreachable("not a new/delete operator");
Jordan Rose6cd16c52012-07-10 23:13:01 +0000618 }
619 }
620
Anton Yartsev05789592013-03-28 17:05:19 +0000621 if (Filter.CMallocOptimistic || Filter.CMismatchedDeallocatorChecker) {
Anna Zaks40a7eb32012-02-22 19:24:52 +0000622 // Check all the attributes, if there are any.
623 // There can be multiple of these attributes.
624 if (FD->hasAttrs())
625 for (specific_attr_iterator<OwnershipAttr>
626 i = FD->specific_attr_begin<OwnershipAttr>(),
627 e = FD->specific_attr_end<OwnershipAttr>();
628 i != e; ++i) {
629 switch ((*i)->getOwnKind()) {
630 case OwnershipAttr::Returns:
631 State = MallocMemReturnsAttr(C, CE, *i);
632 break;
633 case OwnershipAttr::Takes:
634 case OwnershipAttr::Holds:
635 State = FreeMemAttr(C, CE, *i);
636 break;
637 }
638 }
Zhongxing Xu527ff6d2010-06-01 03:01:33 +0000639 }
Anna Zaks199e8e52012-02-22 03:14:20 +0000640 C.addTransition(State);
Zhongxing Xuc0484fa2009-12-12 12:29:38 +0000641}
642
Anton Yartsev13df0362013-03-25 01:35:45 +0000643void MallocChecker::checkPostStmt(const CXXNewExpr *NE,
644 CheckerContext &C) const {
645
646 if (NE->getNumPlacementArgs())
647 for (CXXNewExpr::const_arg_iterator I = NE->placement_arg_begin(),
648 E = NE->placement_arg_end(); I != E; ++I)
649 if (SymbolRef Sym = C.getSVal(*I).getAsSymbol())
650 checkUseAfterFree(Sym, C, *I);
651
Anton Yartsev13df0362013-03-25 01:35:45 +0000652 if (!isStandardNewDelete(NE->getOperatorNew(), C.getASTContext()))
653 return;
654
655 ProgramStateRef State = C.getState();
656 // The return value from operator new is bound to a specified initialization
657 // value (if any) and we don't want to loose this value. So we call
658 // MallocUpdateRefState() instead of MallocMemAux() which breakes the
659 // existing binding.
Anton Yartsev05789592013-03-28 17:05:19 +0000660 State = MallocUpdateRefState(C, NE, State, NE->isArray() ? AF_CXXNewArray
661 : AF_CXXNew);
Anton Yartsev13df0362013-03-25 01:35:45 +0000662 C.addTransition(State);
663}
664
665void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE,
666 CheckerContext &C) const {
667
Anton Yartsev05789592013-03-28 17:05:19 +0000668 if (!Filter.CNewDeleteChecker)
Anton Yartsev13df0362013-03-25 01:35:45 +0000669 if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol())
670 checkUseAfterFree(Sym, C, DE->getArgument());
671
Anton Yartsev13df0362013-03-25 01:35:45 +0000672 if (!isStandardNewDelete(DE->getOperatorDelete(), C.getASTContext()))
673 return;
674
675 ProgramStateRef State = C.getState();
676 bool ReleasedAllocated;
677 State = FreeMemAux(C, DE->getArgument(), DE, State,
678 /*Hold*/false, ReleasedAllocated);
679
680 C.addTransition(State);
681}
682
Jordan Rose613f3c02013-03-09 00:59:10 +0000683static bool isKnownDeallocObjCMethodName(const ObjCMethodCall &Call) {
684 // If the first selector piece is one of the names below, assume that the
685 // object takes ownership of the memory, promising to eventually deallocate it
686 // with free().
687 // Ex: [NSData dataWithBytesNoCopy:bytes length:10];
688 // (...unless a 'freeWhenDone' parameter is false, but that's checked later.)
689 StringRef FirstSlot = Call.getSelector().getNameForSlot(0);
690 if (FirstSlot == "dataWithBytesNoCopy" ||
691 FirstSlot == "initWithBytesNoCopy" ||
692 FirstSlot == "initWithCharactersNoCopy")
693 return true;
Anna Zaks0d6989b2012-06-22 02:04:31 +0000694
695 return false;
696}
697
Jordan Rose613f3c02013-03-09 00:59:10 +0000698static Optional<bool> getFreeWhenDoneArg(const ObjCMethodCall &Call) {
699 Selector S = Call.getSelector();
700
701 // FIXME: We should not rely on fully-constrained symbols being folded.
702 for (unsigned i = 1; i < S.getNumArgs(); ++i)
703 if (S.getNameForSlot(i).equals("freeWhenDone"))
704 return !Call.getArgSVal(i).isZeroConstant();
705
706 return None;
707}
708
Anna Zaks67291b92012-11-13 03:18:01 +0000709void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call,
710 CheckerContext &C) const {
Anna Zaksa7b1c472012-12-11 00:17:53 +0000711 if (C.wasInlined)
712 return;
713
Jordan Rose613f3c02013-03-09 00:59:10 +0000714 if (!isKnownDeallocObjCMethodName(Call))
715 return;
Anna Zaks67291b92012-11-13 03:18:01 +0000716
Jordan Rose613f3c02013-03-09 00:59:10 +0000717 if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(Call))
718 if (!*FreeWhenDone)
719 return;
720
721 bool ReleasedAllocatedMemory;
722 ProgramStateRef State = FreeMemAux(C, Call.getArgExpr(0),
723 Call.getOriginExpr(), C.getState(),
724 /*Hold=*/true, ReleasedAllocatedMemory,
725 /*RetNullOnFailure=*/true);
726
727 C.addTransition(State);
Anna Zaks0d6989b2012-06-22 02:04:31 +0000728}
729
Richard Smith852e9ce2013-11-27 01:46:48 +0000730ProgramStateRef
731MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
732 const OwnershipAttr *Att) const {
733 if (Att->getModule() != II_malloc)
Anna Zaks40a7eb32012-02-22 19:24:52 +0000734 return 0;
Ted Kremenekd21139a2010-07-31 01:52:11 +0000735
Alexis Huntdcfba7b2010-08-18 23:23:40 +0000736 OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
Ted Kremenekd21139a2010-07-31 01:52:11 +0000737 if (I != E) {
Anna Zaks40a7eb32012-02-22 19:24:52 +0000738 return MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState());
Ted Kremenekd21139a2010-07-31 01:52:11 +0000739 }
Anna Zaks40a7eb32012-02-22 19:24:52 +0000740 return MallocMemAux(C, CE, UnknownVal(), UndefinedVal(), C.getState());
Ted Kremenekd21139a2010-07-31 01:52:11 +0000741}
742
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000743ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
Zhongxing Xuc0484fa2009-12-12 12:29:38 +0000744 const CallExpr *CE,
Zhongxing Xu527ff6d2010-06-01 03:01:33 +0000745 SVal Size, SVal Init,
Anton Yartsev05789592013-03-28 17:05:19 +0000746 ProgramStateRef State,
747 AllocationFamily Family) {
Anna Zaks3563fde2012-06-07 03:57:32 +0000748
749 // Bind the return value to the symbolic value from the heap region.
750 // TODO: We could rewrite post visit to eval call; 'malloc' does not have
751 // side effects other than what we model here.
Ted Kremenekd94854a2012-08-22 06:26:15 +0000752 unsigned Count = C.blockCount();
Anna Zaks3563fde2012-06-07 03:57:32 +0000753 SValBuilder &svalBuilder = C.getSValBuilder();
754 const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
David Blaikie2fdacbc2013-02-20 05:52:05 +0000755 DefinedSVal RetVal = svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count)
756 .castAs<DefinedSVal>();
Anton Yartsev05789592013-03-28 17:05:19 +0000757 State = State->BindExpr(CE, C.getLocationContext(), RetVal);
Zhongxing Xu9cb53b82009-12-11 03:09:01 +0000758
Anna Zaksd5157482012-02-15 00:11:22 +0000759 // We expect the malloc functions to return a pointer.
David Blaikie2fdacbc2013-02-20 05:52:05 +0000760 if (!RetVal.getAs<Loc>())
Anna Zaksd5157482012-02-15 00:11:22 +0000761 return 0;
762
Jordy Rose674bd552010-07-04 00:00:41 +0000763 // Fill the region with the initialization value.
Anton Yartsev05789592013-03-28 17:05:19 +0000764 State = State->bindDefault(RetVal, Init);
Zhongxing Xu527ff6d2010-06-01 03:01:33 +0000765
Jordy Rose674bd552010-07-04 00:00:41 +0000766 // Set the region's extent equal to the Size parameter.
Anna Zaks31886862012-02-10 01:11:00 +0000767 const SymbolicRegion *R =
Anna Zaks3563fde2012-06-07 03:57:32 +0000768 dyn_cast_or_null<SymbolicRegion>(RetVal.getAsRegion());
Anna Zaks199e8e52012-02-22 03:14:20 +0000769 if (!R)
Anna Zaks31886862012-02-10 01:11:00 +0000770 return 0;
David Blaikie05785d12013-02-20 22:23:23 +0000771 if (Optional<DefinedOrUnknownSVal> DefinedSize =
David Blaikie2fdacbc2013-02-20 05:52:05 +0000772 Size.getAs<DefinedOrUnknownSVal>()) {
Anna Zaks40a7eb32012-02-22 19:24:52 +0000773 SValBuilder &svalBuilder = C.getSValBuilder();
Anna Zaks199e8e52012-02-22 03:14:20 +0000774 DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
Anna Zaks199e8e52012-02-22 03:14:20 +0000775 DefinedOrUnknownSVal extentMatchesSize =
Anton Yartsev05789592013-03-28 17:05:19 +0000776 svalBuilder.evalEQ(State, Extent, *DefinedSize);
Anna Zaks31886862012-02-10 01:11:00 +0000777
Anton Yartsev05789592013-03-28 17:05:19 +0000778 State = State->assume(extentMatchesSize, true);
779 assert(State);
Anna Zaks199e8e52012-02-22 03:14:20 +0000780 }
Ted Kremenek90af9092010-12-02 07:49:45 +0000781
Anton Yartsev05789592013-03-28 17:05:19 +0000782 return MallocUpdateRefState(C, CE, State, Family);
Anna Zaks40a7eb32012-02-22 19:24:52 +0000783}
784
785ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C,
Anton Yartsev13df0362013-03-25 01:35:45 +0000786 const Expr *E,
Anton Yartsev05789592013-03-28 17:05:19 +0000787 ProgramStateRef State,
788 AllocationFamily Family) {
Anna Zaks40a7eb32012-02-22 19:24:52 +0000789 // Get the return value.
Anton Yartsev05789592013-03-28 17:05:19 +0000790 SVal retVal = State->getSVal(E, C.getLocationContext());
Anna Zaks40a7eb32012-02-22 19:24:52 +0000791
792 // We expect the malloc functions to return a pointer.
David Blaikie2fdacbc2013-02-20 05:52:05 +0000793 if (!retVal.getAs<Loc>())
Anna Zaks40a7eb32012-02-22 19:24:52 +0000794 return 0;
795
Ted Kremenek90af9092010-12-02 07:49:45 +0000796 SymbolRef Sym = retVal.getAsLocSymbol();
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000797 assert(Sym);
Ted Kremenek90af9092010-12-02 07:49:45 +0000798
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000799 // Set the symbol's state to Allocated.
Anton Yartsev05789592013-03-28 17:05:19 +0000800 return State->set<RegionState>(Sym, RefState::getAllocated(Family, E));
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000801}
802
Anna Zaks40a7eb32012-02-22 19:24:52 +0000803ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C,
804 const CallExpr *CE,
Richard Smith852e9ce2013-11-27 01:46:48 +0000805 const OwnershipAttr *Att) const {
806 if (Att->getModule() != II_malloc)
Anna Zaks40a7eb32012-02-22 19:24:52 +0000807 return 0;
Ted Kremenekd21139a2010-07-31 01:52:11 +0000808
Anna Zaks8dc53af2012-03-01 22:06:06 +0000809 ProgramStateRef State = C.getState();
Anna Zaksfe6eb672012-08-24 02:28:20 +0000810 bool ReleasedAllocated = false;
Anna Zaks8dc53af2012-03-01 22:06:06 +0000811
Alexis Huntdcfba7b2010-08-18 23:23:40 +0000812 for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
813 I != E; ++I) {
Anna Zaks8dc53af2012-03-01 22:06:06 +0000814 ProgramStateRef StateI = FreeMemAux(C, CE, State, *I,
Anna Zaksfe6eb672012-08-24 02:28:20 +0000815 Att->getOwnKind() == OwnershipAttr::Holds,
816 ReleasedAllocated);
Anna Zaks8dc53af2012-03-01 22:06:06 +0000817 if (StateI)
818 State = StateI;
Ted Kremenekd21139a2010-07-31 01:52:11 +0000819 }
Anna Zaks8dc53af2012-03-01 22:06:06 +0000820 return State;
Ted Kremenekd21139a2010-07-31 01:52:11 +0000821}
822
Ted Kremenek49b1e382012-01-26 21:29:00 +0000823ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
Anna Zaks31886862012-02-10 01:11:00 +0000824 const CallExpr *CE,
825 ProgramStateRef state,
826 unsigned Num,
Anna Zaksfe6eb672012-08-24 02:28:20 +0000827 bool Hold,
Anna Zaks67291b92012-11-13 03:18:01 +0000828 bool &ReleasedAllocated,
829 bool ReturnsNullOnFailure) const {
Anna Zaksb508d292012-04-10 23:41:11 +0000830 if (CE->getNumArgs() < (Num + 1))
831 return 0;
832
Anna Zaks67291b92012-11-13 03:18:01 +0000833 return FreeMemAux(C, CE->getArg(Num), CE, state, Hold,
834 ReleasedAllocated, ReturnsNullOnFailure);
835}
836
Anna Zaksa14c1d02012-11-13 19:47:40 +0000837/// Checks if the previous call to free on the given symbol failed - if free
838/// failed, returns true. Also, returns the corresponding return value symbol.
Benjamin Kramerba4c85e2012-11-22 15:02:44 +0000839static bool didPreviousFreeFail(ProgramStateRef State,
840 SymbolRef Sym, SymbolRef &RetStatusSymbol) {
Anna Zaksa14c1d02012-11-13 19:47:40 +0000841 const SymbolRef *Ret = State->get<FreeReturnValue>(Sym);
Anna Zaks67291b92012-11-13 03:18:01 +0000842 if (Ret) {
843 assert(*Ret && "We should not store the null return symbol");
844 ConstraintManager &CMgr = State->getConstraintManager();
845 ConditionTruthVal FreeFailed = CMgr.isNull(State, *Ret);
Anna Zaksa14c1d02012-11-13 19:47:40 +0000846 RetStatusSymbol = *Ret;
847 return FreeFailed.isConstrainedTrue();
Anna Zaks67291b92012-11-13 03:18:01 +0000848 }
Anna Zaksa14c1d02012-11-13 19:47:40 +0000849 return false;
Anna Zaks0d6989b2012-06-22 02:04:31 +0000850}
851
Anton Yartsev05789592013-03-28 17:05:19 +0000852AllocationFamily MallocChecker::getAllocationFamily(CheckerContext &C,
Anton Yartseve3377fb2013-04-04 23:46:29 +0000853 const Stmt *S) const {
854 if (!S)
Anton Yartsev05789592013-03-28 17:05:19 +0000855 return AF_None;
856
Anton Yartseve3377fb2013-04-04 23:46:29 +0000857 if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
Anton Yartsev05789592013-03-28 17:05:19 +0000858 const FunctionDecl *FD = C.getCalleeDecl(CE);
Anton Yartseve3377fb2013-04-04 23:46:29 +0000859
860 if (!FD)
861 FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
862
Anton Yartsev05789592013-03-28 17:05:19 +0000863 ASTContext &Ctx = C.getASTContext();
864
Anton Yartseve3377fb2013-04-04 23:46:29 +0000865 if (isAllocationFunction(FD, Ctx) || isFreeFunction(FD, Ctx))
Anton Yartsev05789592013-03-28 17:05:19 +0000866 return AF_Malloc;
867
868 if (isStandardNewDelete(FD, Ctx)) {
869 OverloadedOperatorKind Kind = FD->getOverloadedOperator();
Anton Yartseve3377fb2013-04-04 23:46:29 +0000870 if (Kind == OO_New || Kind == OO_Delete)
Anton Yartsev05789592013-03-28 17:05:19 +0000871 return AF_CXXNew;
Anton Yartseve3377fb2013-04-04 23:46:29 +0000872 else if (Kind == OO_Array_New || Kind == OO_Array_Delete)
Anton Yartsev05789592013-03-28 17:05:19 +0000873 return AF_CXXNewArray;
874 }
875
876 return AF_None;
877 }
878
Anton Yartseve3377fb2013-04-04 23:46:29 +0000879 if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(S))
880 return NE->isArray() ? AF_CXXNewArray : AF_CXXNew;
881
882 if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(S))
Anton Yartsev05789592013-03-28 17:05:19 +0000883 return DE->isArrayForm() ? AF_CXXNewArray : AF_CXXNew;
884
Anton Yartseve3377fb2013-04-04 23:46:29 +0000885 if (isa<ObjCMessageExpr>(S))
Anton Yartsev05789592013-03-28 17:05:19 +0000886 return AF_Malloc;
887
888 return AF_None;
889}
890
891bool MallocChecker::printAllocDeallocName(raw_ostream &os, CheckerContext &C,
892 const Expr *E) const {
893 if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
894 // FIXME: This doesn't handle indirect calls.
895 const FunctionDecl *FD = CE->getDirectCallee();
896 if (!FD)
897 return false;
898
899 os << *FD;
900 if (!FD->isOverloadedOperator())
901 os << "()";
902 return true;
903 }
904
905 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) {
906 if (Msg->isInstanceMessage())
907 os << "-";
908 else
909 os << "+";
Aaron Ballmanb190f972014-01-03 17:59:55 +0000910 Msg->getSelector().print(os);
Anton Yartsev05789592013-03-28 17:05:19 +0000911 return true;
912 }
913
914 if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) {
915 os << "'"
916 << getOperatorSpelling(NE->getOperatorNew()->getOverloadedOperator())
917 << "'";
918 return true;
919 }
920
921 if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(E)) {
922 os << "'"
923 << getOperatorSpelling(DE->getOperatorDelete()->getOverloadedOperator())
924 << "'";
925 return true;
926 }
927
928 return false;
929}
930
931void MallocChecker::printExpectedAllocName(raw_ostream &os, CheckerContext &C,
932 const Expr *E) const {
933 AllocationFamily Family = getAllocationFamily(C, E);
934
935 switch(Family) {
936 case AF_Malloc: os << "malloc()"; return;
937 case AF_CXXNew: os << "'new'"; return;
938 case AF_CXXNewArray: os << "'new[]'"; return;
939 case AF_None: llvm_unreachable("not a deallocation expression");
940 }
941}
942
943void MallocChecker::printExpectedDeallocName(raw_ostream &os,
944 AllocationFamily Family) const {
945 switch(Family) {
946 case AF_Malloc: os << "free()"; return;
947 case AF_CXXNew: os << "'delete'"; return;
948 case AF_CXXNewArray: os << "'delete[]'"; return;
949 case AF_None: llvm_unreachable("suspicious AF_None argument");
950 }
951}
952
Anna Zaks0d6989b2012-06-22 02:04:31 +0000953ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
954 const Expr *ArgExpr,
955 const Expr *ParentExpr,
Anna Zaks67291b92012-11-13 03:18:01 +0000956 ProgramStateRef State,
Anna Zaksfe6eb672012-08-24 02:28:20 +0000957 bool Hold,
Anna Zaks67291b92012-11-13 03:18:01 +0000958 bool &ReleasedAllocated,
959 bool ReturnsNullOnFailure) const {
Anna Zaks0d6989b2012-06-22 02:04:31 +0000960
Anna Zaks67291b92012-11-13 03:18:01 +0000961 SVal ArgVal = State->getSVal(ArgExpr, C.getLocationContext());
David Blaikie2fdacbc2013-02-20 05:52:05 +0000962 if (!ArgVal.getAs<DefinedOrUnknownSVal>())
Anna Zaks31886862012-02-10 01:11:00 +0000963 return 0;
David Blaikie2fdacbc2013-02-20 05:52:05 +0000964 DefinedOrUnknownSVal location = ArgVal.castAs<DefinedOrUnknownSVal>();
Ted Kremenekd21139a2010-07-31 01:52:11 +0000965
966 // Check for null dereferences.
David Blaikie2fdacbc2013-02-20 05:52:05 +0000967 if (!location.getAs<Loc>())
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000968 return 0;
Ted Kremenekd21139a2010-07-31 01:52:11 +0000969
Anna Zaksad01ef52012-02-14 00:26:13 +0000970 // The explicit NULL case, no operation is performed.
Ted Kremenek49b1e382012-01-26 21:29:00 +0000971 ProgramStateRef notNullState, nullState;
Anna Zaks67291b92012-11-13 03:18:01 +0000972 llvm::tie(notNullState, nullState) = State->assume(location);
Ted Kremenekd21139a2010-07-31 01:52:11 +0000973 if (nullState && !notNullState)
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000974 return 0;
Ted Kremenekd21139a2010-07-31 01:52:11 +0000975
Jordy Rose3597b212010-06-07 19:32:37 +0000976 // Unknown values could easily be okay
977 // Undefined values are handled elsewhere
978 if (ArgVal.isUnknownOrUndef())
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000979 return 0;
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000980
Jordy Rose3597b212010-06-07 19:32:37 +0000981 const MemRegion *R = ArgVal.getAsRegion();
982
983 // Nonlocs can't be freed, of course.
984 // Non-region locations (labels and fixed addresses) also shouldn't be freed.
985 if (!R) {
Anton Yartsev05789592013-03-28 17:05:19 +0000986 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000987 return 0;
Jordy Rose3597b212010-06-07 19:32:37 +0000988 }
989
990 R = R->StripCasts();
991
992 // Blocks might show up as heap data, but should not be free()d
993 if (isa<BlockDataRegion>(R)) {
Anton Yartsev05789592013-03-28 17:05:19 +0000994 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000995 return 0;
Jordy Rose3597b212010-06-07 19:32:37 +0000996 }
997
998 const MemSpaceRegion *MS = R->getMemorySpace();
999
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001000 // Parameters, locals, statics, globals, and memory returned by alloca()
1001 // shouldn't be freed.
Jordy Rose3597b212010-06-07 19:32:37 +00001002 if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
1003 // FIXME: at the time this code was written, malloc() regions were
1004 // represented by conjured symbols, which are all in UnknownSpaceRegion.
1005 // This means that there isn't actually anything from HeapSpaceRegion
1006 // that should be freed, even though we allow it here.
1007 // Of course, free() can work on memory allocated outside the current
1008 // function, so UnknownSpaceRegion is always a possibility.
1009 // False negatives are better than false positives.
1010
Anton Yartsev05789592013-03-28 17:05:19 +00001011 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
Anna Zaksc68bf4c2012-02-08 20:13:28 +00001012 return 0;
Jordy Rose3597b212010-06-07 19:32:37 +00001013 }
Anna Zaksc89ad072013-02-07 23:05:47 +00001014
1015 const SymbolicRegion *SrBase = dyn_cast<SymbolicRegion>(R->getBaseRegion());
Jordy Rose3597b212010-06-07 19:32:37 +00001016 // Various cases could lead to non-symbol values here.
1017 // For now, ignore them.
Anna Zaksc89ad072013-02-07 23:05:47 +00001018 if (!SrBase)
Anna Zaksc68bf4c2012-02-08 20:13:28 +00001019 return 0;
Jordy Rose3597b212010-06-07 19:32:37 +00001020
Anna Zaksc89ad072013-02-07 23:05:47 +00001021 SymbolRef SymBase = SrBase->getSymbol();
1022 const RefState *RsBase = State->get<RegionState>(SymBase);
Anna Zaksa14c1d02012-11-13 19:47:40 +00001023 SymbolRef PreviousRetStatusSymbol = 0;
Zhongxing Xue2bdb9a2010-01-18 03:27:34 +00001024
Anton Yartseve3377fb2013-04-04 23:46:29 +00001025 if (RsBase) {
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001026
Anna Zaks93a21a82013-04-09 00:30:28 +00001027 // Check for double free first.
1028 if ((RsBase->isReleased() || RsBase->isRelinquished()) &&
Anton Yartseve3377fb2013-04-04 23:46:29 +00001029 !didPreviousFreeFail(State, SymBase, PreviousRetStatusSymbol)) {
1030 ReportDoubleFree(C, ParentExpr->getSourceRange(), RsBase->isReleased(),
1031 SymBase, PreviousRetStatusSymbol);
1032 return 0;
Anton Yartseve3377fb2013-04-04 23:46:29 +00001033
Anna Zaks93a21a82013-04-09 00:30:28 +00001034 // If the pointer is allocated or escaped, but we are now trying to free it,
1035 // check that the call to free is proper.
1036 } else if (RsBase->isAllocated() || RsBase->isEscaped()) {
1037
1038 // Check if an expected deallocation function matches the real one.
1039 bool DeallocMatchesAlloc =
1040 RsBase->getAllocationFamily() == getAllocationFamily(C, ParentExpr);
1041 if (!DeallocMatchesAlloc) {
1042 ReportMismatchedDealloc(C, ArgExpr->getSourceRange(),
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001043 ParentExpr, RsBase, SymBase, Hold);
Anna Zaks93a21a82013-04-09 00:30:28 +00001044 return 0;
1045 }
1046
1047 // Check if the memory location being freed is the actual location
1048 // allocated, or an offset.
1049 RegionOffset Offset = R->getAsOffset();
1050 if (Offset.isValid() &&
1051 !Offset.hasSymbolicOffset() &&
1052 Offset.getOffset() != 0) {
1053 const Expr *AllocExpr = cast<Expr>(RsBase->getStmt());
1054 ReportOffsetFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
1055 AllocExpr);
1056 return 0;
1057 }
Anton Yartseve3377fb2013-04-04 23:46:29 +00001058 }
Anna Zaksc89ad072013-02-07 23:05:47 +00001059 }
1060
Jordan Rose2f8b0222013-08-15 17:22:06 +00001061 ReleasedAllocated = (RsBase != 0) && RsBase->isAllocated();
Anna Zaksfe6eb672012-08-24 02:28:20 +00001062
Anna Zaksa14c1d02012-11-13 19:47:40 +00001063 // Clean out the info on previous call to free return info.
Anna Zaksc89ad072013-02-07 23:05:47 +00001064 State = State->remove<FreeReturnValue>(SymBase);
Anna Zaksa14c1d02012-11-13 19:47:40 +00001065
Anna Zaks67291b92012-11-13 03:18:01 +00001066 // Keep track of the return value. If it is NULL, we will know that free
1067 // failed.
1068 if (ReturnsNullOnFailure) {
1069 SVal RetVal = C.getSVal(ParentExpr);
1070 SymbolRef RetStatusSymbol = RetVal.getAsSymbol();
1071 if (RetStatusSymbol) {
Anna Zaksc89ad072013-02-07 23:05:47 +00001072 C.getSymbolManager().addSymbolDependency(SymBase, RetStatusSymbol);
1073 State = State->set<FreeReturnValue>(SymBase, RetStatusSymbol);
Anna Zaks67291b92012-11-13 03:18:01 +00001074 }
1075 }
1076
Anton Yartsev030bcdd2013-04-05 19:08:04 +00001077 AllocationFamily Family = RsBase ? RsBase->getAllocationFamily()
1078 : getAllocationFamily(C, ParentExpr);
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001079 // Normal free.
Anton Yartsev05789592013-03-28 17:05:19 +00001080 if (Hold)
Anna Zaksc89ad072013-02-07 23:05:47 +00001081 return State->set<RegionState>(SymBase,
Anton Yartsev05789592013-03-28 17:05:19 +00001082 RefState::getRelinquished(Family,
1083 ParentExpr));
1084
1085 return State->set<RegionState>(SymBase,
1086 RefState::getReleased(Family, ParentExpr));
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00001087}
1088
Anton Yartsev1e2bc9b2013-04-11 00:05:20 +00001089bool MallocChecker::isTrackedByCurrentChecker(AllocationFamily Family) const {
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001090 switch (Family) {
1091 case AF_Malloc: {
1092 if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic)
1093 return false;
Anton Yartsev2f910042013-04-05 02:12:04 +00001094 return true;
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001095 }
1096 case AF_CXXNew:
1097 case AF_CXXNewArray: {
Anton Yartsev7af0aa82013-04-12 23:25:40 +00001098 if (!Filter.CNewDeleteChecker)
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001099 return false;
Anton Yartsev2f910042013-04-05 02:12:04 +00001100 return true;
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001101 }
1102 case AF_None: {
Anton Yartsev030bcdd2013-04-05 19:08:04 +00001103 llvm_unreachable("no family");
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001104 }
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001105 }
Anton Yartsev2f910042013-04-05 02:12:04 +00001106 llvm_unreachable("unhandled family");
Anton Yartseve3377fb2013-04-04 23:46:29 +00001107}
1108
Anton Yartsev1e2bc9b2013-04-11 00:05:20 +00001109bool
1110MallocChecker::isTrackedByCurrentChecker(CheckerContext &C,
1111 const Stmt *AllocDeallocStmt) const {
1112 return isTrackedByCurrentChecker(getAllocationFamily(C, AllocDeallocStmt));
Anton Yartseve3377fb2013-04-04 23:46:29 +00001113}
1114
Anton Yartsev1e2bc9b2013-04-11 00:05:20 +00001115bool MallocChecker::isTrackedByCurrentChecker(CheckerContext &C,
1116 SymbolRef Sym) const {
Anton Yartseve3377fb2013-04-04 23:46:29 +00001117
Anton Yartsev030bcdd2013-04-05 19:08:04 +00001118 const RefState *RS = C.getState()->get<RegionState>(Sym);
1119 assert(RS);
Anton Yartsev1e2bc9b2013-04-11 00:05:20 +00001120 return isTrackedByCurrentChecker(RS->getAllocationFamily());
Anton Yartseve3377fb2013-04-04 23:46:29 +00001121}
1122
Ted Kremenek5ef32db2011-08-12 23:37:29 +00001123bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
David Blaikie05785d12013-02-20 22:23:23 +00001124 if (Optional<nonloc::ConcreteInt> IntVal = V.getAs<nonloc::ConcreteInt>())
Jordy Rose3597b212010-06-07 19:32:37 +00001125 os << "an integer (" << IntVal->getValue() << ")";
David Blaikie05785d12013-02-20 22:23:23 +00001126 else if (Optional<loc::ConcreteInt> ConstAddr = V.getAs<loc::ConcreteInt>())
Jordy Rose3597b212010-06-07 19:32:37 +00001127 os << "a constant address (" << ConstAddr->getValue() << ")";
David Blaikie05785d12013-02-20 22:23:23 +00001128 else if (Optional<loc::GotoLabel> Label = V.getAs<loc::GotoLabel>())
Chris Lattner5a9b1ec2011-02-17 05:38:27 +00001129 os << "the address of the label '" << Label->getLabel()->getName() << "'";
Jordy Rose3597b212010-06-07 19:32:37 +00001130 else
1131 return false;
1132
1133 return true;
1134}
1135
Ted Kremenek5ef32db2011-08-12 23:37:29 +00001136bool MallocChecker::SummarizeRegion(raw_ostream &os,
Jordy Rose3597b212010-06-07 19:32:37 +00001137 const MemRegion *MR) {
1138 switch (MR->getKind()) {
1139 case MemRegion::FunctionTextRegionKind: {
Anna Zaks42782342012-09-17 19:13:56 +00001140 const NamedDecl *FD = cast<FunctionTextRegion>(MR)->getDecl();
Jordy Rose3597b212010-06-07 19:32:37 +00001141 if (FD)
Benjamin Kramerb89514a2011-10-14 18:45:37 +00001142 os << "the address of the function '" << *FD << '\'';
Jordy Rose3597b212010-06-07 19:32:37 +00001143 else
1144 os << "the address of a function";
1145 return true;
1146 }
1147 case MemRegion::BlockTextRegionKind:
1148 os << "block text";
1149 return true;
1150 case MemRegion::BlockDataRegionKind:
1151 // FIXME: where the block came from?
1152 os << "a block";
1153 return true;
1154 default: {
1155 const MemSpaceRegion *MS = MR->getMemorySpace();
1156
Anna Zaks8158ef02012-01-04 23:54:01 +00001157 if (isa<StackLocalsSpaceRegion>(MS)) {
Jordy Rose3597b212010-06-07 19:32:37 +00001158 const VarRegion *VR = dyn_cast<VarRegion>(MR);
1159 const VarDecl *VD;
1160 if (VR)
1161 VD = VR->getDecl();
1162 else
1163 VD = NULL;
1164
1165 if (VD)
1166 os << "the address of the local variable '" << VD->getName() << "'";
1167 else
1168 os << "the address of a local stack variable";
1169 return true;
1170 }
Anna Zaks8158ef02012-01-04 23:54:01 +00001171
1172 if (isa<StackArgumentsSpaceRegion>(MS)) {
Jordy Rose3597b212010-06-07 19:32:37 +00001173 const VarRegion *VR = dyn_cast<VarRegion>(MR);
1174 const VarDecl *VD;
1175 if (VR)
1176 VD = VR->getDecl();
1177 else
1178 VD = NULL;
1179
1180 if (VD)
1181 os << "the address of the parameter '" << VD->getName() << "'";
1182 else
1183 os << "the address of a parameter";
1184 return true;
1185 }
Anna Zaks8158ef02012-01-04 23:54:01 +00001186
1187 if (isa<GlobalsSpaceRegion>(MS)) {
Jordy Rose3597b212010-06-07 19:32:37 +00001188 const VarRegion *VR = dyn_cast<VarRegion>(MR);
1189 const VarDecl *VD;
1190 if (VR)
1191 VD = VR->getDecl();
1192 else
1193 VD = NULL;
1194
1195 if (VD) {
1196 if (VD->isStaticLocal())
1197 os << "the address of the static variable '" << VD->getName() << "'";
1198 else
1199 os << "the address of the global variable '" << VD->getName() << "'";
1200 } else
1201 os << "the address of a global variable";
1202 return true;
1203 }
Anna Zaks8158ef02012-01-04 23:54:01 +00001204
1205 return false;
Jordy Rose3597b212010-06-07 19:32:37 +00001206 }
1207 }
1208}
1209
Anton Yartsev05789592013-03-28 17:05:19 +00001210void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
1211 SourceRange Range,
1212 const Expr *DeallocExpr) const {
1213
1214 if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic &&
1215 !Filter.CNewDeleteChecker)
1216 return;
1217
Anton Yartsev1e2bc9b2013-04-11 00:05:20 +00001218 if (!isTrackedByCurrentChecker(C, DeallocExpr))
Anton Yartseve3377fb2013-04-04 23:46:29 +00001219 return;
1220
Ted Kremenek750b7ac2010-12-20 21:19:09 +00001221 if (ExplodedNode *N = C.generateSink()) {
Jordy Rose3597b212010-06-07 19:32:37 +00001222 if (!BT_BadFree)
Anna Zaks546c49c2012-02-16 22:26:12 +00001223 BT_BadFree.reset(new BugType("Bad free", "Memory Error"));
Jordy Rose3597b212010-06-07 19:32:37 +00001224
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001225 SmallString<100> buf;
Jordy Rose3597b212010-06-07 19:32:37 +00001226 llvm::raw_svector_ostream os(buf);
Anton Yartsev05789592013-03-28 17:05:19 +00001227
Jordy Rose3597b212010-06-07 19:32:37 +00001228 const MemRegion *MR = ArgVal.getAsRegion();
Anton Yartsev05789592013-03-28 17:05:19 +00001229 while (const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(MR))
1230 MR = ER->getSuperRegion();
1231
1232 if (MR && isa<AllocaRegion>(MR))
1233 os << "Memory allocated by alloca() should not be deallocated";
1234 else {
1235 os << "Argument to ";
1236 if (!printAllocDeallocName(os, C, DeallocExpr))
1237 os << "deallocator";
1238
1239 os << " is ";
1240 bool Summarized = MR ? SummarizeRegion(os, MR)
1241 : SummarizeValue(os, ArgVal);
1242 if (Summarized)
1243 os << ", which is not memory allocated by ";
Jordy Rose3597b212010-06-07 19:32:37 +00001244 else
Anton Yartsev05789592013-03-28 17:05:19 +00001245 os << "not memory allocated by ";
1246
1247 printExpectedAllocName(os, C, DeallocExpr);
Jordy Rose3597b212010-06-07 19:32:37 +00001248 }
Anton Yartsev05789592013-03-28 17:05:19 +00001249
Anna Zaks3a6bdf82011-08-17 23:00:25 +00001250 BugReport *R = new BugReport(*BT_BadFree, os.str(), N);
Ted Kremenek1e809b42012-03-09 01:13:14 +00001251 R->markInteresting(MR);
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001252 R->addRange(Range);
Jordan Rosee10d5a72012-11-02 01:53:40 +00001253 C.emitReport(R);
Jordy Rose3597b212010-06-07 19:32:37 +00001254 }
1255}
1256
Anton Yartseve3377fb2013-04-04 23:46:29 +00001257void MallocChecker::ReportMismatchedDealloc(CheckerContext &C,
1258 SourceRange Range,
1259 const Expr *DeallocExpr,
Anton Yartsevf0593d62013-04-05 11:25:10 +00001260 const RefState *RS,
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001261 SymbolRef Sym,
1262 bool OwnershipTransferred) const {
Anton Yartsev05789592013-03-28 17:05:19 +00001263
1264 if (!Filter.CMismatchedDeallocatorChecker)
1265 return;
1266
1267 if (ExplodedNode *N = C.generateSink()) {
Anton Yartseve3377fb2013-04-04 23:46:29 +00001268 if (!BT_MismatchedDealloc)
1269 BT_MismatchedDealloc.reset(new BugType("Bad deallocator",
1270 "Memory Error"));
Anton Yartsev05789592013-03-28 17:05:19 +00001271
1272 SmallString<100> buf;
1273 llvm::raw_svector_ostream os(buf);
1274
1275 const Expr *AllocExpr = cast<Expr>(RS->getStmt());
1276 SmallString<20> AllocBuf;
1277 llvm::raw_svector_ostream AllocOs(AllocBuf);
1278 SmallString<20> DeallocBuf;
1279 llvm::raw_svector_ostream DeallocOs(DeallocBuf);
1280
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001281 if (OwnershipTransferred) {
1282 if (printAllocDeallocName(DeallocOs, C, DeallocExpr))
1283 os << DeallocOs.str() << " cannot";
1284 else
1285 os << "Cannot";
Anton Yartsev05789592013-03-28 17:05:19 +00001286
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001287 os << " take ownership of memory";
Anton Yartsev05789592013-03-28 17:05:19 +00001288
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001289 if (printAllocDeallocName(AllocOs, C, AllocExpr))
1290 os << " allocated by " << AllocOs.str();
1291 } else {
1292 os << "Memory";
1293 if (printAllocDeallocName(AllocOs, C, AllocExpr))
1294 os << " allocated by " << AllocOs.str();
1295
1296 os << " should be deallocated by ";
1297 printExpectedDeallocName(os, RS->getAllocationFamily());
1298
1299 if (printAllocDeallocName(DeallocOs, C, DeallocExpr))
1300 os << ", not " << DeallocOs.str();
1301 }
Anton Yartsev05789592013-03-28 17:05:19 +00001302
Anton Yartseve3377fb2013-04-04 23:46:29 +00001303 BugReport *R = new BugReport(*BT_MismatchedDealloc, os.str(), N);
Anton Yartsevf0593d62013-04-05 11:25:10 +00001304 R->markInteresting(Sym);
Anton Yartsev05789592013-03-28 17:05:19 +00001305 R->addRange(Range);
Anton Yartsevf0593d62013-04-05 11:25:10 +00001306 R->addVisitor(new MallocBugVisitor(Sym));
Anton Yartsev05789592013-03-28 17:05:19 +00001307 C.emitReport(R);
1308 }
1309}
1310
Anna Zaksc89ad072013-02-07 23:05:47 +00001311void MallocChecker::ReportOffsetFree(CheckerContext &C, SVal ArgVal,
Anton Yartsev05789592013-03-28 17:05:19 +00001312 SourceRange Range, const Expr *DeallocExpr,
1313 const Expr *AllocExpr) const {
1314
1315 if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic &&
1316 !Filter.CNewDeleteChecker)
1317 return;
1318
Anton Yartsev1e2bc9b2013-04-11 00:05:20 +00001319 if (!isTrackedByCurrentChecker(C, AllocExpr))
Anton Yartseve3377fb2013-04-04 23:46:29 +00001320 return;
1321
Anna Zaksc89ad072013-02-07 23:05:47 +00001322 ExplodedNode *N = C.generateSink();
1323 if (N == NULL)
1324 return;
1325
1326 if (!BT_OffsetFree)
1327 BT_OffsetFree.reset(new BugType("Offset free", "Memory Error"));
1328
1329 SmallString<100> buf;
1330 llvm::raw_svector_ostream os(buf);
Anton Yartsev05789592013-03-28 17:05:19 +00001331 SmallString<20> AllocNameBuf;
1332 llvm::raw_svector_ostream AllocNameOs(AllocNameBuf);
Anna Zaksc89ad072013-02-07 23:05:47 +00001333
1334 const MemRegion *MR = ArgVal.getAsRegion();
1335 assert(MR && "Only MemRegion based symbols can have offset free errors");
1336
1337 RegionOffset Offset = MR->getAsOffset();
1338 assert((Offset.isValid() &&
1339 !Offset.hasSymbolicOffset() &&
1340 Offset.getOffset() != 0) &&
1341 "Only symbols with a valid offset can have offset free errors");
1342
1343 int offsetBytes = Offset.getOffset() / C.getASTContext().getCharWidth();
1344
Anton Yartsev05789592013-03-28 17:05:19 +00001345 os << "Argument to ";
1346 if (!printAllocDeallocName(os, C, DeallocExpr))
1347 os << "deallocator";
1348 os << " is offset by "
Anna Zaksc89ad072013-02-07 23:05:47 +00001349 << offsetBytes
1350 << " "
1351 << ((abs(offsetBytes) > 1) ? "bytes" : "byte")
Anton Yartsev05789592013-03-28 17:05:19 +00001352 << " from the start of ";
1353 if (AllocExpr && printAllocDeallocName(AllocNameOs, C, AllocExpr))
1354 os << "memory allocated by " << AllocNameOs.str();
1355 else
1356 os << "allocated memory";
Anna Zaksc89ad072013-02-07 23:05:47 +00001357
1358 BugReport *R = new BugReport(*BT_OffsetFree, os.str(), N);
1359 R->markInteresting(MR->getBaseRegion());
1360 R->addRange(Range);
1361 C.emitReport(R);
1362}
1363
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001364void MallocChecker::ReportUseAfterFree(CheckerContext &C, SourceRange Range,
1365 SymbolRef Sym) const {
1366
Anton Yartsev05789592013-03-28 17:05:19 +00001367 if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic &&
1368 !Filter.CNewDeleteChecker)
1369 return;
1370
Anton Yartsev1e2bc9b2013-04-11 00:05:20 +00001371 if (!isTrackedByCurrentChecker(C, Sym))
Anton Yartseve3377fb2013-04-04 23:46:29 +00001372 return;
1373
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001374 if (ExplodedNode *N = C.generateSink()) {
1375 if (!BT_UseFree)
1376 BT_UseFree.reset(new BugType("Use-after-free", "Memory Error"));
1377
1378 BugReport *R = new BugReport(*BT_UseFree,
1379 "Use of memory after it is freed", N);
1380
1381 R->markInteresting(Sym);
1382 R->addRange(Range);
1383 R->addVisitor(new MallocBugVisitor(Sym));
1384 C.emitReport(R);
1385 }
1386}
1387
1388void MallocChecker::ReportDoubleFree(CheckerContext &C, SourceRange Range,
1389 bool Released, SymbolRef Sym,
Anton Yartsev6c2af432013-03-13 17:07:32 +00001390 SymbolRef PrevSym) const {
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001391
Anton Yartsev05789592013-03-28 17:05:19 +00001392 if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic &&
1393 !Filter.CNewDeleteChecker)
1394 return;
1395
Anton Yartsev1e2bc9b2013-04-11 00:05:20 +00001396 if (!isTrackedByCurrentChecker(C, Sym))
Anton Yartseve3377fb2013-04-04 23:46:29 +00001397 return;
1398
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001399 if (ExplodedNode *N = C.generateSink()) {
1400 if (!BT_DoubleFree)
1401 BT_DoubleFree.reset(new BugType("Double free", "Memory Error"));
1402
1403 BugReport *R = new BugReport(*BT_DoubleFree,
1404 (Released ? "Attempt to free released memory"
1405 : "Attempt to free non-owned memory"),
1406 N);
1407 R->addRange(Range);
Anton Yartsev6c2af432013-03-13 17:07:32 +00001408 R->markInteresting(Sym);
1409 if (PrevSym)
1410 R->markInteresting(PrevSym);
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001411 R->addVisitor(new MallocBugVisitor(Sym));
1412 C.emitReport(R);
1413 }
1414}
1415
Anna Zaks40a7eb32012-02-22 19:24:52 +00001416ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
1417 const CallExpr *CE,
1418 bool FreesOnFail) const {
Anna Zaksb508d292012-04-10 23:41:11 +00001419 if (CE->getNumArgs() < 2)
1420 return 0;
1421
Ted Kremenek49b1e382012-01-26 21:29:00 +00001422 ProgramStateRef state = C.getState();
Ted Kremenek90af9092010-12-02 07:49:45 +00001423 const Expr *arg0Expr = CE->getArg(0);
Ted Kremenek632e3b72012-01-06 22:09:28 +00001424 const LocationContext *LCtx = C.getLocationContext();
Anna Zaks31886862012-02-10 01:11:00 +00001425 SVal Arg0Val = state->getSVal(arg0Expr, LCtx);
David Blaikie2fdacbc2013-02-20 05:52:05 +00001426 if (!Arg0Val.getAs<DefinedOrUnknownSVal>())
Anna Zaks40a7eb32012-02-22 19:24:52 +00001427 return 0;
David Blaikie2fdacbc2013-02-20 05:52:05 +00001428 DefinedOrUnknownSVal arg0Val = Arg0Val.castAs<DefinedOrUnknownSVal>();
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00001429
Ted Kremenek9d0bb1e2010-12-01 21:28:31 +00001430 SValBuilder &svalBuilder = C.getSValBuilder();
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00001431
Ted Kremenek90af9092010-12-02 07:49:45 +00001432 DefinedOrUnknownSVal PtrEQ =
1433 svalBuilder.evalEQ(state, arg0Val, svalBuilder.makeNull());
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00001434
Lenny Maiorani005b5c12011-04-27 14:49:29 +00001435 // Get the size argument. If there is no size arg then give up.
1436 const Expr *Arg1 = CE->getArg(1);
1437 if (!Arg1)
Anna Zaks40a7eb32012-02-22 19:24:52 +00001438 return 0;
Lenny Maiorani005b5c12011-04-27 14:49:29 +00001439
1440 // Get the value of the size argument.
Anna Zaks31886862012-02-10 01:11:00 +00001441 SVal Arg1ValG = state->getSVal(Arg1, LCtx);
David Blaikie2fdacbc2013-02-20 05:52:05 +00001442 if (!Arg1ValG.getAs<DefinedOrUnknownSVal>())
Anna Zaks40a7eb32012-02-22 19:24:52 +00001443 return 0;
David Blaikie2fdacbc2013-02-20 05:52:05 +00001444 DefinedOrUnknownSVal Arg1Val = Arg1ValG.castAs<DefinedOrUnknownSVal>();
Lenny Maiorani005b5c12011-04-27 14:49:29 +00001445
1446 // Compare the size argument to 0.
1447 DefinedOrUnknownSVal SizeZero =
1448 svalBuilder.evalEQ(state, Arg1Val,
1449 svalBuilder.makeIntValWithPtrWidth(0, false));
1450
Anna Zaksd56c8792012-02-13 18:05:39 +00001451 ProgramStateRef StatePtrIsNull, StatePtrNotNull;
1452 llvm::tie(StatePtrIsNull, StatePtrNotNull) = state->assume(PtrEQ);
1453 ProgramStateRef StateSizeIsZero, StateSizeNotZero;
1454 llvm::tie(StateSizeIsZero, StateSizeNotZero) = state->assume(SizeZero);
1455 // We only assume exceptional states if they are definitely true; if the
1456 // state is under-constrained, assume regular realloc behavior.
1457 bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull;
1458 bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero;
1459
Lenny Maiorani005b5c12011-04-27 14:49:29 +00001460 // If the ptr is NULL and the size is not 0, the call is equivalent to
1461 // malloc(size).
Anna Zaksd56c8792012-02-13 18:05:39 +00001462 if ( PrtIsNull && !SizeIsZero) {
Anna Zaks40a7eb32012-02-22 19:24:52 +00001463 ProgramStateRef stateMalloc = MallocMemAux(C, CE, CE->getArg(1),
Anna Zaksd56c8792012-02-13 18:05:39 +00001464 UndefinedVal(), StatePtrIsNull);
Anna Zaks40a7eb32012-02-22 19:24:52 +00001465 return stateMalloc;
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00001466 }
1467
Anna Zaksd56c8792012-02-13 18:05:39 +00001468 if (PrtIsNull && SizeIsZero)
Anna Zaks40a7eb32012-02-22 19:24:52 +00001469 return 0;
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00001470
Anna Zaks8fd0f2a2012-02-13 20:57:07 +00001471 // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size).
Anna Zaksd56c8792012-02-13 18:05:39 +00001472 assert(!PrtIsNull);
Anna Zaks8fd0f2a2012-02-13 20:57:07 +00001473 SymbolRef FromPtr = arg0Val.getAsSymbol();
1474 SVal RetVal = state->getSVal(CE, LCtx);
1475 SymbolRef ToPtr = RetVal.getAsSymbol();
1476 if (!FromPtr || !ToPtr)
Anna Zaks40a7eb32012-02-22 19:24:52 +00001477 return 0;
Anna Zaksd56c8792012-02-13 18:05:39 +00001478
Anna Zaksfe6eb672012-08-24 02:28:20 +00001479 bool ReleasedAllocated = false;
1480
Anna Zaksd56c8792012-02-13 18:05:39 +00001481 // If the size is 0, free the memory.
1482 if (SizeIsZero)
Anna Zaksfe6eb672012-08-24 02:28:20 +00001483 if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero, 0,
1484 false, ReleasedAllocated)){
Anna Zaksd56c8792012-02-13 18:05:39 +00001485 // The semantics of the return value are:
1486 // If size was equal to 0, either NULL or a pointer suitable to be passed
Anna Zaks52242a62012-08-03 18:30:18 +00001487 // to free() is returned. We just free the input pointer and do not add
1488 // any constrains on the output pointer.
Anna Zaks40a7eb32012-02-22 19:24:52 +00001489 return stateFree;
Anna Zaksd56c8792012-02-13 18:05:39 +00001490 }
1491
1492 // Default behavior.
Anna Zaksfe6eb672012-08-24 02:28:20 +00001493 if (ProgramStateRef stateFree =
1494 FreeMemAux(C, CE, state, 0, false, ReleasedAllocated)) {
1495
Anna Zaksd56c8792012-02-13 18:05:39 +00001496 ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
1497 UnknownVal(), stateFree);
Anna Zaks8fd0f2a2012-02-13 20:57:07 +00001498 if (!stateRealloc)
Anna Zaks40a7eb32012-02-22 19:24:52 +00001499 return 0;
Anna Zaksfe6eb672012-08-24 02:28:20 +00001500
Anna Zaks75cfbb62012-09-12 22:57:34 +00001501 ReallocPairKind Kind = RPToBeFreedAfterFailure;
1502 if (FreesOnFail)
1503 Kind = RPIsFreeOnFailure;
1504 else if (!ReleasedAllocated)
1505 Kind = RPDoNotTrackAfterFailure;
1506
Anna Zaksfe6eb672012-08-24 02:28:20 +00001507 // Record the info about the reallocated symbol so that we could properly
1508 // process failed reallocation.
Anna Zaksac068142012-02-15 00:11:25 +00001509 stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr,
Anna Zaks75cfbb62012-09-12 22:57:34 +00001510 ReallocPair(FromPtr, Kind));
Anna Zaksfe6eb672012-08-24 02:28:20 +00001511 // The reallocated symbol should stay alive for as long as the new symbol.
Anna Zaksad01ef52012-02-14 00:26:13 +00001512 C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
Anna Zaks40a7eb32012-02-22 19:24:52 +00001513 return stateRealloc;
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00001514 }
Anna Zaks40a7eb32012-02-22 19:24:52 +00001515 return 0;
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001516}
Zhongxing Xuc4902a52009-11-13 07:25:27 +00001517
Anna Zaks40a7eb32012-02-22 19:24:52 +00001518ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE){
Anna Zaksb508d292012-04-10 23:41:11 +00001519 if (CE->getNumArgs() < 2)
1520 return 0;
1521
Ted Kremenek49b1e382012-01-26 21:29:00 +00001522 ProgramStateRef state = C.getState();
Ted Kremenek9d0bb1e2010-12-01 21:28:31 +00001523 SValBuilder &svalBuilder = C.getSValBuilder();
Ted Kremenek632e3b72012-01-06 22:09:28 +00001524 const LocationContext *LCtx = C.getLocationContext();
1525 SVal count = state->getSVal(CE->getArg(0), LCtx);
1526 SVal elementSize = state->getSVal(CE->getArg(1), LCtx);
Ted Kremenek90af9092010-12-02 07:49:45 +00001527 SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, count, elementSize,
1528 svalBuilder.getContext().getSizeType());
1529 SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
Zhongxing Xu527ff6d2010-06-01 03:01:33 +00001530
Anna Zaks40a7eb32012-02-22 19:24:52 +00001531 return MallocMemAux(C, CE, TotalSize, zeroVal, state);
Zhongxing Xu527ff6d2010-06-01 03:01:33 +00001532}
1533
Anna Zaksfc2e1532012-03-21 19:45:08 +00001534LeakInfo
Anna Zaksdf901a42012-02-23 21:38:21 +00001535MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
1536 CheckerContext &C) const {
Anna Zaks43ffba22012-02-27 23:40:55 +00001537 const LocationContext *LeakContext = N->getLocationContext();
Anna Zaksdf901a42012-02-23 21:38:21 +00001538 // Walk the ExplodedGraph backwards and find the first node that referred to
1539 // the tracked symbol.
1540 const ExplodedNode *AllocNode = N;
Anna Zaksfc2e1532012-03-21 19:45:08 +00001541 const MemRegion *ReferenceRegion = 0;
Anna Zaksdf901a42012-02-23 21:38:21 +00001542
1543 while (N) {
Anna Zaksfc2e1532012-03-21 19:45:08 +00001544 ProgramStateRef State = N->getState();
1545 if (!State->get<RegionState>(Sym))
Anna Zaksdf901a42012-02-23 21:38:21 +00001546 break;
Anna Zaksfc2e1532012-03-21 19:45:08 +00001547
1548 // Find the most recent expression bound to the symbol in the current
1549 // context.
Anna Zaks7c19abe2013-04-10 21:42:02 +00001550 if (!ReferenceRegion) {
1551 if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) {
1552 SVal Val = State->getSVal(MR);
1553 if (Val.getAsLocSymbol() == Sym) {
Anna Zaks07804ef2013-04-10 22:56:33 +00001554 const VarRegion* VR = MR->getBaseRegion()->getAs<VarRegion>();
Anna Zaks7c19abe2013-04-10 21:42:02 +00001555 // Do not show local variables belonging to a function other than
1556 // where the error is reported.
1557 if (!VR ||
1558 (VR->getStackFrame() == LeakContext->getCurrentStackFrame()))
1559 ReferenceRegion = MR;
1560 }
1561 }
Benjamin Kramerc25c5e02012-03-21 21:03:48 +00001562 }
Anna Zaksfc2e1532012-03-21 19:45:08 +00001563
Anna Zaks43ffba22012-02-27 23:40:55 +00001564 // Allocation node, is the last node in the current context in which the
1565 // symbol was tracked.
1566 if (N->getLocationContext() == LeakContext)
1567 AllocNode = N;
Anna Zaksdf901a42012-02-23 21:38:21 +00001568 N = N->pred_empty() ? NULL : *(N->pred_begin());
1569 }
1570
Anna Zaksa043d0c2013-01-08 00:25:29 +00001571 return LeakInfo(AllocNode, ReferenceRegion);
Anna Zaksdf901a42012-02-23 21:38:21 +00001572}
1573
Anna Zaksd3571e5a2012-02-11 21:02:40 +00001574void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
1575 CheckerContext &C) const {
Anton Yartsev05789592013-03-28 17:05:19 +00001576
1577 if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic &&
Jordan Rose26330562013-04-05 17:55:00 +00001578 !Filter.CNewDeleteLeaksChecker)
Anton Yartsev05789592013-03-28 17:05:19 +00001579 return;
1580
Jordan Rose26330562013-04-05 17:55:00 +00001581 const RefState *RS = C.getState()->get<RegionState>(Sym);
1582 assert(RS && "cannot leak an untracked symbol");
1583 AllocationFamily Family = RS->getAllocationFamily();
Anton Yartsev1e2bc9b2013-04-11 00:05:20 +00001584 if (!isTrackedByCurrentChecker(Family))
Anton Yartsev6e499252013-04-05 02:25:02 +00001585 return;
1586
Jordan Rose26330562013-04-05 17:55:00 +00001587 // Special case for new and new[]; these are controlled by a separate checker
1588 // flag so that they can be selectively disabled.
1589 if (Family == AF_CXXNew || Family == AF_CXXNewArray)
1590 if (!Filter.CNewDeleteLeaksChecker)
1591 return;
1592
Anna Zaksd3571e5a2012-02-11 21:02:40 +00001593 assert(N);
1594 if (!BT_Leak) {
Anna Zaks546c49c2012-02-16 22:26:12 +00001595 BT_Leak.reset(new BugType("Memory leak", "Memory Error"));
Anna Zaksd3571e5a2012-02-11 21:02:40 +00001596 // Leaks should not be reported if they are post-dominated by a sink:
1597 // (1) Sinks are higher importance bugs.
1598 // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
1599 // with __noreturn functions such as assert() or exit(). We choose not
1600 // to report leaks on such paths.
1601 BT_Leak->setSuppressOnSink(true);
1602 }
1603
Anna Zaksdf901a42012-02-23 21:38:21 +00001604 // Most bug reports are cached at the location where they occurred.
1605 // With leaks, we want to unique them by the location where they were
1606 // allocated, and only report a single path.
Anna Zaks43ffba22012-02-27 23:40:55 +00001607 PathDiagnosticLocation LocUsedForUniqueing;
Anna Zaksa043d0c2013-01-08 00:25:29 +00001608 const ExplodedNode *AllocNode = 0;
Anna Zaksfc2e1532012-03-21 19:45:08 +00001609 const MemRegion *Region = 0;
Anna Zaksa043d0c2013-01-08 00:25:29 +00001610 llvm::tie(AllocNode, Region) = getAllocationSite(N, Sym, C);
1611
1612 ProgramPoint P = AllocNode->getLocation();
1613 const Stmt *AllocationStmt = 0;
David Blaikie87396b92013-02-21 22:23:56 +00001614 if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
Anna Zaksa043d0c2013-01-08 00:25:29 +00001615 AllocationStmt = Exit->getCalleeContext()->getCallSite();
David Blaikie87396b92013-02-21 22:23:56 +00001616 else if (Optional<StmtPoint> SP = P.getAs<StmtPoint>())
Anna Zaksa043d0c2013-01-08 00:25:29 +00001617 AllocationStmt = SP->getStmt();
Anton Yartsev6e499252013-04-05 02:25:02 +00001618 if (AllocationStmt)
Anna Zaksa043d0c2013-01-08 00:25:29 +00001619 LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocationStmt,
1620 C.getSourceManager(),
1621 AllocNode->getLocationContext());
Anna Zaksdf901a42012-02-23 21:38:21 +00001622
Anna Zaksfc2e1532012-03-21 19:45:08 +00001623 SmallString<200> buf;
1624 llvm::raw_svector_ostream os(buf);
Jordan Rosed86b3bd2012-08-08 18:23:36 +00001625 if (Region && Region->canPrintPretty()) {
Anna Zaks6cea7d92013-04-12 18:40:21 +00001626 os << "Potential leak of memory pointed to by ";
Jordan Rosed86b3bd2012-08-08 18:23:36 +00001627 Region->printPretty(os);
Anna Zaksa1de8562013-04-06 00:41:36 +00001628 } else {
1629 os << "Potential memory leak";
Anna Zaksfc2e1532012-03-21 19:45:08 +00001630 }
1631
Anna Zaksa043d0c2013-01-08 00:25:29 +00001632 BugReport *R = new BugReport(*BT_Leak, os.str(), N,
1633 LocUsedForUniqueing,
1634 AllocNode->getLocationContext()->getDecl());
Ted Kremenek1e809b42012-03-09 01:13:14 +00001635 R->markInteresting(Sym);
Anna Zaks62cce9e2012-05-10 01:37:40 +00001636 R->addVisitor(new MallocBugVisitor(Sym, true));
Jordan Rosee10d5a72012-11-02 01:53:40 +00001637 C.emitReport(R);
Anna Zaksd3571e5a2012-02-11 21:02:40 +00001638}
1639
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +00001640void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
1641 CheckerContext &C) const
Ted Kremenek90af9092010-12-02 07:49:45 +00001642{
Zhongxing Xubce831f2010-08-15 08:19:57 +00001643 if (!SymReaper.hasDeadSymbols())
1644 return;
Zhongxing Xuc7460962009-11-13 07:48:11 +00001645
Ted Kremenek49b1e382012-01-26 21:29:00 +00001646 ProgramStateRef state = C.getState();
Zhongxing Xubce831f2010-08-15 08:19:57 +00001647 RegionStateTy RS = state->get<RegionState>();
Jordy Rose82584992010-08-18 04:33:47 +00001648 RegionStateTy::Factory &F = state->get_context<RegionState>();
Zhongxing Xubce831f2010-08-15 08:19:57 +00001649
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001650 SmallVector<SymbolRef, 2> Errors;
Zhongxing Xubce831f2010-08-15 08:19:57 +00001651 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
1652 if (SymReaper.isDead(I->first)) {
Anna Zaks58a2c4e2012-10-29 22:51:54 +00001653 if (I->second.isAllocated())
Anna Zaks78edc2f2012-02-09 06:48:19 +00001654 Errors.push_back(I->first);
Jordy Rose82584992010-08-18 04:33:47 +00001655 // Remove the dead symbol from the map.
Ted Kremenekb3b56c62010-11-24 00:54:37 +00001656 RS = F.remove(RS, I->first);
Ted Kremeneke227f492011-07-28 23:07:51 +00001657
Zhongxing Xuc7460962009-11-13 07:48:11 +00001658 }
1659 }
Ted Kremeneke227f492011-07-28 23:07:51 +00001660
Anna Zaksd56c8792012-02-13 18:05:39 +00001661 // Cleanup the Realloc Pairs Map.
Jordan Rose0c153cb2012-11-02 01:54:06 +00001662 ReallocPairsTy RP = state->get<ReallocPairs>();
1663 for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
Anna Zaksac068142012-02-15 00:11:25 +00001664 if (SymReaper.isDead(I->first) ||
1665 SymReaper.isDead(I->second.ReallocatedSym)) {
Anna Zaksd56c8792012-02-13 18:05:39 +00001666 state = state->remove<ReallocPairs>(I->first);
1667 }
1668 }
1669
Anna Zaks67291b92012-11-13 03:18:01 +00001670 // Cleanup the FreeReturnValue Map.
1671 FreeReturnValueTy FR = state->get<FreeReturnValue>();
1672 for (FreeReturnValueTy::iterator I = FR.begin(), E = FR.end(); I != E; ++I) {
1673 if (SymReaper.isDead(I->first) ||
1674 SymReaper.isDead(I->second)) {
1675 state = state->remove<FreeReturnValue>(I->first);
1676 }
1677 }
1678
Anna Zaksdf901a42012-02-23 21:38:21 +00001679 // Generate leak node.
Anna Zaks58a2c4e2012-10-29 22:51:54 +00001680 ExplodedNode *N = C.getPredecessor();
1681 if (!Errors.empty()) {
1682 static SimpleProgramPointTag Tag("MallocChecker : DeadSymbolsLeak");
1683 N = C.addTransition(C.getState(), C.getPredecessor(), &Tag);
Craig Topper2341c0d2013-07-04 03:08:24 +00001684 for (SmallVectorImpl<SymbolRef>::iterator
1685 I = Errors.begin(), E = Errors.end(); I != E; ++I) {
Anna Zaksd3571e5a2012-02-11 21:02:40 +00001686 reportLeak(*I, N, C);
Anna Zaks78edc2f2012-02-09 06:48:19 +00001687 }
Ted Kremeneke227f492011-07-28 23:07:51 +00001688 }
Anna Zaks58a2c4e2012-10-29 22:51:54 +00001689
Anna Zaksdf901a42012-02-23 21:38:21 +00001690 C.addTransition(state->set<RegionState>(RS), N);
Zhongxing Xuc4902a52009-11-13 07:25:27 +00001691}
Zhongxing Xu4668c7e2009-11-17 07:54:15 +00001692
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00001693void MallocChecker::checkPreCall(const CallEvent &Call,
1694 CheckerContext &C) const {
1695
Anna Zaks46d01602012-05-18 01:16:10 +00001696 // We will check for double free in the post visit.
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00001697 if (const AnyFunctionCall *FC = dyn_cast<AnyFunctionCall>(&Call)) {
1698 const FunctionDecl *FD = FC->getDecl();
1699 if (!FD)
1700 return;
Anton Yartsev13df0362013-03-25 01:35:45 +00001701
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00001702 if ((Filter.CMallocOptimistic || Filter.CMallocPessimistic) &&
1703 isFreeFunction(FD, C.getASTContext()))
1704 return;
Anna Zaks3d348342012-02-14 21:55:24 +00001705
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00001706 if (Filter.CNewDeleteChecker &&
1707 isStandardNewDelete(FD, C.getASTContext()))
1708 return;
1709 }
1710
1711 // Check if the callee of a method is deleted.
1712 if (const CXXInstanceCall *CC = dyn_cast<CXXInstanceCall>(&Call)) {
1713 SymbolRef Sym = CC->getCXXThisVal().getAsSymbol();
1714 if (!Sym || checkUseAfterFree(Sym, C, CC->getCXXThisExpr()))
1715 return;
1716 }
1717
1718 // Check arguments for being used after free.
1719 for (unsigned I = 0, E = Call.getNumArgs(); I != E; ++I) {
1720 SVal ArgSVal = Call.getArgSVal(I);
1721 if (ArgSVal.getAs<Loc>()) {
1722 SymbolRef Sym = ArgSVal.getAsSymbol();
Anna Zaks3d348342012-02-14 21:55:24 +00001723 if (!Sym)
1724 continue;
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00001725 if (checkUseAfterFree(Sym, C, Call.getArgExpr(I)))
Anna Zaks3d348342012-02-14 21:55:24 +00001726 return;
1727 }
1728 }
1729}
1730
Anna Zaksa1b227b2012-02-08 23:16:56 +00001731void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
1732 const Expr *E = S->getRetValue();
1733 if (!E)
1734 return;
Anna Zaks3aa52252012-02-11 21:44:39 +00001735
1736 // Check if we are returning a symbol.
Jordan Rose356279c2012-08-08 18:23:31 +00001737 ProgramStateRef State = C.getState();
1738 SVal RetVal = State->getSVal(E, C.getLocationContext());
Anna Zaks4ca45b12012-02-22 02:36:01 +00001739 SymbolRef Sym = RetVal.getAsSymbol();
1740 if (!Sym)
1741 // If we are returning a field of the allocated struct or an array element,
1742 // the callee could still free the memory.
1743 // TODO: This logic should be a part of generic symbol escape callback.
1744 if (const MemRegion *MR = RetVal.getAsRegion())
1745 if (isa<FieldRegion>(MR) || isa<ElementRegion>(MR))
1746 if (const SymbolicRegion *BMR =
1747 dyn_cast<SymbolicRegion>(MR->getBaseRegion()))
1748 Sym = BMR->getSymbol();
Zhongxing Xu23baa012009-11-17 08:58:18 +00001749
Anna Zaks3aa52252012-02-11 21:44:39 +00001750 // Check if we are returning freed memory.
Jordan Rose356279c2012-08-08 18:23:31 +00001751 if (Sym)
Jordan Rosef1f26142012-11-15 19:11:33 +00001752 checkUseAfterFree(Sym, C, E);
Zhongxing Xu23baa012009-11-17 08:58:18 +00001753}
Zhongxing Xub0e15df2009-12-31 06:13:07 +00001754
Anna Zaks9fe80982012-03-22 00:57:20 +00001755// TODO: Blocks should be either inlined or should call invalidate regions
1756// upon invocation. After that's in place, special casing here will not be
1757// needed.
1758void MallocChecker::checkPostStmt(const BlockExpr *BE,
1759 CheckerContext &C) const {
1760
1761 // Scan the BlockDecRefExprs for any object the retain count checker
1762 // may be tracking.
1763 if (!BE->getBlockDecl()->hasCaptures())
1764 return;
1765
1766 ProgramStateRef state = C.getState();
1767 const BlockDataRegion *R =
1768 cast<BlockDataRegion>(state->getSVal(BE,
1769 C.getLocationContext()).getAsRegion());
1770
1771 BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
1772 E = R->referenced_vars_end();
1773
1774 if (I == E)
1775 return;
1776
1777 SmallVector<const MemRegion*, 10> Regions;
1778 const LocationContext *LC = C.getLocationContext();
1779 MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager();
1780
1781 for ( ; I != E; ++I) {
Ted Kremenekbcf90532012-12-06 07:17:20 +00001782 const VarRegion *VR = I.getCapturedRegion();
Anna Zaks9fe80982012-03-22 00:57:20 +00001783 if (VR->getSuperRegion() == R) {
1784 VR = MemMgr.getVarRegion(VR->getDecl(), LC);
1785 }
1786 Regions.push_back(VR);
1787 }
1788
1789 state =
1790 state->scanReachableSymbols<StopTrackingCallback>(Regions.data(),
1791 Regions.data() + Regions.size()).getState();
1792 C.addTransition(state);
1793}
1794
Anna Zaks46d01602012-05-18 01:16:10 +00001795bool MallocChecker::isReleased(SymbolRef Sym, CheckerContext &C) const {
Anna Zaksa1b227b2012-02-08 23:16:56 +00001796 assert(Sym);
1797 const RefState *RS = C.getState()->get<RegionState>(Sym);
Anna Zaks46d01602012-05-18 01:16:10 +00001798 return (RS && RS->isReleased());
1799}
1800
1801bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
1802 const Stmt *S) const {
Anna Zaksa1b227b2012-02-08 23:16:56 +00001803
Jordan Rose1ccc43d2013-09-25 16:06:17 +00001804 // FIXME: Handle destructor called from delete more precisely.
1805 if (isReleased(Sym, C) && S) {
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001806 ReportUseAfterFree(C, S->getSourceRange(), Sym);
1807 return true;
Anna Zaksa1b227b2012-02-08 23:16:56 +00001808 }
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001809
Anna Zaksa1b227b2012-02-08 23:16:56 +00001810 return false;
1811}
1812
Zhongxing Xu1bb6a1a2010-03-10 04:58:55 +00001813// Check if the location is a freed symbolic region.
Anna Zaks3e0f4152011-10-06 00:43:15 +00001814void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
1815 CheckerContext &C) const {
Zhongxing Xu1bb6a1a2010-03-10 04:58:55 +00001816 SymbolRef Sym = l.getLocSymbolInBase();
Anna Zaksa1b227b2012-02-08 23:16:56 +00001817 if (Sym)
Anna Zaks46d01602012-05-18 01:16:10 +00001818 checkUseAfterFree(Sym, C, S);
Zhongxing Xu1bb6a1a2010-03-10 04:58:55 +00001819}
Ted Kremenekd21139a2010-07-31 01:52:11 +00001820
Anna Zaksbb1ef902012-02-11 21:02:35 +00001821// If a symbolic region is assumed to NULL (or another constant), stop tracking
1822// it - assuming that allocation failed on this path.
1823ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state,
1824 SVal Cond,
1825 bool Assumption) const {
1826 RegionStateTy RS = state->get<RegionState>();
Anna Zaksbb1ef902012-02-11 21:02:35 +00001827 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
Ted Kremenek244e1d72012-09-07 22:31:01 +00001828 // If the symbol is assumed to be NULL, remove it from consideration.
Jordan Rose14fe9f32012-11-01 00:18:27 +00001829 ConstraintManager &CMgr = state->getConstraintManager();
1830 ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
1831 if (AllocFailed.isConstrainedTrue())
Anna Zaksbb1ef902012-02-11 21:02:35 +00001832 state = state->remove<RegionState>(I.getKey());
1833 }
1834
Anna Zaksd56c8792012-02-13 18:05:39 +00001835 // Realloc returns 0 when reallocation fails, which means that we should
1836 // restore the state of the pointer being reallocated.
Jordan Rose0c153cb2012-11-02 01:54:06 +00001837 ReallocPairsTy RP = state->get<ReallocPairs>();
1838 for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
Ted Kremenek244e1d72012-09-07 22:31:01 +00001839 // If the symbol is assumed to be NULL, remove it from consideration.
Jordan Rose14fe9f32012-11-01 00:18:27 +00001840 ConstraintManager &CMgr = state->getConstraintManager();
1841 ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
Jordan Rose40bb12492012-11-01 00:25:15 +00001842 if (!AllocFailed.isConstrainedTrue())
Anna Zaks75cfbb62012-09-12 22:57:34 +00001843 continue;
Jordan Rose14fe9f32012-11-01 00:18:27 +00001844
Anna Zaks75cfbb62012-09-12 22:57:34 +00001845 SymbolRef ReallocSym = I.getData().ReallocatedSym;
1846 if (const RefState *RS = state->get<RegionState>(ReallocSym)) {
1847 if (RS->isReleased()) {
1848 if (I.getData().Kind == RPToBeFreedAfterFailure)
Anna Zaksac068142012-02-15 00:11:25 +00001849 state = state->set<RegionState>(ReallocSym,
Anton Yartsev05789592013-03-28 17:05:19 +00001850 RefState::getAllocated(RS->getAllocationFamily(), RS->getStmt()));
Anna Zaks75cfbb62012-09-12 22:57:34 +00001851 else if (I.getData().Kind == RPDoNotTrackAfterFailure)
1852 state = state->remove<RegionState>(ReallocSym);
1853 else
1854 assert(I.getData().Kind == RPIsFreeOnFailure);
Anna Zaksd56c8792012-02-13 18:05:39 +00001855 }
Anna Zaksd56c8792012-02-13 18:05:39 +00001856 }
Anna Zaks75cfbb62012-09-12 22:57:34 +00001857 state = state->remove<ReallocPairs>(I.getKey());
Anna Zaksd56c8792012-02-13 18:05:39 +00001858 }
1859
Anna Zaksbb1ef902012-02-11 21:02:35 +00001860 return state;
1861}
1862
Anna Zaks8ebeb642013-06-08 00:29:29 +00001863bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001864 const CallEvent *Call,
1865 ProgramStateRef State,
1866 SymbolRef &EscapingSymbol) const {
Jordan Rose7ab01822012-07-02 19:27:51 +00001867 assert(Call);
Anna Zaks8ebeb642013-06-08 00:29:29 +00001868 EscapingSymbol = 0;
1869
Anna Zaks7ac344a2012-02-24 23:56:53 +00001870 // For now, assume that any C++ call can free memory.
1871 // TODO: If we want to be more optimistic here, we'll need to make sure that
1872 // regions escape to C++ containers. They seem to do that even now, but for
1873 // mysterious reasons.
Jordan Rose6bad4902012-07-02 19:27:56 +00001874 if (!(isa<FunctionCall>(Call) || isa<ObjCMethodCall>(Call)))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001875 return true;
Anna Zaks7ac344a2012-02-24 23:56:53 +00001876
Jordan Rose742920c2012-07-02 19:27:35 +00001877 // Check Objective-C messages by selector name.
Jordan Rose6bad4902012-07-02 19:27:56 +00001878 if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) {
Jordan Rose7ab01822012-07-02 19:27:51 +00001879 // If it's not a framework call, or if it takes a callback, assume it
1880 // can free memory.
1881 if (!Call->isInSystemHeader() || Call->hasNonZeroCallbackArg())
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001882 return true;
Anna Zaks06a77fc2012-02-28 01:54:22 +00001883
Jordan Rose613f3c02013-03-09 00:59:10 +00001884 // If it's a method we know about, handle it explicitly post-call.
1885 // This should happen before the "freeWhenDone" check below.
1886 if (isKnownDeallocObjCMethodName(*Msg))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001887 return false;
Anna Zaks886dfb82012-06-20 23:35:57 +00001888
Jordan Rose613f3c02013-03-09 00:59:10 +00001889 // If there's a "freeWhenDone" parameter, but the method isn't one we know
1890 // about, we can't be sure that the object will use free() to deallocate the
1891 // memory, so we can't model it explicitly. The best we can do is use it to
1892 // decide whether the pointer escapes.
1893 if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(*Msg))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001894 return *FreeWhenDone;
Anna Zaks7ac344a2012-02-24 23:56:53 +00001895
Jordan Rose613f3c02013-03-09 00:59:10 +00001896 // If the first selector piece ends with "NoCopy", and there is no
1897 // "freeWhenDone" parameter set to zero, we know ownership is being
1898 // transferred. Again, though, we can't be sure that the object will use
1899 // free() to deallocate the memory, so we can't model it explicitly.
1900 StringRef FirstSlot = Msg->getSelector().getNameForSlot(0);
Jordan Rose742920c2012-07-02 19:27:35 +00001901 if (FirstSlot.endswith("NoCopy"))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001902 return true;
Anna Zaks12a8b902012-03-05 17:42:10 +00001903
Anna Zaks42908c72012-06-19 05:10:32 +00001904 // If the first selector starts with addPointer, insertPointer,
1905 // or replacePointer, assume we are dealing with NSPointerArray or similar.
1906 // This is similar to C++ containers (vector); we still might want to check
Jordan Rose742920c2012-07-02 19:27:35 +00001907 // that the pointers get freed by following the container itself.
1908 if (FirstSlot.startswith("addPointer") ||
1909 FirstSlot.startswith("insertPointer") ||
1910 FirstSlot.startswith("replacePointer")) {
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001911 return true;
Anna Zaks42908c72012-06-19 05:10:32 +00001912 }
1913
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001914 // We should escape receiver on call to 'init'. This is especially relevant
1915 // to the receiver, as the corresponding symbol is usually not referenced
1916 // after the call.
1917 if (Msg->getMethodFamily() == OMF_init) {
1918 EscapingSymbol = Msg->getReceiverSVal().getAsSymbol();
1919 return true;
1920 }
Anna Zaks737926b2013-05-31 22:39:13 +00001921
Jordan Rose742920c2012-07-02 19:27:35 +00001922 // Otherwise, assume that the method does not free memory.
1923 // Most framework methods do not free memory.
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001924 return false;
Anna Zaks3d348342012-02-14 21:55:24 +00001925 }
1926
Jordan Rose742920c2012-07-02 19:27:35 +00001927 // At this point the only thing left to handle is straight function calls.
1928 const FunctionDecl *FD = cast<FunctionCall>(Call)->getDecl();
1929 if (!FD)
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001930 return true;
Anna Zaks7ac344a2012-02-24 23:56:53 +00001931
Jordan Rose742920c2012-07-02 19:27:35 +00001932 ASTContext &ASTC = State->getStateManager().getContext();
1933
1934 // If it's one of the allocation functions we can reason about, we model
1935 // its behavior explicitly.
1936 if (isMemFunction(FD, ASTC))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001937 return false;
Jordan Rose742920c2012-07-02 19:27:35 +00001938
1939 // If it's not a system call, assume it frees memory.
1940 if (!Call->isInSystemHeader())
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001941 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00001942
1943 // White list the system functions whose arguments escape.
1944 const IdentifierInfo *II = FD->getIdentifier();
1945 if (!II)
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001946 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00001947 StringRef FName = II->getName();
1948
Jordan Rose742920c2012-07-02 19:27:35 +00001949 // White list the 'XXXNoCopy' CoreFoundation functions.
Jordan Rose7ab01822012-07-02 19:27:51 +00001950 // We specifically check these before
Jordan Rose742920c2012-07-02 19:27:35 +00001951 if (FName.endswith("NoCopy")) {
1952 // Look for the deallocator argument. We know that the memory ownership
1953 // is not transferred only if the deallocator argument is
1954 // 'kCFAllocatorNull'.
1955 for (unsigned i = 1; i < Call->getNumArgs(); ++i) {
1956 const Expr *ArgE = Call->getArgExpr(i)->IgnoreParenCasts();
1957 if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) {
1958 StringRef DeallocatorName = DE->getFoundDecl()->getName();
1959 if (DeallocatorName == "kCFAllocatorNull")
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001960 return false;
Jordan Rose742920c2012-07-02 19:27:35 +00001961 }
1962 }
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001963 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00001964 }
1965
Jordan Rose742920c2012-07-02 19:27:35 +00001966 // Associating streams with malloced buffers. The pointer can escape if
Jordan Rose7ab01822012-07-02 19:27:51 +00001967 // 'closefn' is specified (and if that function does free memory),
1968 // but it will not if closefn is not specified.
Jordan Rose742920c2012-07-02 19:27:35 +00001969 // Currently, we do not inspect the 'closefn' function (PR12101).
1970 if (FName == "funopen")
Jordan Rose7ab01822012-07-02 19:27:51 +00001971 if (Call->getNumArgs() >= 4 && Call->getArgSVal(4).isConstant(0))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001972 return false;
Jordan Rose742920c2012-07-02 19:27:35 +00001973
1974 // Do not warn on pointers passed to 'setbuf' when used with std streams,
1975 // these leaks might be intentional when setting the buffer for stdio.
1976 // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer
1977 if (FName == "setbuf" || FName =="setbuffer" ||
1978 FName == "setlinebuf" || FName == "setvbuf") {
1979 if (Call->getNumArgs() >= 1) {
1980 const Expr *ArgE = Call->getArgExpr(0)->IgnoreParenCasts();
1981 if (const DeclRefExpr *ArgDRE = dyn_cast<DeclRefExpr>(ArgE))
1982 if (const VarDecl *D = dyn_cast<VarDecl>(ArgDRE->getDecl()))
1983 if (D->getCanonicalDecl()->getName().find("std") != StringRef::npos)
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001984 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00001985 }
1986 }
1987
1988 // A bunch of other functions which either take ownership of a pointer or
1989 // wrap the result up in a struct or object, meaning it can be freed later.
1990 // (See RetainCountChecker.) Not all the parameters here are invalidated,
1991 // but the Malloc checker cannot differentiate between them. The right way
1992 // of doing this would be to implement a pointer escapes callback.
1993 if (FName == "CGBitmapContextCreate" ||
1994 FName == "CGBitmapContextCreateWithData" ||
1995 FName == "CVPixelBufferCreateWithBytes" ||
1996 FName == "CVPixelBufferCreateWithPlanarBytes" ||
1997 FName == "OSAtomicEnqueue") {
Anna Zaksa4bc5e12013-05-31 23:47:32 +00001998 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00001999 }
2000
Jordan Rose7ab01822012-07-02 19:27:51 +00002001 // Handle cases where we know a buffer's /address/ can escape.
2002 // Note that the above checks handle some special cases where we know that
2003 // even though the address escapes, it's still our responsibility to free the
2004 // buffer.
2005 if (Call->argumentsMayEscape())
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002006 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00002007
2008 // Otherwise, assume that the function does not free memory.
2009 // Most system calls do not free the memory.
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002010 return false;
Anna Zaks3d348342012-02-14 21:55:24 +00002011}
2012
Anna Zaks333481b2013-03-28 23:15:29 +00002013static bool retTrue(const RefState *RS) {
2014 return true;
2015}
2016
2017static bool checkIfNewOrNewArrayFamily(const RefState *RS) {
2018 return (RS->getAllocationFamily() == AF_CXXNewArray ||
2019 RS->getAllocationFamily() == AF_CXXNew);
2020}
2021
Anna Zaksdc154152012-12-20 00:38:25 +00002022ProgramStateRef MallocChecker::checkPointerEscape(ProgramStateRef State,
2023 const InvalidatedSymbols &Escaped,
Anna Zaksacdc13c2013-02-07 23:05:43 +00002024 const CallEvent *Call,
2025 PointerEscapeKind Kind) const {
Anna Zaks333481b2013-03-28 23:15:29 +00002026 return checkPointerEscapeAux(State, Escaped, Call, Kind, &retTrue);
2027}
2028
2029ProgramStateRef MallocChecker::checkConstPointerEscape(ProgramStateRef State,
2030 const InvalidatedSymbols &Escaped,
2031 const CallEvent *Call,
2032 PointerEscapeKind Kind) const {
2033 return checkPointerEscapeAux(State, Escaped, Call, Kind,
2034 &checkIfNewOrNewArrayFamily);
2035}
2036
2037ProgramStateRef MallocChecker::checkPointerEscapeAux(ProgramStateRef State,
2038 const InvalidatedSymbols &Escaped,
2039 const CallEvent *Call,
2040 PointerEscapeKind Kind,
2041 bool(*CheckRefState)(const RefState*)) const {
Jordan Rose613f3c02013-03-09 00:59:10 +00002042 // If we know that the call does not free memory, or we want to process the
2043 // call later, keep tracking the top level arguments.
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002044 SymbolRef EscapingSymbol = 0;
Jordan Rose757fbb02013-05-10 17:07:16 +00002045 if (Kind == PSK_DirectEscapeOnCall &&
Anna Zaks8ebeb642013-06-08 00:29:29 +00002046 !mayFreeAnyEscapedMemoryOrIsModeledExplicitly(Call, State,
2047 EscapingSymbol) &&
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002048 !EscapingSymbol) {
Anna Zaks3d348342012-02-14 21:55:24 +00002049 return State;
Anna Zaksacdc13c2013-02-07 23:05:43 +00002050 }
Anna Zaks3d348342012-02-14 21:55:24 +00002051
Anna Zaksdc154152012-12-20 00:38:25 +00002052 for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
Anna Zaks333481b2013-03-28 23:15:29 +00002053 E = Escaped.end();
2054 I != E; ++I) {
Anna Zaksbb1ef902012-02-11 21:02:35 +00002055 SymbolRef sym = *I;
Anna Zaksdc154152012-12-20 00:38:25 +00002056
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002057 if (EscapingSymbol && EscapingSymbol != sym)
2058 continue;
2059
Anna Zaks0d6989b2012-06-22 02:04:31 +00002060 if (const RefState *RS = State->get<RegionState>(sym)) {
Anna Zaks93a21a82013-04-09 00:30:28 +00002061 if (RS->isAllocated() && CheckRefState(RS)) {
Anna Zaks23a62012012-08-09 00:42:24 +00002062 State = State->remove<RegionState>(sym);
Anna Zaks93a21a82013-04-09 00:30:28 +00002063 State = State->set<RegionState>(sym, RefState::getEscaped(RS));
2064 }
Anna Zaks0d6989b2012-06-22 02:04:31 +00002065 }
Anna Zaksbb1ef902012-02-11 21:02:35 +00002066 }
Anna Zaks3d348342012-02-14 21:55:24 +00002067 return State;
Ted Kremenekd21139a2010-07-31 01:52:11 +00002068}
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +00002069
Jordy Rosebf38f202012-03-18 07:43:35 +00002070static SymbolRef findFailedReallocSymbol(ProgramStateRef currState,
2071 ProgramStateRef prevState) {
Jordan Rose0c153cb2012-11-02 01:54:06 +00002072 ReallocPairsTy currMap = currState->get<ReallocPairs>();
2073 ReallocPairsTy prevMap = prevState->get<ReallocPairs>();
Jordy Rosebf38f202012-03-18 07:43:35 +00002074
Jordan Rose0c153cb2012-11-02 01:54:06 +00002075 for (ReallocPairsTy::iterator I = prevMap.begin(), E = prevMap.end();
Jordy Rosebf38f202012-03-18 07:43:35 +00002076 I != E; ++I) {
2077 SymbolRef sym = I.getKey();
2078 if (!currMap.lookup(sym))
2079 return sym;
2080 }
2081
2082 return NULL;
2083}
2084
Anna Zaks2b5bb972012-02-09 06:25:51 +00002085PathDiagnosticPiece *
2086MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N,
2087 const ExplodedNode *PrevN,
2088 BugReporterContext &BRC,
2089 BugReport &BR) {
Jordy Rosebf38f202012-03-18 07:43:35 +00002090 ProgramStateRef state = N->getState();
2091 ProgramStateRef statePrev = PrevN->getState();
2092
2093 const RefState *RS = state->get<RegionState>(Sym);
2094 const RefState *RSPrev = statePrev->get<RegionState>(Sym);
Anna Zaks52242a62012-08-03 18:30:18 +00002095 if (!RS)
Anna Zaks2b5bb972012-02-09 06:25:51 +00002096 return 0;
2097
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002098 const Stmt *S = 0;
2099 const char *Msg = 0;
Anna Zakscba4f292012-03-16 23:24:20 +00002100 StackHintGeneratorForSymbol *StackHint = 0;
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002101
2102 // Retrieve the associated statement.
2103 ProgramPoint ProgLoc = N->getLocation();
David Blaikie87396b92013-02-21 22:23:56 +00002104 if (Optional<StmtPoint> SP = ProgLoc.getAs<StmtPoint>()) {
Jordan Rosefbe6dba2012-07-10 22:07:52 +00002105 S = SP->getStmt();
David Blaikie87396b92013-02-21 22:23:56 +00002106 } else if (Optional<CallExitEnd> Exit = ProgLoc.getAs<CallExitEnd>()) {
Jordan Rosefbe6dba2012-07-10 22:07:52 +00002107 S = Exit->getCalleeContext()->getCallSite();
David Blaikie87396b92013-02-21 22:23:56 +00002108 } else if (Optional<BlockEdge> Edge = ProgLoc.getAs<BlockEdge>()) {
Ted Kremenek7505b5a2013-01-04 19:04:36 +00002109 // If an assumption was made on a branch, it should be caught
2110 // here by looking at the state transition.
2111 S = Edge->getSrc()->getTerminator();
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002112 }
Ted Kremenek7505b5a2013-01-04 19:04:36 +00002113
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002114 if (!S)
Anna Zaks2b5bb972012-02-09 06:25:51 +00002115 return 0;
Anna Zaks2b5bb972012-02-09 06:25:51 +00002116
Jordan Rose681cce92012-07-10 22:07:42 +00002117 // FIXME: We will eventually need to handle non-statement-based events
2118 // (__attribute__((cleanup))).
2119
Anna Zaks2b5bb972012-02-09 06:25:51 +00002120 // Find out if this is an interesting point and what is the kind.
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002121 if (Mode == Normal) {
Anna Zaks1ff57d52012-03-15 21:13:02 +00002122 if (isAllocated(RS, RSPrev, S)) {
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002123 Msg = "Memory is allocated";
Anna Zaksa7f457a2012-03-16 23:44:28 +00002124 StackHint = new StackHintGeneratorForSymbol(Sym,
2125 "Returned allocated memory");
Anna Zaks1ff57d52012-03-15 21:13:02 +00002126 } else if (isReleased(RS, RSPrev, S)) {
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002127 Msg = "Memory is released";
Anna Zaksa7f457a2012-03-16 23:44:28 +00002128 StackHint = new StackHintGeneratorForSymbol(Sym,
Anna Zakse4cfcd42013-04-16 00:22:55 +00002129 "Returning; memory was released");
Anna Zaks0d6989b2012-06-22 02:04:31 +00002130 } else if (isRelinquished(RS, RSPrev, S)) {
Alp Toker5faf0c02013-12-02 03:50:25 +00002131 Msg = "Memory ownership is transferred";
Anna Zaks0d6989b2012-06-22 02:04:31 +00002132 StackHint = new StackHintGeneratorForSymbol(Sym, "");
Anna Zaks1ff57d52012-03-15 21:13:02 +00002133 } else if (isReallocFailedCheck(RS, RSPrev, S)) {
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002134 Mode = ReallocationFailed;
2135 Msg = "Reallocation failed";
Anna Zakscba4f292012-03-16 23:24:20 +00002136 StackHint = new StackHintGeneratorForReallocationFailed(Sym,
Anna Zaksa7f457a2012-03-16 23:44:28 +00002137 "Reallocation failed");
Jordy Rosebf38f202012-03-18 07:43:35 +00002138
Jordy Rose21ff76e2012-03-24 03:15:09 +00002139 if (SymbolRef sym = findFailedReallocSymbol(state, statePrev)) {
2140 // Is it possible to fail two reallocs WITHOUT testing in between?
2141 assert((!FailedReallocSymbol || FailedReallocSymbol == sym) &&
2142 "We only support one failed realloc at a time.");
Jordy Rosebf38f202012-03-18 07:43:35 +00002143 BR.markInteresting(sym);
Jordy Rose21ff76e2012-03-24 03:15:09 +00002144 FailedReallocSymbol = sym;
2145 }
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002146 }
2147
2148 // We are in a special mode if a reallocation failed later in the path.
2149 } else if (Mode == ReallocationFailed) {
Jordy Rose21ff76e2012-03-24 03:15:09 +00002150 assert(FailedReallocSymbol && "No symbol to look for.");
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002151
Jordy Rose21ff76e2012-03-24 03:15:09 +00002152 // Is this is the first appearance of the reallocated symbol?
2153 if (!statePrev->get<RegionState>(FailedReallocSymbol)) {
Jordy Rose21ff76e2012-03-24 03:15:09 +00002154 // We're at the reallocation point.
2155 Msg = "Attempt to reallocate memory";
2156 StackHint = new StackHintGeneratorForSymbol(Sym,
2157 "Returned reallocated memory");
2158 FailedReallocSymbol = NULL;
2159 Mode = Normal;
2160 }
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002161 }
2162
Anna Zaks2b5bb972012-02-09 06:25:51 +00002163 if (!Msg)
2164 return 0;
Anna Zakscba4f292012-03-16 23:24:20 +00002165 assert(StackHint);
Anna Zaks2b5bb972012-02-09 06:25:51 +00002166
2167 // Generate the extra diagnostic.
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002168 PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
Anna Zaks2b5bb972012-02-09 06:25:51 +00002169 N->getLocationContext());
Anna Zakscba4f292012-03-16 23:24:20 +00002170 return new PathDiagnosticEventPiece(Pos, Msg, true, StackHint);
Anna Zaks2b5bb972012-02-09 06:25:51 +00002171}
2172
Anna Zaks263b7e02012-05-02 00:05:20 +00002173void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State,
2174 const char *NL, const char *Sep) const {
2175
2176 RegionStateTy RS = State->get<RegionState>();
2177
Ted Kremenek6fcefb52013-01-03 01:30:12 +00002178 if (!RS.isEmpty()) {
2179 Out << Sep << "MallocChecker:" << NL;
2180 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
2181 I.getKey()->dumpToStream(Out);
2182 Out << " : ";
2183 I.getData().dump(Out);
2184 Out << NL;
2185 }
2186 }
Anna Zaks263b7e02012-05-02 00:05:20 +00002187}
Anna Zaks2b5bb972012-02-09 06:25:51 +00002188
Anna Zakse4cfcd42013-04-16 00:22:55 +00002189void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) {
2190 registerCStringCheckerBasic(mgr);
2191 mgr.registerChecker<MallocChecker>()->Filter.CNewDeleteLeaksChecker = true;
2192 // We currently treat NewDeleteLeaks checker as a subchecker of NewDelete
2193 // checker.
2194 mgr.registerChecker<MallocChecker>()->Filter.CNewDeleteChecker = true;
2195}
Anton Yartsev7af0aa82013-04-12 23:25:40 +00002196
Anna Zakscd37bf42012-02-08 23:16:52 +00002197#define REGISTER_CHECKER(name) \
2198void ento::register##name(CheckerManager &mgr) {\
Anna Zakse56167e2012-02-17 22:35:31 +00002199 registerCStringCheckerBasic(mgr); \
Anna Zakscd37bf42012-02-08 23:16:52 +00002200 mgr.registerChecker<MallocChecker>()->Filter.C##name = true;\
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +00002201}
Anna Zakscd37bf42012-02-08 23:16:52 +00002202
2203REGISTER_CHECKER(MallocPessimistic)
2204REGISTER_CHECKER(MallocOptimistic)
Anton Yartsev13df0362013-03-25 01:35:45 +00002205REGISTER_CHECKER(NewDeleteChecker)
Anton Yartsev05789592013-03-28 17:05:19 +00002206REGISTER_CHECKER(MismatchedDeallocatorChecker)