blob: 3ac7105f44d907956700581bfedbde331c696248 [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"
Anton Yartsev4e4cb6b2014-08-05 18:26:05 +000018#include "clang/AST/ParentMap.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000019#include "clang/Basic/SourceManager.h"
Jordan Rose6b33c6f2014-03-26 17:05:46 +000020#include "clang/Basic/TargetInfo.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000021#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
Artem Dergachevb6a513d2017-05-03 11:47:13 +000022#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
Argyrios Kyrtzidis6a5674f2011-03-01 01:16:21 +000023#include "clang/StaticAnalyzer/Core/Checker.h"
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +000024#include "clang/StaticAnalyzer/Core/CheckerManager.h"
Jordan Rose4f7df9b2012-07-26 21:39:41 +000025#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000026#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
Ted Kremenek001fd5b2011-08-15 22:09:50 +000027#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
28#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
Ted Kremenekf8cbac42011-02-10 01:03:03 +000029#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
Benjamin Kramer3307c5082012-02-04 12:31:12 +000030#include "llvm/ADT/STLExtras.h"
Benjamin Kramerea70eb32012-12-01 15:09:41 +000031#include "llvm/ADT/SmallString.h"
Jordan Rosec102b352012-09-22 01:24:42 +000032#include "llvm/ADT/StringExtras.h"
Reka Kovacs18775fc2018-06-09 13:03:49 +000033#include "AllocationState.h"
Anna Zaks199e8e52012-02-22 03:14:20 +000034#include <climits>
Benjamin Kramercfeacf52016-05-27 14:27:13 +000035#include <utility>
Anna Zaks199e8e52012-02-22 03:14:20 +000036
Zhongxing Xu88cca6b2009-11-12 08:38:56 +000037using namespace clang;
Ted Kremenek98857c92010-12-23 07:20:52 +000038using namespace ento;
Zhongxing Xu88cca6b2009-11-12 08:38:56 +000039
40namespace {
41
Anton Yartsev05789592013-03-28 17:05:19 +000042// Used to check correspondence between allocators and deallocators.
43enum AllocationFamily {
44 AF_None,
45 AF_Malloc,
46 AF_CXXNew,
Anna Zaksd79b8402014-10-03 21:48:59 +000047 AF_CXXNewArray,
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +000048 AF_IfNameIndex,
Reka Kovacs18775fc2018-06-09 13:03:49 +000049 AF_Alloca,
Reka Kovacs88ad7042018-07-20 15:14:49 +000050 AF_InnerBuffer
Anton Yartsev05789592013-03-28 17:05:19 +000051};
52
Zhongxing Xu1239de12009-12-11 00:55:44 +000053class RefState {
Anna Zaks9050ffd2012-06-20 20:57:46 +000054 enum Kind { // Reference to allocated memory.
55 Allocated,
Anton Yartsevb50f4ba2015-04-14 14:18:04 +000056 // Reference to zero-allocated memory.
57 AllocatedOfSizeZero,
Anna Zaks9050ffd2012-06-20 20:57:46 +000058 // Reference to released/freed memory.
59 Released,
Alp Toker5faf0c02013-12-02 03:50:25 +000060 // The responsibility for freeing resources has transferred from
Anna Zaks9050ffd2012-06-20 20:57:46 +000061 // this reference. A relinquished symbol should not be freed.
Anna Zaks93a21a82013-04-09 00:30:28 +000062 Relinquished,
63 // We are no longer guaranteed to have observed all manipulations
64 // of this pointer/memory. For example, it could have been
65 // passed as a parameter to an opaque function.
66 Escaped
67 };
Anton Yartsev05789592013-03-28 17:05:19 +000068
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000069 const Stmt *S;
Anton Yartsevb50f4ba2015-04-14 14:18:04 +000070 unsigned K : 3; // Kind enum, but stored as a bitfield.
Ted Kremenek3a0678e2015-09-08 03:50:52 +000071 unsigned Family : 29; // Rest of 32-bit word, currently just an allocation
Anton Yartsev05789592013-03-28 17:05:19 +000072 // family.
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000073
Ted Kremenek3a0678e2015-09-08 03:50:52 +000074 RefState(Kind k, const Stmt *s, unsigned family)
Anna Zaks93a21a82013-04-09 00:30:28 +000075 : S(s), K(k), Family(family) {
76 assert(family != AF_None);
77 }
Zhongxing Xu1239de12009-12-11 00:55:44 +000078public:
Anna Zaks9050ffd2012-06-20 20:57:46 +000079 bool isAllocated() const { return K == Allocated; }
Anton Yartsevb50f4ba2015-04-14 14:18:04 +000080 bool isAllocatedOfSizeZero() const { return K == AllocatedOfSizeZero; }
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000081 bool isReleased() const { return K == Released; }
Anna Zaks9050ffd2012-06-20 20:57:46 +000082 bool isRelinquished() const { return K == Relinquished; }
Anna Zaks93a21a82013-04-09 00:30:28 +000083 bool isEscaped() const { return K == Escaped; }
84 AllocationFamily getAllocationFamily() const {
Anton Yartsev05789592013-03-28 17:05:19 +000085 return (AllocationFamily)Family;
86 }
Anna Zaksd56c8792012-02-13 18:05:39 +000087 const Stmt *getStmt() const { return S; }
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000088
89 bool operator==(const RefState &X) const {
Anton Yartsev05789592013-03-28 17:05:19 +000090 return K == X.K && S == X.S && Family == X.Family;
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000091 }
92
Anton Yartsev05789592013-03-28 17:05:19 +000093 static RefState getAllocated(unsigned family, const Stmt *s) {
94 return RefState(Allocated, s, family);
Zhongxing Xub0e15df2009-12-31 06:13:07 +000095 }
Anton Yartsevb50f4ba2015-04-14 14:18:04 +000096 static RefState getAllocatedOfSizeZero(const RefState *RS) {
97 return RefState(AllocatedOfSizeZero, RS->getStmt(),
98 RS->getAllocationFamily());
99 }
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000100 static RefState getReleased(unsigned family, const Stmt *s) {
Anton Yartsev05789592013-03-28 17:05:19 +0000101 return RefState(Released, s, family);
102 }
103 static RefState getRelinquished(unsigned family, const Stmt *s) {
104 return RefState(Relinquished, s, family);
Ted Kremenek0bbf24d2010-08-06 21:12:55 +0000105 }
Anna Zaks93a21a82013-04-09 00:30:28 +0000106 static RefState getEscaped(const RefState *RS) {
107 return RefState(Escaped, RS->getStmt(), RS->getAllocationFamily());
108 }
Zhongxing Xu4668c7e2009-11-17 07:54:15 +0000109
110 void Profile(llvm::FoldingSetNodeID &ID) const {
111 ID.AddInteger(K);
112 ID.AddPointer(S);
Anton Yartsev05789592013-03-28 17:05:19 +0000113 ID.AddInteger(Family);
Zhongxing Xu4668c7e2009-11-17 07:54:15 +0000114 }
Ted Kremenek6fcefb52013-01-03 01:30:12 +0000115
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000116 void dump(raw_ostream &OS) const {
Jordan Rose6adadb92014-01-23 03:59:01 +0000117 switch (static_cast<Kind>(K)) {
118#define CASE(ID) case ID: OS << #ID; break;
119 CASE(Allocated)
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000120 CASE(AllocatedOfSizeZero)
Jordan Rose6adadb92014-01-23 03:59:01 +0000121 CASE(Released)
122 CASE(Relinquished)
123 CASE(Escaped)
124 }
Ted Kremenek6fcefb52013-01-03 01:30:12 +0000125 }
126
Alp Tokeref6b0072014-01-04 13:47:14 +0000127 LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); }
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000128};
129
Anna Zaks75cfbb62012-09-12 22:57:34 +0000130enum ReallocPairKind {
131 RPToBeFreedAfterFailure,
132 // The symbol has been freed when reallocation failed.
133 RPIsFreeOnFailure,
134 // The symbol does not need to be freed after reallocation fails.
135 RPDoNotTrackAfterFailure
136};
137
Anna Zaksfe6eb672012-08-24 02:28:20 +0000138/// \class ReallocPair
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000139/// Stores information about the symbol being reallocated by a call to
Anna Zaksfe6eb672012-08-24 02:28:20 +0000140/// 'realloc' to allow modeling failed reallocation later in the path.
Anna Zaksac068142012-02-15 00:11:25 +0000141struct ReallocPair {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000142 // The symbol which realloc reallocated.
Anna Zaksac068142012-02-15 00:11:25 +0000143 SymbolRef ReallocatedSym;
Anna Zaks75cfbb62012-09-12 22:57:34 +0000144 ReallocPairKind Kind;
Anna Zaksfe6eb672012-08-24 02:28:20 +0000145
Anna Zaks75cfbb62012-09-12 22:57:34 +0000146 ReallocPair(SymbolRef S, ReallocPairKind K) :
147 ReallocatedSym(S), Kind(K) {}
Anna Zaksac068142012-02-15 00:11:25 +0000148 void Profile(llvm::FoldingSetNodeID &ID) const {
Anna Zaks75cfbb62012-09-12 22:57:34 +0000149 ID.AddInteger(Kind);
Anna Zaksac068142012-02-15 00:11:25 +0000150 ID.AddPointer(ReallocatedSym);
151 }
152 bool operator==(const ReallocPair &X) const {
153 return ReallocatedSym == X.ReallocatedSym &&
Anna Zaks75cfbb62012-09-12 22:57:34 +0000154 Kind == X.Kind;
Anna Zaksac068142012-02-15 00:11:25 +0000155 }
156};
157
Anna Zaksa043d0c2013-01-08 00:25:29 +0000158typedef std::pair<const ExplodedNode*, const MemRegion*> LeakInfo;
Anna Zaksfc2e1532012-03-21 19:45:08 +0000159
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000160class MallocChecker : public Checker<check::DeadSymbols,
Anna Zaksdc154152012-12-20 00:38:25 +0000161 check::PointerEscape,
Anna Zaks333481b2013-03-28 23:15:29 +0000162 check::ConstPointerEscape,
Ted Kremenek778d2bb2012-01-04 23:48:37 +0000163 check::PreStmt<ReturnStmt>,
Reka Kovacs122171e2018-08-02 23:02:08 +0000164 check::EndFunction,
Anton Yartsevcb2ccd62013-04-10 22:21:41 +0000165 check::PreCall,
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000166 check::PostStmt<CallExpr>,
Anton Yartsev13df0362013-03-25 01:35:45 +0000167 check::PostStmt<CXXNewExpr>,
Artem Dergachev13b20262018-01-17 23:46:13 +0000168 check::NewAllocator,
Anton Yartsev13df0362013-03-25 01:35:45 +0000169 check::PreStmt<CXXDeleteExpr>,
Anna Zaks9fe80982012-03-22 00:57:20 +0000170 check::PostStmt<BlockExpr>,
Anna Zaks67291b92012-11-13 03:18:01 +0000171 check::PostObjCMessage,
Ted Kremenek778d2bb2012-01-04 23:48:37 +0000172 check::Location,
Anna Zaksdc154152012-12-20 00:38:25 +0000173 eval::Assume>
Ted Kremenek778d2bb2012-01-04 23:48:37 +0000174{
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000175public:
Craig Topper0dbb7832014-05-27 02:45:47 +0000176 MallocChecker()
Anna Zaks30d46682016-03-08 01:21:51 +0000177 : II_alloca(nullptr), II_win_alloca(nullptr), II_malloc(nullptr),
178 II_free(nullptr), II_realloc(nullptr), II_calloc(nullptr),
179 II_valloc(nullptr), II_reallocf(nullptr), II_strndup(nullptr),
180 II_strdup(nullptr), II_win_strdup(nullptr), II_kmalloc(nullptr),
181 II_if_nameindex(nullptr), II_if_freenameindex(nullptr),
Anna Zaksbbec97c2017-03-09 00:01:01 +0000182 II_wcsdup(nullptr), II_win_wcsdup(nullptr), II_g_malloc(nullptr),
Fangrui Song6907ce22018-07-30 19:24:48 +0000183 II_g_malloc0(nullptr), II_g_realloc(nullptr), II_g_try_malloc(nullptr),
184 II_g_try_malloc0(nullptr), II_g_try_realloc(nullptr),
185 II_g_free(nullptr), II_g_memdup(nullptr), II_g_malloc_n(nullptr),
186 II_g_malloc0_n(nullptr), II_g_realloc_n(nullptr),
187 II_g_try_malloc_n(nullptr), II_g_try_malloc0_n(nullptr),
Leslie Zhaie3986c52017-04-26 05:33:14 +0000188 II_g_try_realloc_n(nullptr) {}
Anna Zakscd37bf42012-02-08 23:16:52 +0000189
190 /// In pessimistic mode, the checker assumes that it does not know which
191 /// functions might free the memory.
Alexander Kornienko4aca9b12014-02-11 21:49:21 +0000192 enum CheckKind {
Gabor Horvathe40c71c2015-03-04 17:59:34 +0000193 CK_MallocChecker,
Alexander Kornienko4aca9b12014-02-11 21:49:21 +0000194 CK_NewDeleteChecker,
195 CK_NewDeleteLeaksChecker,
196 CK_MismatchedDeallocatorChecker,
197 CK_NumCheckKinds
Anna Zakscd37bf42012-02-08 23:16:52 +0000198 };
199
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000200 enum class MemoryOperationKind {
Anna Zaksd79b8402014-10-03 21:48:59 +0000201 MOK_Allocate,
202 MOK_Free,
203 MOK_Any
204 };
205
Gabor Horvathe40c71c2015-03-04 17:59:34 +0000206 DefaultBool IsOptimistic;
207
Alexander Kornienko4aca9b12014-02-11 21:49:21 +0000208 DefaultBool ChecksEnabled[CK_NumCheckKinds];
209 CheckName CheckNames[CK_NumCheckKinds];
Anna Zakscd37bf42012-02-08 23:16:52 +0000210
Anton Yartsevcb2ccd62013-04-10 22:21:41 +0000211 void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000212 void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
Anton Yartsev13df0362013-03-25 01:35:45 +0000213 void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const;
Artem Dergachev13b20262018-01-17 23:46:13 +0000214 void checkNewAllocator(const CXXNewExpr *NE, SVal Target,
215 CheckerContext &C) const;
Anton Yartsev13df0362013-03-25 01:35:45 +0000216 void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
Anna Zaks67291b92012-11-13 03:18:01 +0000217 void checkPostObjCMessage(const ObjCMethodCall &Call, CheckerContext &C) const;
Anna Zaks9fe80982012-03-22 00:57:20 +0000218 void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +0000219 void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +0000220 void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
Reka Kovacs122171e2018-08-02 23:02:08 +0000221 void checkEndFunction(const ReturnStmt *S, CheckerContext &C) const;
Ted Kremenek49b1e382012-01-26 21:29:00 +0000222 ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +0000223 bool Assumption) const;
Anna Zaks3e0f4152011-10-06 00:43:15 +0000224 void checkLocation(SVal l, bool isLoad, const Stmt *S,
225 CheckerContext &C) const;
Anna Zaksdc154152012-12-20 00:38:25 +0000226
227 ProgramStateRef checkPointerEscape(ProgramStateRef State,
228 const InvalidatedSymbols &Escaped,
Anna Zaksacdc13c2013-02-07 23:05:43 +0000229 const CallEvent *Call,
230 PointerEscapeKind Kind) const;
Anna Zaks333481b2013-03-28 23:15:29 +0000231 ProgramStateRef checkConstPointerEscape(ProgramStateRef State,
232 const InvalidatedSymbols &Escaped,
233 const CallEvent *Call,
234 PointerEscapeKind Kind) const;
Zhongxing Xub0e15df2009-12-31 06:13:07 +0000235
Anna Zaks263b7e02012-05-02 00:05:20 +0000236 void printState(raw_ostream &Out, ProgramStateRef State,
Craig Topperfb6b25b2014-03-15 04:29:04 +0000237 const char *NL, const char *Sep) const override;
Anna Zaks263b7e02012-05-02 00:05:20 +0000238
Zhongxing Xuc4902a52009-11-13 07:25:27 +0000239private:
Ahmed Charlesb8984322014-03-07 20:03:18 +0000240 mutable std::unique_ptr<BugType> BT_DoubleFree[CK_NumCheckKinds];
241 mutable std::unique_ptr<BugType> BT_DoubleDelete;
242 mutable std::unique_ptr<BugType> BT_Leak[CK_NumCheckKinds];
243 mutable std::unique_ptr<BugType> BT_UseFree[CK_NumCheckKinds];
244 mutable std::unique_ptr<BugType> BT_BadFree[CK_NumCheckKinds];
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000245 mutable std::unique_ptr<BugType> BT_FreeAlloca[CK_NumCheckKinds];
Ahmed Charlesb8984322014-03-07 20:03:18 +0000246 mutable std::unique_ptr<BugType> BT_MismatchedDealloc;
247 mutable std::unique_ptr<BugType> BT_OffsetFree[CK_NumCheckKinds];
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000248 mutable std::unique_ptr<BugType> BT_UseZerroAllocated[CK_NumCheckKinds];
Anna Zaks30d46682016-03-08 01:21:51 +0000249 mutable IdentifierInfo *II_alloca, *II_win_alloca, *II_malloc, *II_free,
250 *II_realloc, *II_calloc, *II_valloc, *II_reallocf,
251 *II_strndup, *II_strdup, *II_win_strdup, *II_kmalloc,
252 *II_if_nameindex, *II_if_freenameindex, *II_wcsdup,
Fangrui Song6907ce22018-07-30 19:24:48 +0000253 *II_win_wcsdup, *II_g_malloc, *II_g_malloc0,
254 *II_g_realloc, *II_g_try_malloc, *II_g_try_malloc0,
255 *II_g_try_realloc, *II_g_free, *II_g_memdup,
256 *II_g_malloc_n, *II_g_malloc0_n, *II_g_realloc_n,
257 *II_g_try_malloc_n, *II_g_try_malloc0_n,
Leslie Zhaie3986c52017-04-26 05:33:14 +0000258 *II_g_try_realloc_n;
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000259 mutable Optional<uint64_t> KernelZeroFlagVal;
Alexander Kornienko4aca9b12014-02-11 21:49:21 +0000260
Anna Zaks3d348342012-02-14 21:55:24 +0000261 void initIdentifierInfo(ASTContext &C) const;
262
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000263 /// Determine family of a deallocation expression.
Anton Yartseve3377fb2013-04-04 23:46:29 +0000264 AllocationFamily getAllocationFamily(CheckerContext &C, const Stmt *S) const;
Anton Yartsev05789592013-03-28 17:05:19 +0000265
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000266 /// Print names of allocators and deallocators.
Anton Yartsev05789592013-03-28 17:05:19 +0000267 ///
268 /// \returns true on success.
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000269 bool printAllocDeallocName(raw_ostream &os, CheckerContext &C,
Anton Yartsev05789592013-03-28 17:05:19 +0000270 const Expr *E) const;
271
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000272 /// Print expected name of an allocator based on the deallocator's
Anton Yartsev05789592013-03-28 17:05:19 +0000273 /// family derived from the DeallocExpr.
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000274 void printExpectedAllocName(raw_ostream &os, CheckerContext &C,
Anton Yartsev05789592013-03-28 17:05:19 +0000275 const Expr *DeallocExpr) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000276 /// Print expected name of a deallocator based on the allocator's
Anton Yartsev05789592013-03-28 17:05:19 +0000277 /// family.
278 void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) const;
279
Jordan Rose613f3c02013-03-09 00:59:10 +0000280 ///@{
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000281 /// Check if this is one of the functions which can allocate/reallocate memory
Anna Zaks3d348342012-02-14 21:55:24 +0000282 /// pointed to by one of its arguments.
283 bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const;
Anna Zaksd79b8402014-10-03 21:48:59 +0000284 bool isCMemFunction(const FunctionDecl *FD,
285 ASTContext &C,
286 AllocationFamily Family,
Benjamin Kramer719772c2014-10-03 22:20:30 +0000287 MemoryOperationKind MemKind) const;
Anton Yartsev13df0362013-03-25 01:35:45 +0000288 bool isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const;
Jordan Rose613f3c02013-03-09 00:59:10 +0000289 ///@}
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000290
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000291 /// Process C++ operator new()'s allocation, which is the part of C++
Artem Dergachev13b20262018-01-17 23:46:13 +0000292 /// new-expression that goes before the constructor.
293 void processNewAllocation(const CXXNewExpr *NE, CheckerContext &C,
294 SVal Target) const;
295
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000296 /// Perform a zero-allocation check.
Artem Dergachev13b20262018-01-17 23:46:13 +0000297 /// The optional \p RetVal parameter specifies the newly allocated pointer
298 /// value; if unspecified, the value of expression \p E is used.
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000299 ProgramStateRef ProcessZeroAllocation(CheckerContext &C, const Expr *E,
300 const unsigned AllocationSizeArg,
Artem Dergachev13b20262018-01-17 23:46:13 +0000301 ProgramStateRef State,
302 Optional<SVal> RetVal = None) const;
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000303
Richard Smith852e9ce2013-11-27 01:46:48 +0000304 ProgramStateRef MallocMemReturnsAttr(CheckerContext &C,
305 const CallExpr *CE,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000306 const OwnershipAttr* Att,
307 ProgramStateRef State) const;
Ted Kremenek49b1e382012-01-26 21:29:00 +0000308 static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000309 const Expr *SizeEx, SVal Init,
310 ProgramStateRef State,
311 AllocationFamily Family = AF_Malloc);
Ted Kremenek49b1e382012-01-26 21:29:00 +0000312 static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000313 SVal SizeEx, SVal Init,
314 ProgramStateRef State,
315 AllocationFamily Family = AF_Malloc);
Zhongxing Xu527ff6d2010-06-01 03:01:33 +0000316
Gabor Horvath73040272016-09-19 20:39:52 +0000317 static ProgramStateRef addExtentSize(CheckerContext &C, const CXXNewExpr *NE,
Artem Dergachev13b20262018-01-17 23:46:13 +0000318 ProgramStateRef State, SVal Target);
Gabor Horvath73040272016-09-19 20:39:52 +0000319
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000320 // Check if this malloc() for special flags. At present that means M_ZERO or
321 // __GFP_ZERO (in which case, treat it like calloc).
322 llvm::Optional<ProgramStateRef>
323 performKernelMalloc(const CallExpr *CE, CheckerContext &C,
324 const ProgramStateRef &State) const;
325
Anna Zaks40a7eb32012-02-22 19:24:52 +0000326 /// Update the RefState to reflect the new memory allocation.
Artem Dergachev13b20262018-01-17 23:46:13 +0000327 /// The optional \p RetVal parameter specifies the newly allocated pointer
328 /// value; if unspecified, the value of expression \p E is used.
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000329 static ProgramStateRef
Anton Yartsev05789592013-03-28 17:05:19 +0000330 MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State,
Artem Dergachev13b20262018-01-17 23:46:13 +0000331 AllocationFamily Family = AF_Malloc,
332 Optional<SVal> RetVal = None);
Anna Zaks40a7eb32012-02-22 19:24:52 +0000333
334 ProgramStateRef FreeMemAttr(CheckerContext &C, const CallExpr *CE,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000335 const OwnershipAttr* Att,
336 ProgramStateRef State) const;
Ted Kremenek49b1e382012-01-26 21:29:00 +0000337 ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE,
Anna Zaks0d6989b2012-06-22 02:04:31 +0000338 ProgramStateRef state, unsigned Num,
Anna Zaksfe6eb672012-08-24 02:28:20 +0000339 bool Hold,
Anna Zaks67291b92012-11-13 03:18:01 +0000340 bool &ReleasedAllocated,
341 bool ReturnsNullOnFailure = false) const;
Anna Zaks0d6989b2012-06-22 02:04:31 +0000342 ProgramStateRef FreeMemAux(CheckerContext &C, const Expr *Arg,
343 const Expr *ParentExpr,
Anna Zaks67291b92012-11-13 03:18:01 +0000344 ProgramStateRef State,
Anna Zaksfe6eb672012-08-24 02:28:20 +0000345 bool Hold,
Anna Zaks67291b92012-11-13 03:18:01 +0000346 bool &ReleasedAllocated,
347 bool ReturnsNullOnFailure = false) const;
Zhongxing Xuc0484fa2009-12-12 12:29:38 +0000348
Leslie Zhaie3986c52017-04-26 05:33:14 +0000349 ProgramStateRef ReallocMemAux(CheckerContext &C, const CallExpr *CE,
350 bool FreesMemOnFailure,
Fangrui Song6907ce22018-07-30 19:24:48 +0000351 ProgramStateRef State,
Leslie Zhaie3986c52017-04-26 05:33:14 +0000352 bool SuffixWithN = false) const;
353 static SVal evalMulForBufferSize(CheckerContext &C, const Expr *Blocks,
354 const Expr *BlockBytes);
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000355 static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE,
356 ProgramStateRef State);
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000357
Reka Kovacs122171e2018-08-02 23:02:08 +0000358 /// Check if the memory associated with this symbol was released.
Anna Zaks46d01602012-05-18 01:16:10 +0000359 bool isReleased(SymbolRef Sym, CheckerContext &C) const;
360
Anton Yartsev13df0362013-03-25 01:35:45 +0000361 bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const;
Anna Zaksa1b227b2012-02-08 23:16:56 +0000362
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000363 void checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C,
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000364 const Stmt *S) const;
365
Jordan Rose656fdd52014-01-08 18:46:55 +0000366 bool checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const;
367
Anna Zaksa4bc5e12013-05-31 23:47:32 +0000368 /// Check if the function is known free memory, or if it is
Jordan Rose613f3c02013-03-09 00:59:10 +0000369 /// "interesting" and should be modeled explicitly.
370 ///
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000371 /// \param [out] EscapingSymbol A function might not free memory in general,
Anna Zaks8ebeb642013-06-08 00:29:29 +0000372 /// but could be known to free a particular symbol. In this case, false is
Anna Zaksa4bc5e12013-05-31 23:47:32 +0000373 /// returned and the single escaping symbol is returned through the out
374 /// parameter.
375 ///
Jordan Rose613f3c02013-03-09 00:59:10 +0000376 /// We assume that pointers do not escape through calls to system functions
377 /// not handled by this checker.
Anna Zaks8ebeb642013-06-08 00:29:29 +0000378 bool mayFreeAnyEscapedMemoryOrIsModeledExplicitly(const CallEvent *Call,
Anna Zaksa4bc5e12013-05-31 23:47:32 +0000379 ProgramStateRef State,
380 SymbolRef &EscapingSymbol) const;
Anna Zaks3d348342012-02-14 21:55:24 +0000381
Reka Kovacs122171e2018-08-02 23:02:08 +0000382 // Implementation of the checkPointerEscape callbacks.
Anna Zaks333481b2013-03-28 23:15:29 +0000383 ProgramStateRef checkPointerEscapeAux(ProgramStateRef State,
384 const InvalidatedSymbols &Escaped,
385 const CallEvent *Call,
386 PointerEscapeKind Kind,
387 bool(*CheckRefState)(const RefState*)) const;
388
Reka Kovacs122171e2018-08-02 23:02:08 +0000389 // Implementation of the checkPreStmt and checkEndFunction callbacks.
390 void checkEscapeOnReturn(const ReturnStmt *S, CheckerContext &C) const;
391
Anton Yartsev1e2bc9b2013-04-11 00:05:20 +0000392 ///@{
393 /// Tells if a given family/call/symbol is tracked by the current checker.
Anton Yartsev4eb394d2015-03-07 00:31:53 +0000394 /// Sets CheckKind to the kind of the checker responsible for this
395 /// family/call/symbol.
Anton Yartsev2487dd62015-03-10 22:24:21 +0000396 Optional<CheckKind> getCheckIfTracked(AllocationFamily Family,
397 bool IsALeakCheck = false) const;
Anton Yartsev4eb394d2015-03-07 00:31:53 +0000398 Optional<CheckKind> getCheckIfTracked(CheckerContext &C,
Anton Yartsev2487dd62015-03-10 22:24:21 +0000399 const Stmt *AllocDeallocStmt,
400 bool IsALeakCheck = false) const;
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000401 Optional<CheckKind> getCheckIfTracked(CheckerContext &C, SymbolRef Sym,
Anton Yartsev2487dd62015-03-10 22:24:21 +0000402 bool IsALeakCheck = false) const;
Anton Yartsev1e2bc9b2013-04-11 00:05:20 +0000403 ///@}
Ted Kremenek5ef32db2011-08-12 23:37:29 +0000404 static bool SummarizeValue(raw_ostream &os, SVal V);
405 static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000406 void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
Anton Yartsev05789592013-03-28 17:05:19 +0000407 const Expr *DeallocExpr) const;
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000408 void ReportFreeAlloca(CheckerContext &C, SVal ArgVal,
409 SourceRange Range) const;
Anton Yartseve3377fb2013-04-04 23:46:29 +0000410 void ReportMismatchedDealloc(CheckerContext &C, SourceRange Range,
Anton Yartsevf0593d62013-04-05 11:25:10 +0000411 const Expr *DeallocExpr, const RefState *RS,
Anton Yartsevf5bccce2013-09-16 17:51:25 +0000412 SymbolRef Sym, bool OwnershipTransferred) const;
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000413 void ReportOffsetFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
414 const Expr *DeallocExpr,
Craig Topper0dbb7832014-05-27 02:45:47 +0000415 const Expr *AllocExpr = nullptr) const;
Anton Yartsev59ed15b2013-03-13 14:39:10 +0000416 void ReportUseAfterFree(CheckerContext &C, SourceRange Range,
417 SymbolRef Sym) const;
418 void ReportDoubleFree(CheckerContext &C, SourceRange Range, bool Released,
Anton Yartsev6c2af432013-03-13 17:07:32 +0000419 SymbolRef Sym, SymbolRef PrevSym) const;
Anna Zaks2b5bb972012-02-09 06:25:51 +0000420
Jordan Rose656fdd52014-01-08 18:46:55 +0000421 void ReportDoubleDelete(CheckerContext &C, SymbolRef Sym) const;
422
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000423 void ReportUseZeroAllocated(CheckerContext &C, SourceRange Range,
424 SymbolRef Sym) const;
425
Daniel Marjamakia43a8f52017-05-02 11:46:12 +0000426 void ReportFunctionPointerFree(CheckerContext &C, SVal ArgVal,
427 SourceRange Range, const Expr *FreeExpr) const;
428
Anna Zaksdf901a42012-02-23 21:38:21 +0000429 /// Find the location of the allocation for Sym on the path leading to the
430 /// exploded node N.
Anna Zaksfc2e1532012-03-21 19:45:08 +0000431 LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
432 CheckerContext &C) const;
Anna Zaksdf901a42012-02-23 21:38:21 +0000433
Anna Zaksd3571e5a2012-02-11 21:02:40 +0000434 void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const;
435
Anna Zaks2b5bb972012-02-09 06:25:51 +0000436 /// The bug visitor which allows us to print extra diagnostics along the
437 /// BugReport path. For example, showing the allocation site of the leaked
438 /// region.
George Karpenkov70ec1dd2018-06-26 21:12:08 +0000439 class MallocBugVisitor final : public BugReporterVisitor {
Anna Zaks2b5bb972012-02-09 06:25:51 +0000440 protected:
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000441 enum NotificationMode {
442 Normal,
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000443 ReallocationFailed
444 };
445
Anna Zaks2b5bb972012-02-09 06:25:51 +0000446 // The allocated region symbol tracked by the main analysis.
447 SymbolRef Sym;
448
Anna Zaks62cce9e2012-05-10 01:37:40 +0000449 // The mode we are in, i.e. what kind of diagnostics will be emitted.
450 NotificationMode Mode;
Jordy Rose21ff76e2012-03-24 03:15:09 +0000451
Anna Zaks62cce9e2012-05-10 01:37:40 +0000452 // A symbol from when the primary region should have been reallocated.
453 SymbolRef FailedReallocSymbol;
Jordy Rose21ff76e2012-03-24 03:15:09 +0000454
Artem Dergachev5337efc2018-02-27 21:19:33 +0000455 // A C++ destructor stack frame in which memory was released. Used for
456 // miscellaneous false positive suppression.
457 const StackFrameContext *ReleaseDestructorLC;
458
Anna Zaks62cce9e2012-05-10 01:37:40 +0000459 bool IsLeak;
460
461 public:
462 MallocBugVisitor(SymbolRef S, bool isLeak = false)
Artem Dergachev5337efc2018-02-27 21:19:33 +0000463 : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr),
464 ReleaseDestructorLC(nullptr), IsLeak(isLeak) {}
465
466 static void *getTag() {
467 static int Tag = 0;
468 return &Tag;
469 }
Jordy Rose21ff76e2012-03-24 03:15:09 +0000470
Craig Topperfb6b25b2014-03-15 04:29:04 +0000471 void Profile(llvm::FoldingSetNodeID &ID) const override {
Artem Dergachev5337efc2018-02-27 21:19:33 +0000472 ID.AddPointer(getTag());
Anna Zaks2b5bb972012-02-09 06:25:51 +0000473 ID.AddPointer(Sym);
474 }
475
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000476 inline bool isAllocated(const RefState *S, const RefState *SPrev,
477 const Stmt *Stmt) {
Anna Zaks2b5bb972012-02-09 06:25:51 +0000478 // Did not track -> allocated. Other state (released) -> allocated.
Anton Yartsev13df0362013-03-25 01:35:45 +0000479 return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXNewExpr>(Stmt)) &&
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000480 (S && (S->isAllocated() || S->isAllocatedOfSizeZero())) &&
481 (!SPrev || !(SPrev->isAllocated() ||
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000482 SPrev->isAllocatedOfSizeZero())));
Anna Zaks2b5bb972012-02-09 06:25:51 +0000483 }
484
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000485 inline bool isReleased(const RefState *S, const RefState *SPrev,
486 const Stmt *Stmt) {
Anna Zaks2b5bb972012-02-09 06:25:51 +0000487 // Did not track -> released. Other state (allocated) -> released.
Reka Kovacs8707cd12018-07-07 17:22:45 +0000488 // The statement associated with the release might be missing.
489 bool IsReleased = (S && S->isReleased()) &&
490 (!SPrev || !SPrev->isReleased());
491 assert(!IsReleased ||
492 (Stmt && (isa<CallExpr>(Stmt) || isa<CXXDeleteExpr>(Stmt))) ||
Reka Kovacs88ad7042018-07-20 15:14:49 +0000493 (!Stmt && S->getAllocationFamily() == AF_InnerBuffer));
Reka Kovacs8707cd12018-07-07 17:22:45 +0000494 return IsReleased;
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000495 }
496
Anna Zaks0d6989b2012-06-22 02:04:31 +0000497 inline bool isRelinquished(const RefState *S, const RefState *SPrev,
498 const Stmt *Stmt) {
499 // Did not track -> relinquished. Other state (allocated) -> relinquished.
500 return (Stmt && (isa<CallExpr>(Stmt) || isa<ObjCMessageExpr>(Stmt) ||
501 isa<ObjCPropertyRefExpr>(Stmt)) &&
502 (S && S->isRelinquished()) &&
503 (!SPrev || !SPrev->isRelinquished()));
504 }
505
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000506 inline bool isReallocFailedCheck(const RefState *S, const RefState *SPrev,
507 const Stmt *Stmt) {
508 // If the expression is not a call, and the state change is
509 // released -> allocated, it must be the realloc return value
510 // check. If we have to handle more cases here, it might be cleaner just
511 // to track this extra bit in the state itself.
512 return ((!Stmt || !isa<CallExpr>(Stmt)) &&
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000513 (S && (S->isAllocated() || S->isAllocatedOfSizeZero())) &&
514 (SPrev && !(SPrev->isAllocated() ||
515 SPrev->isAllocatedOfSizeZero())));
Anna Zaks2b5bb972012-02-09 06:25:51 +0000516 }
517
David Blaikie0a0c2752017-01-05 17:26:53 +0000518 std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
519 const ExplodedNode *PrevN,
520 BugReporterContext &BRC,
521 BugReport &BR) override;
Anna Zaks62cce9e2012-05-10 01:37:40 +0000522
George Karpenkov70ec1dd2018-06-26 21:12:08 +0000523 std::shared_ptr<PathDiagnosticPiece>
David Blaikied15481c2014-08-29 18:18:43 +0000524 getEndPath(BugReporterContext &BRC, const ExplodedNode *EndPathNode,
525 BugReport &BR) override {
Anna Zaks62cce9e2012-05-10 01:37:40 +0000526 if (!IsLeak)
Craig Topper0dbb7832014-05-27 02:45:47 +0000527 return nullptr;
Anna Zaks62cce9e2012-05-10 01:37:40 +0000528
529 PathDiagnosticLocation L =
530 PathDiagnosticLocation::createEndOfPath(EndPathNode,
531 BRC.getSourceManager());
532 // Do not add the statement itself as a range in case of leak.
George Karpenkov70ec1dd2018-06-26 21:12:08 +0000533 return std::make_shared<PathDiagnosticEventPiece>(L, BR.getDescription(),
David Blaikied15481c2014-08-29 18:18:43 +0000534 false);
Anna Zaks62cce9e2012-05-10 01:37:40 +0000535 }
536
Anna Zakscba4f292012-03-16 23:24:20 +0000537 private:
538 class StackHintGeneratorForReallocationFailed
539 : public StackHintGeneratorForSymbol {
540 public:
541 StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M)
542 : StackHintGeneratorForSymbol(S, M) {}
543
Craig Topperfb6b25b2014-03-15 04:29:04 +0000544 std::string getMessageForArg(const Expr *ArgE,
545 unsigned ArgIndex) override {
Jordan Rosec102b352012-09-22 01:24:42 +0000546 // Printed parameters start at 1, not 0.
547 ++ArgIndex;
548
Anna Zakscba4f292012-03-16 23:24:20 +0000549 SmallString<200> buf;
550 llvm::raw_svector_ostream os(buf);
551
Jordan Rosec102b352012-09-22 01:24:42 +0000552 os << "Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex)
553 << " parameter failed";
Anna Zakscba4f292012-03-16 23:24:20 +0000554
555 return os.str();
556 }
557
Craig Topperfb6b25b2014-03-15 04:29:04 +0000558 std::string getMessageForReturn(const CallExpr *CallExpr) override {
Anna Zaksa7f457a2012-03-16 23:44:28 +0000559 return "Reallocation of returned value failed";
Anna Zakscba4f292012-03-16 23:24:20 +0000560 }
561 };
Anna Zaks2b5bb972012-02-09 06:25:51 +0000562 };
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000563};
Kovarththanan Rajaratnam65c65662009-11-28 06:07:30 +0000564} // end anonymous namespace
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000565
Jordan Rose0c153cb2012-11-02 01:54:06 +0000566REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState)
567REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair)
Devin Coughlin81771732015-09-22 22:47:14 +0000568REGISTER_SET_WITH_PROGRAMSTATE(ReallocSizeZeroSymbols, SymbolRef)
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000569
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000570// A map from the freed symbol to the symbol representing the return value of
Anna Zaks67291b92012-11-13 03:18:01 +0000571// the free function.
572REGISTER_MAP_WITH_PROGRAMSTATE(FreeReturnValue, SymbolRef, SymbolRef)
573
Anna Zaksbb1ef902012-02-11 21:02:35 +0000574namespace {
David Blaikie903c2932015-08-13 22:50:09 +0000575class StopTrackingCallback final : public SymbolVisitor {
Anna Zaksbb1ef902012-02-11 21:02:35 +0000576 ProgramStateRef state;
577public:
Benjamin Kramercfeacf52016-05-27 14:27:13 +0000578 StopTrackingCallback(ProgramStateRef st) : state(std::move(st)) {}
Anna Zaksbb1ef902012-02-11 21:02:35 +0000579 ProgramStateRef getState() const { return state; }
580
Craig Topperfb6b25b2014-03-15 04:29:04 +0000581 bool VisitSymbol(SymbolRef sym) override {
Anna Zaksbb1ef902012-02-11 21:02:35 +0000582 state = state->remove<RegionState>(sym);
583 return true;
584 }
585};
586} // end anonymous namespace
587
Anna Zaks3d348342012-02-14 21:55:24 +0000588void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const {
Anna Zaksb3436602012-05-18 22:47:40 +0000589 if (II_malloc)
590 return;
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000591 II_alloca = &Ctx.Idents.get("alloca");
Anna Zaksb3436602012-05-18 22:47:40 +0000592 II_malloc = &Ctx.Idents.get("malloc");
593 II_free = &Ctx.Idents.get("free");
594 II_realloc = &Ctx.Idents.get("realloc");
595 II_reallocf = &Ctx.Idents.get("reallocf");
596 II_calloc = &Ctx.Idents.get("calloc");
597 II_valloc = &Ctx.Idents.get("valloc");
598 II_strdup = &Ctx.Idents.get("strdup");
599 II_strndup = &Ctx.Idents.get("strndup");
Anna Zaks30d46682016-03-08 01:21:51 +0000600 II_wcsdup = &Ctx.Idents.get("wcsdup");
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000601 II_kmalloc = &Ctx.Idents.get("kmalloc");
Anna Zaksd79b8402014-10-03 21:48:59 +0000602 II_if_nameindex = &Ctx.Idents.get("if_nameindex");
603 II_if_freenameindex = &Ctx.Idents.get("if_freenameindex");
Anna Zaks30d46682016-03-08 01:21:51 +0000604
605 //MSVC uses `_`-prefixed instead, so we check for them too.
606 II_win_strdup = &Ctx.Idents.get("_strdup");
607 II_win_wcsdup = &Ctx.Idents.get("_wcsdup");
608 II_win_alloca = &Ctx.Idents.get("_alloca");
Anna Zaksbbec97c2017-03-09 00:01:01 +0000609
610 // Glib
611 II_g_malloc = &Ctx.Idents.get("g_malloc");
612 II_g_malloc0 = &Ctx.Idents.get("g_malloc0");
613 II_g_realloc = &Ctx.Idents.get("g_realloc");
614 II_g_try_malloc = &Ctx.Idents.get("g_try_malloc");
615 II_g_try_malloc0 = &Ctx.Idents.get("g_try_malloc0");
616 II_g_try_realloc = &Ctx.Idents.get("g_try_realloc");
617 II_g_free = &Ctx.Idents.get("g_free");
618 II_g_memdup = &Ctx.Idents.get("g_memdup");
Leslie Zhaie3986c52017-04-26 05:33:14 +0000619 II_g_malloc_n = &Ctx.Idents.get("g_malloc_n");
620 II_g_malloc0_n = &Ctx.Idents.get("g_malloc0_n");
621 II_g_realloc_n = &Ctx.Idents.get("g_realloc_n");
622 II_g_try_malloc_n = &Ctx.Idents.get("g_try_malloc_n");
623 II_g_try_malloc0_n = &Ctx.Idents.get("g_try_malloc0_n");
624 II_g_try_realloc_n = &Ctx.Idents.get("g_try_realloc_n");
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000625}
626
Anna Zaks3d348342012-02-14 21:55:24 +0000627bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const {
Anna Zaksd79b8402014-10-03 21:48:59 +0000628 if (isCMemFunction(FD, C, AF_Malloc, MemoryOperationKind::MOK_Any))
Anna Zaks46d01602012-05-18 01:16:10 +0000629 return true;
630
Anna Zaksd79b8402014-10-03 21:48:59 +0000631 if (isCMemFunction(FD, C, AF_IfNameIndex, MemoryOperationKind::MOK_Any))
Anna Zaks46d01602012-05-18 01:16:10 +0000632 return true;
633
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000634 if (isCMemFunction(FD, C, AF_Alloca, MemoryOperationKind::MOK_Any))
635 return true;
636
Anton Yartsev13df0362013-03-25 01:35:45 +0000637 if (isStandardNewDelete(FD, C))
638 return true;
639
Anna Zaks46d01602012-05-18 01:16:10 +0000640 return false;
641}
642
Anna Zaksd79b8402014-10-03 21:48:59 +0000643bool MallocChecker::isCMemFunction(const FunctionDecl *FD,
644 ASTContext &C,
645 AllocationFamily Family,
Benjamin Kramer719772c2014-10-03 22:20:30 +0000646 MemoryOperationKind MemKind) const {
Anna Zaksd1ff1cb2012-02-15 02:12:00 +0000647 if (!FD)
648 return false;
Anna Zaks46d01602012-05-18 01:16:10 +0000649
Anna Zaksd79b8402014-10-03 21:48:59 +0000650 bool CheckFree = (MemKind == MemoryOperationKind::MOK_Any ||
651 MemKind == MemoryOperationKind::MOK_Free);
652 bool CheckAlloc = (MemKind == MemoryOperationKind::MOK_Any ||
653 MemKind == MemoryOperationKind::MOK_Allocate);
654
Jordan Rose6cd16c52012-07-10 23:13:01 +0000655 if (FD->getKind() == Decl::Function) {
Anna Zaksd79b8402014-10-03 21:48:59 +0000656 const IdentifierInfo *FunI = FD->getIdentifier();
Jordan Rose6cd16c52012-07-10 23:13:01 +0000657 initIdentifierInfo(C);
Anna Zaks3d348342012-02-14 21:55:24 +0000658
Anna Zaksd79b8402014-10-03 21:48:59 +0000659 if (Family == AF_Malloc && CheckFree) {
Fangrui Song6907ce22018-07-30 19:24:48 +0000660 if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf ||
Anna Zaksbbec97c2017-03-09 00:01:01 +0000661 FunI == II_g_free)
Anna Zaksd79b8402014-10-03 21:48:59 +0000662 return true;
663 }
664
665 if (Family == AF_Malloc && CheckAlloc) {
666 if (FunI == II_malloc || FunI == II_realloc || FunI == II_reallocf ||
667 FunI == II_calloc || FunI == II_valloc || FunI == II_strdup ||
Anna Zaks30d46682016-03-08 01:21:51 +0000668 FunI == II_win_strdup || FunI == II_strndup || FunI == II_wcsdup ||
Anna Zaksbbec97c2017-03-09 00:01:01 +0000669 FunI == II_win_wcsdup || FunI == II_kmalloc ||
Fangrui Song6907ce22018-07-30 19:24:48 +0000670 FunI == II_g_malloc || FunI == II_g_malloc0 ||
671 FunI == II_g_realloc || FunI == II_g_try_malloc ||
Anna Zaksbbec97c2017-03-09 00:01:01 +0000672 FunI == II_g_try_malloc0 || FunI == II_g_try_realloc ||
Fangrui Song6907ce22018-07-30 19:24:48 +0000673 FunI == II_g_memdup || FunI == II_g_malloc_n ||
674 FunI == II_g_malloc0_n || FunI == II_g_realloc_n ||
675 FunI == II_g_try_malloc_n || FunI == II_g_try_malloc0_n ||
Leslie Zhaie3986c52017-04-26 05:33:14 +0000676 FunI == II_g_try_realloc_n)
Anna Zaksd79b8402014-10-03 21:48:59 +0000677 return true;
678 }
679
680 if (Family == AF_IfNameIndex && CheckFree) {
681 if (FunI == II_if_freenameindex)
682 return true;
683 }
684
685 if (Family == AF_IfNameIndex && CheckAlloc) {
686 if (FunI == II_if_nameindex)
687 return true;
688 }
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000689
690 if (Family == AF_Alloca && CheckAlloc) {
Anna Zaks30d46682016-03-08 01:21:51 +0000691 if (FunI == II_alloca || FunI == II_win_alloca)
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000692 return true;
693 }
Jordan Rose6cd16c52012-07-10 23:13:01 +0000694 }
Anna Zaks3d348342012-02-14 21:55:24 +0000695
Anna Zaksd79b8402014-10-03 21:48:59 +0000696 if (Family != AF_Malloc)
Anna Zaks46d01602012-05-18 01:16:10 +0000697 return false;
698
Gabor Horvathe40c71c2015-03-04 17:59:34 +0000699 if (IsOptimistic && FD->hasAttrs()) {
Anna Zaksd79b8402014-10-03 21:48:59 +0000700 for (const auto *I : FD->specific_attrs<OwnershipAttr>()) {
701 OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind();
702 if(OwnKind == OwnershipAttr::Takes || OwnKind == OwnershipAttr::Holds) {
703 if (CheckFree)
704 return true;
705 } else if (OwnKind == OwnershipAttr::Returns) {
706 if (CheckAlloc)
707 return true;
708 }
709 }
Jordan Rose6cd16c52012-07-10 23:13:01 +0000710 }
Anna Zaks3d348342012-02-14 21:55:24 +0000711
Anna Zaks3d348342012-02-14 21:55:24 +0000712 return false;
713}
714
Anton Yartsev8b662702013-03-28 16:10:38 +0000715// Tells if the callee is one of the following:
716// 1) A global non-placement new/delete operator function.
717// 2) A global placement operator function with the single placement argument
718// of type std::nothrow_t.
Anton Yartsev13df0362013-03-25 01:35:45 +0000719bool MallocChecker::isStandardNewDelete(const FunctionDecl *FD,
720 ASTContext &C) const {
721 if (!FD)
722 return false;
723
724 OverloadedOperatorKind Kind = FD->getOverloadedOperator();
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000725 if (Kind != OO_New && Kind != OO_Array_New &&
Anton Yartsev13df0362013-03-25 01:35:45 +0000726 Kind != OO_Delete && Kind != OO_Array_Delete)
727 return false;
728
Anton Yartsev8b662702013-03-28 16:10:38 +0000729 // Skip all operator new/delete methods.
730 if (isa<CXXMethodDecl>(FD))
Anton Yartsev13df0362013-03-25 01:35:45 +0000731 return false;
732
733 // Return true if tested operator is a standard placement nothrow operator.
734 if (FD->getNumParams() == 2) {
735 QualType T = FD->getParamDecl(1)->getType();
736 if (const IdentifierInfo *II = T.getBaseTypeIdentifier())
737 return II->getName().equals("nothrow_t");
738 }
739
740 // Skip placement operators.
741 if (FD->getNumParams() != 1 || FD->isVariadic())
742 return false;
743
744 // One of the standard new/new[]/delete/delete[] non-placement operators.
745 return true;
746}
747
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000748llvm::Optional<ProgramStateRef> MallocChecker::performKernelMalloc(
749 const CallExpr *CE, CheckerContext &C, const ProgramStateRef &State) const {
750 // 3-argument malloc(), as commonly used in {Free,Net,Open}BSD Kernels:
751 //
752 // void *malloc(unsigned long size, struct malloc_type *mtp, int flags);
753 //
754 // One of the possible flags is M_ZERO, which means 'give me back an
755 // allocation which is already zeroed', like calloc.
756
757 // 2-argument kmalloc(), as used in the Linux kernel:
758 //
759 // void *kmalloc(size_t size, gfp_t flags);
760 //
761 // Has the similar flag value __GFP_ZERO.
762
763 // This logic is largely cloned from O_CREAT in UnixAPIChecker, maybe some
764 // code could be shared.
765
766 ASTContext &Ctx = C.getASTContext();
767 llvm::Triple::OSType OS = Ctx.getTargetInfo().getTriple().getOS();
768
769 if (!KernelZeroFlagVal.hasValue()) {
770 if (OS == llvm::Triple::FreeBSD)
771 KernelZeroFlagVal = 0x0100;
772 else if (OS == llvm::Triple::NetBSD)
773 KernelZeroFlagVal = 0x0002;
774 else if (OS == llvm::Triple::OpenBSD)
775 KernelZeroFlagVal = 0x0008;
776 else if (OS == llvm::Triple::Linux)
777 // __GFP_ZERO
778 KernelZeroFlagVal = 0x8000;
779 else
780 // FIXME: We need a more general way of getting the M_ZERO value.
781 // See also: O_CREAT in UnixAPIChecker.cpp.
782
783 // Fall back to normal malloc behavior on platforms where we don't
784 // know M_ZERO.
785 return None;
786 }
787
788 // We treat the last argument as the flags argument, and callers fall-back to
789 // normal malloc on a None return. This works for the FreeBSD kernel malloc
790 // as well as Linux kmalloc.
791 if (CE->getNumArgs() < 2)
792 return None;
793
794 const Expr *FlagsEx = CE->getArg(CE->getNumArgs() - 1);
George Karpenkovd703ec92018-01-17 20:27:29 +0000795 const SVal V = C.getSVal(FlagsEx);
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000796 if (!V.getAs<NonLoc>()) {
797 // The case where 'V' can be a location can only be due to a bad header,
798 // so in this case bail out.
799 return None;
800 }
801
802 NonLoc Flags = V.castAs<NonLoc>();
803 NonLoc ZeroFlag = C.getSValBuilder()
804 .makeIntVal(KernelZeroFlagVal.getValue(), FlagsEx->getType())
805 .castAs<NonLoc>();
806 SVal MaskedFlagsUC = C.getSValBuilder().evalBinOpNN(State, BO_And,
807 Flags, ZeroFlag,
808 FlagsEx->getType());
809 if (MaskedFlagsUC.isUnknownOrUndef())
810 return None;
811 DefinedSVal MaskedFlags = MaskedFlagsUC.castAs<DefinedSVal>();
812
813 // Check if maskedFlags is non-zero.
814 ProgramStateRef TrueState, FalseState;
815 std::tie(TrueState, FalseState) = State->assume(MaskedFlags);
816
817 // If M_ZERO is set, treat this like calloc (initialized).
818 if (TrueState && !FalseState) {
819 SVal ZeroVal = C.getSValBuilder().makeZeroVal(Ctx.CharTy);
820 return MallocMemAux(C, CE, CE->getArg(0), ZeroVal, TrueState);
821 }
822
823 return None;
824}
825
Leslie Zhaie3986c52017-04-26 05:33:14 +0000826SVal MallocChecker::evalMulForBufferSize(CheckerContext &C, const Expr *Blocks,
827 const Expr *BlockBytes) {
828 SValBuilder &SB = C.getSValBuilder();
829 SVal BlocksVal = C.getSVal(Blocks);
830 SVal BlockBytesVal = C.getSVal(BlockBytes);
831 ProgramStateRef State = C.getState();
832 SVal TotalSize = SB.evalBinOp(State, BO_Mul, BlocksVal, BlockBytesVal,
833 SB.getContext().getSizeType());
834 return TotalSize;
835}
836
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000837void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
Jordan Rosed6e5fd52012-09-20 01:55:32 +0000838 if (C.wasInlined)
839 return;
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000840
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000841 const FunctionDecl *FD = C.getCalleeDecl(CE);
842 if (!FD)
843 return;
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000844
Anna Zaks40a7eb32012-02-22 19:24:52 +0000845 ProgramStateRef State = C.getState();
Anna Zaksfe6eb672012-08-24 02:28:20 +0000846 bool ReleasedAllocatedMemory = false;
Jordan Rose6cd16c52012-07-10 23:13:01 +0000847
848 if (FD->getKind() == Decl::Function) {
849 initIdentifierInfo(C.getASTContext());
850 IdentifierInfo *FunI = FD->getIdentifier();
851
Anna Zaksbbec97c2017-03-09 00:01:01 +0000852 if (FunI == II_malloc || FunI == II_g_malloc || FunI == II_g_try_malloc) {
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000853 if (CE->getNumArgs() < 1)
854 return;
855 if (CE->getNumArgs() < 3) {
856 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000857 if (CE->getNumArgs() == 1)
858 State = ProcessZeroAllocation(C, CE, 0, State);
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000859 } else if (CE->getNumArgs() == 3) {
860 llvm::Optional<ProgramStateRef> MaybeState =
861 performKernelMalloc(CE, C, State);
862 if (MaybeState.hasValue())
863 State = MaybeState.getValue();
864 else
865 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
866 }
867 } else if (FunI == II_kmalloc) {
Devin Coughlin684d19d2016-10-16 22:19:03 +0000868 if (CE->getNumArgs() < 1)
869 return;
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000870 llvm::Optional<ProgramStateRef> MaybeState =
871 performKernelMalloc(CE, C, State);
872 if (MaybeState.hasValue())
873 State = MaybeState.getValue();
874 else
875 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
876 } else if (FunI == II_valloc) {
Anton Yartseve3377fb2013-04-04 23:46:29 +0000877 if (CE->getNumArgs() < 1)
878 return;
879 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000880 State = ProcessZeroAllocation(C, CE, 0, State);
Fangrui Song6907ce22018-07-30 19:24:48 +0000881 } else if (FunI == II_realloc || FunI == II_g_realloc ||
Anna Zaksbbec97c2017-03-09 00:01:01 +0000882 FunI == II_g_try_realloc) {
Leslie Zhaie3986c52017-04-26 05:33:14 +0000883 State = ReallocMemAux(C, CE, false, State);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000884 State = ProcessZeroAllocation(C, CE, 1, State);
Anton Yartseve3377fb2013-04-04 23:46:29 +0000885 } else if (FunI == II_reallocf) {
Leslie Zhaie3986c52017-04-26 05:33:14 +0000886 State = ReallocMemAux(C, CE, true, State);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000887 State = ProcessZeroAllocation(C, CE, 1, State);
Anton Yartseve3377fb2013-04-04 23:46:29 +0000888 } else if (FunI == II_calloc) {
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000889 State = CallocMem(C, CE, State);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000890 State = ProcessZeroAllocation(C, CE, 0, State);
891 State = ProcessZeroAllocation(C, CE, 1, State);
Anna Zaksbbec97c2017-03-09 00:01:01 +0000892 } else if (FunI == II_free || FunI == II_g_free) {
Anton Yartseve3377fb2013-04-04 23:46:29 +0000893 State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
Anna Zaks30d46682016-03-08 01:21:51 +0000894 } else if (FunI == II_strdup || FunI == II_win_strdup ||
895 FunI == II_wcsdup || FunI == II_win_wcsdup) {
Anton Yartseve3377fb2013-04-04 23:46:29 +0000896 State = MallocUpdateRefState(C, CE, State);
897 } else if (FunI == II_strndup) {
898 State = MallocUpdateRefState(C, CE, State);
Anna Zaks30d46682016-03-08 01:21:51 +0000899 } else if (FunI == II_alloca || FunI == II_win_alloca) {
Devin Coughlin684d19d2016-10-16 22:19:03 +0000900 if (CE->getNumArgs() < 1)
901 return;
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000902 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
903 AF_Alloca);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000904 State = ProcessZeroAllocation(C, CE, 0, State);
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000905 } else if (isStandardNewDelete(FD, C.getASTContext())) {
Anton Yartseve3377fb2013-04-04 23:46:29 +0000906 // Process direct calls to operator new/new[]/delete/delete[] functions
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000907 // as distinct from new/new[]/delete/delete[] expressions that are
908 // processed by the checkPostStmt callbacks for CXXNewExpr and
Anton Yartseve3377fb2013-04-04 23:46:29 +0000909 // CXXDeleteExpr.
910 OverloadedOperatorKind K = FD->getOverloadedOperator();
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000911 if (K == OO_New) {
Anton Yartseve3377fb2013-04-04 23:46:29 +0000912 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
913 AF_CXXNew);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000914 State = ProcessZeroAllocation(C, CE, 0, State);
915 }
916 else if (K == OO_Array_New) {
Anton Yartseve3377fb2013-04-04 23:46:29 +0000917 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
918 AF_CXXNewArray);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000919 State = ProcessZeroAllocation(C, CE, 0, State);
920 }
Anton Yartseve3377fb2013-04-04 23:46:29 +0000921 else if (K == OO_Delete || K == OO_Array_Delete)
922 State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
923 else
924 llvm_unreachable("not a new/delete operator");
Anna Zaksd79b8402014-10-03 21:48:59 +0000925 } else if (FunI == II_if_nameindex) {
926 // Should we model this differently? We can allocate a fixed number of
927 // elements with zeros in the last one.
928 State = MallocMemAux(C, CE, UnknownVal(), UnknownVal(), State,
929 AF_IfNameIndex);
930 } else if (FunI == II_if_freenameindex) {
931 State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
Anna Zaksbbec97c2017-03-09 00:01:01 +0000932 } else if (FunI == II_g_malloc0 || FunI == II_g_try_malloc0) {
933 if (CE->getNumArgs() < 1)
934 return;
935 SValBuilder &svalBuilder = C.getSValBuilder();
936 SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
937 State = MallocMemAux(C, CE, CE->getArg(0), zeroVal, State);
938 State = ProcessZeroAllocation(C, CE, 0, State);
939 } else if (FunI == II_g_memdup) {
940 if (CE->getNumArgs() < 2)
941 return;
942 State = MallocMemAux(C, CE, CE->getArg(1), UndefinedVal(), State);
943 State = ProcessZeroAllocation(C, CE, 1, State);
Fangrui Song6907ce22018-07-30 19:24:48 +0000944 } else if (FunI == II_g_malloc_n || FunI == II_g_try_malloc_n ||
Leslie Zhaie3986c52017-04-26 05:33:14 +0000945 FunI == II_g_malloc0_n || FunI == II_g_try_malloc0_n) {
946 if (CE->getNumArgs() < 2)
947 return;
948 SVal Init = UndefinedVal();
949 if (FunI == II_g_malloc0_n || FunI == II_g_try_malloc0_n) {
950 SValBuilder &SB = C.getSValBuilder();
951 Init = SB.makeZeroVal(SB.getContext().CharTy);
952 }
953 SVal TotalSize = evalMulForBufferSize(C, CE->getArg(0), CE->getArg(1));
954 State = MallocMemAux(C, CE, TotalSize, Init, State);
955 State = ProcessZeroAllocation(C, CE, 0, State);
956 State = ProcessZeroAllocation(C, CE, 1, State);
957 } else if (FunI == II_g_realloc_n || FunI == II_g_try_realloc_n) {
958 if (CE->getNumArgs() < 3)
959 return;
960 State = ReallocMemAux(C, CE, false, State, true);
961 State = ProcessZeroAllocation(C, CE, 1, State);
962 State = ProcessZeroAllocation(C, CE, 2, State);
Jordan Rose6cd16c52012-07-10 23:13:01 +0000963 }
964 }
965
Gabor Horvathe40c71c2015-03-04 17:59:34 +0000966 if (IsOptimistic || ChecksEnabled[CK_MismatchedDeallocatorChecker]) {
Anna Zaks40a7eb32012-02-22 19:24:52 +0000967 // Check all the attributes, if there are any.
968 // There can be multiple of these attributes.
969 if (FD->hasAttrs())
Aaron Ballmanbe22bcb2014-03-10 17:08:28 +0000970 for (const auto *I : FD->specific_attrs<OwnershipAttr>()) {
971 switch (I->getOwnKind()) {
Anna Zaks40a7eb32012-02-22 19:24:52 +0000972 case OwnershipAttr::Returns:
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000973 State = MallocMemReturnsAttr(C, CE, I, State);
Anna Zaks40a7eb32012-02-22 19:24:52 +0000974 break;
975 case OwnershipAttr::Takes:
976 case OwnershipAttr::Holds:
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000977 State = FreeMemAttr(C, CE, I, State);
Anna Zaks40a7eb32012-02-22 19:24:52 +0000978 break;
979 }
980 }
Zhongxing Xu527ff6d2010-06-01 03:01:33 +0000981 }
Anna Zaks199e8e52012-02-22 03:14:20 +0000982 C.addTransition(State);
Zhongxing Xuc0484fa2009-12-12 12:29:38 +0000983}
984
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000985// Performs a 0-sized allocations check.
Artem Dergachev13b20262018-01-17 23:46:13 +0000986ProgramStateRef MallocChecker::ProcessZeroAllocation(
987 CheckerContext &C, const Expr *E, const unsigned AllocationSizeArg,
988 ProgramStateRef State, Optional<SVal> RetVal) const {
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000989 if (!State)
990 return nullptr;
991
Artem Dergachev13b20262018-01-17 23:46:13 +0000992 if (!RetVal)
993 RetVal = C.getSVal(E);
994
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000995 const Expr *Arg = nullptr;
996
997 if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
998 Arg = CE->getArg(AllocationSizeArg);
999 }
1000 else if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) {
1001 if (NE->isArray())
1002 Arg = NE->getArraySize();
1003 else
1004 return State;
1005 }
1006 else
1007 llvm_unreachable("not a CallExpr or CXXNewExpr");
1008
1009 assert(Arg);
1010
George Karpenkovd703ec92018-01-17 20:27:29 +00001011 Optional<DefinedSVal> DefArgVal = C.getSVal(Arg).getAs<DefinedSVal>();
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00001012
1013 if (!DefArgVal)
1014 return State;
1015
1016 // Check if the allocation size is 0.
1017 ProgramStateRef TrueState, FalseState;
1018 SValBuilder &SvalBuilder = C.getSValBuilder();
1019 DefinedSVal Zero =
1020 SvalBuilder.makeZeroVal(Arg->getType()).castAs<DefinedSVal>();
1021
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001022 std::tie(TrueState, FalseState) =
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00001023 State->assume(SvalBuilder.evalEQ(State, *DefArgVal, Zero));
1024
1025 if (TrueState && !FalseState) {
Artem Dergachev13b20262018-01-17 23:46:13 +00001026 SymbolRef Sym = RetVal->getAsLocSymbol();
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00001027 if (!Sym)
1028 return State;
1029
1030 const RefState *RS = State->get<RegionState>(Sym);
Devin Coughlin81771732015-09-22 22:47:14 +00001031 if (RS) {
1032 if (RS->isAllocated())
1033 return TrueState->set<RegionState>(Sym,
1034 RefState::getAllocatedOfSizeZero(RS));
1035 else
1036 return State;
1037 } else {
1038 // Case of zero-size realloc. Historically 'realloc(ptr, 0)' is treated as
1039 // 'free(ptr)' and the returned value from 'realloc(ptr, 0)' is not
1040 // tracked. Add zero-reallocated Sym to the state to catch references
1041 // to zero-allocated memory.
1042 return TrueState->add<ReallocSizeZeroSymbols>(Sym);
1043 }
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00001044 }
1045
1046 // Assume the value is non-zero going forward.
1047 assert(FalseState);
1048 return FalseState;
1049}
1050
Anton Yartsev4e4cb6b2014-08-05 18:26:05 +00001051static QualType getDeepPointeeType(QualType T) {
1052 QualType Result = T, PointeeType = T->getPointeeType();
1053 while (!PointeeType.isNull()) {
1054 Result = PointeeType;
1055 PointeeType = PointeeType->getPointeeType();
1056 }
1057 return Result;
1058}
1059
1060static bool treatUnusedNewEscaped(const CXXNewExpr *NE) {
1061
1062 const CXXConstructExpr *ConstructE = NE->getConstructExpr();
1063 if (!ConstructE)
1064 return false;
1065
1066 if (!NE->getAllocatedType()->getAsCXXRecordDecl())
1067 return false;
1068
1069 const CXXConstructorDecl *CtorD = ConstructE->getConstructor();
1070
1071 // Iterate over the constructor parameters.
David Majnemer59f77922016-06-24 04:05:48 +00001072 for (const auto *CtorParam : CtorD->parameters()) {
Anton Yartsev4e4cb6b2014-08-05 18:26:05 +00001073
1074 QualType CtorParamPointeeT = CtorParam->getType()->getPointeeType();
1075 if (CtorParamPointeeT.isNull())
1076 continue;
1077
1078 CtorParamPointeeT = getDeepPointeeType(CtorParamPointeeT);
1079
1080 if (CtorParamPointeeT->getAsCXXRecordDecl())
1081 return true;
1082 }
1083
1084 return false;
1085}
1086
Artem Dergachev13b20262018-01-17 23:46:13 +00001087void MallocChecker::processNewAllocation(const CXXNewExpr *NE,
1088 CheckerContext &C,
1089 SVal Target) const {
Anton Yartsev13df0362013-03-25 01:35:45 +00001090 if (NE->getNumPlacementArgs())
1091 for (CXXNewExpr::const_arg_iterator I = NE->placement_arg_begin(),
1092 E = NE->placement_arg_end(); I != E; ++I)
1093 if (SymbolRef Sym = C.getSVal(*I).getAsSymbol())
1094 checkUseAfterFree(Sym, C, *I);
1095
Anton Yartsev13df0362013-03-25 01:35:45 +00001096 if (!isStandardNewDelete(NE->getOperatorNew(), C.getASTContext()))
1097 return;
1098
Anton Yartsev4e4cb6b2014-08-05 18:26:05 +00001099 ParentMap &PM = C.getLocationContext()->getParentMap();
1100 if (!PM.isConsumedExpr(NE) && treatUnusedNewEscaped(NE))
1101 return;
1102
Anton Yartsev13df0362013-03-25 01:35:45 +00001103 ProgramStateRef State = C.getState();
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001104 // The return value from operator new is bound to a specified initialization
1105 // value (if any) and we don't want to loose this value. So we call
1106 // MallocUpdateRefState() instead of MallocMemAux() which breakes the
Anton Yartsev13df0362013-03-25 01:35:45 +00001107 // existing binding.
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001108 State = MallocUpdateRefState(C, NE, State, NE->isArray() ? AF_CXXNewArray
Artem Dergachev13b20262018-01-17 23:46:13 +00001109 : AF_CXXNew, Target);
1110 State = addExtentSize(C, NE, State, Target);
1111 State = ProcessZeroAllocation(C, NE, 0, State, Target);
Anton Yartsev13df0362013-03-25 01:35:45 +00001112 C.addTransition(State);
1113}
1114
Artem Dergachev13b20262018-01-17 23:46:13 +00001115void MallocChecker::checkPostStmt(const CXXNewExpr *NE,
1116 CheckerContext &C) const {
1117 if (!C.getAnalysisManager().getAnalyzerOptions().mayInlineCXXAllocator())
1118 processNewAllocation(NE, C, C.getSVal(NE));
1119}
1120
1121void MallocChecker::checkNewAllocator(const CXXNewExpr *NE, SVal Target,
1122 CheckerContext &C) const {
1123 if (!C.wasInlined)
1124 processNewAllocation(NE, C, Target);
1125}
1126
Gabor Horvath73040272016-09-19 20:39:52 +00001127// Sets the extent value of the MemRegion allocated by
1128// new expression NE to its size in Bytes.
1129//
1130ProgramStateRef MallocChecker::addExtentSize(CheckerContext &C,
1131 const CXXNewExpr *NE,
Artem Dergachev13b20262018-01-17 23:46:13 +00001132 ProgramStateRef State,
1133 SVal Target) {
Gabor Horvath73040272016-09-19 20:39:52 +00001134 if (!State)
1135 return nullptr;
1136 SValBuilder &svalBuilder = C.getSValBuilder();
1137 SVal ElementCount;
Gabor Horvath73040272016-09-19 20:39:52 +00001138 const SubRegion *Region;
1139 if (NE->isArray()) {
1140 const Expr *SizeExpr = NE->getArraySize();
George Karpenkovd703ec92018-01-17 20:27:29 +00001141 ElementCount = C.getSVal(SizeExpr);
Gabor Horvath73040272016-09-19 20:39:52 +00001142 // Store the extent size for the (symbolic)region
1143 // containing the elements.
Artem Dergachev13b20262018-01-17 23:46:13 +00001144 Region = Target.getAsRegion()
Gabor Horvath73040272016-09-19 20:39:52 +00001145 ->getAs<SubRegion>()
Artem Dergachev13b20262018-01-17 23:46:13 +00001146 ->StripCasts()
Gabor Horvath73040272016-09-19 20:39:52 +00001147 ->getAs<SubRegion>();
1148 } else {
1149 ElementCount = svalBuilder.makeIntVal(1, true);
Artem Dergachev13b20262018-01-17 23:46:13 +00001150 Region = Target.getAsRegion()->getAs<SubRegion>();
Gabor Horvath73040272016-09-19 20:39:52 +00001151 }
1152 assert(Region);
1153
1154 // Set the region's extent equal to the Size in Bytes.
1155 QualType ElementType = NE->getAllocatedType();
1156 ASTContext &AstContext = C.getASTContext();
1157 CharUnits TypeSize = AstContext.getTypeSizeInChars(ElementType);
1158
Devin Coughline3b75de2016-12-16 18:41:40 +00001159 if (ElementCount.getAs<NonLoc>()) {
Gabor Horvath73040272016-09-19 20:39:52 +00001160 DefinedOrUnknownSVal Extent = Region->getExtent(svalBuilder);
1161 // size in Bytes = ElementCount*TypeSize
1162 SVal SizeInBytes = svalBuilder.evalBinOpNN(
1163 State, BO_Mul, ElementCount.castAs<NonLoc>(),
1164 svalBuilder.makeArrayIndex(TypeSize.getQuantity()),
1165 svalBuilder.getArrayIndexType());
1166 DefinedOrUnknownSVal extentMatchesSize = svalBuilder.evalEQ(
1167 State, Extent, SizeInBytes.castAs<DefinedOrUnknownSVal>());
1168 State = State->assume(extentMatchesSize, true);
1169 }
1170 return State;
1171}
1172
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001173void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE,
Anton Yartsev13df0362013-03-25 01:35:45 +00001174 CheckerContext &C) const {
1175
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001176 if (!ChecksEnabled[CK_NewDeleteChecker])
Anton Yartsev13df0362013-03-25 01:35:45 +00001177 if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol())
1178 checkUseAfterFree(Sym, C, DE->getArgument());
1179
Anton Yartsev13df0362013-03-25 01:35:45 +00001180 if (!isStandardNewDelete(DE->getOperatorDelete(), C.getASTContext()))
1181 return;
1182
1183 ProgramStateRef State = C.getState();
1184 bool ReleasedAllocated;
1185 State = FreeMemAux(C, DE->getArgument(), DE, State,
1186 /*Hold*/false, ReleasedAllocated);
1187
1188 C.addTransition(State);
1189}
1190
Jordan Rose613f3c02013-03-09 00:59:10 +00001191static bool isKnownDeallocObjCMethodName(const ObjCMethodCall &Call) {
1192 // If the first selector piece is one of the names below, assume that the
1193 // object takes ownership of the memory, promising to eventually deallocate it
1194 // with free().
1195 // Ex: [NSData dataWithBytesNoCopy:bytes length:10];
1196 // (...unless a 'freeWhenDone' parameter is false, but that's checked later.)
1197 StringRef FirstSlot = Call.getSelector().getNameForSlot(0);
Alexander Kornienko9c104902015-12-28 13:06:58 +00001198 return FirstSlot == "dataWithBytesNoCopy" ||
1199 FirstSlot == "initWithBytesNoCopy" ||
1200 FirstSlot == "initWithCharactersNoCopy";
Anna Zaks0d6989b2012-06-22 02:04:31 +00001201}
1202
Jordan Rose613f3c02013-03-09 00:59:10 +00001203static Optional<bool> getFreeWhenDoneArg(const ObjCMethodCall &Call) {
1204 Selector S = Call.getSelector();
1205
1206 // FIXME: We should not rely on fully-constrained symbols being folded.
1207 for (unsigned i = 1; i < S.getNumArgs(); ++i)
1208 if (S.getNameForSlot(i).equals("freeWhenDone"))
1209 return !Call.getArgSVal(i).isZeroConstant();
1210
1211 return None;
1212}
1213
Anna Zaks67291b92012-11-13 03:18:01 +00001214void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call,
1215 CheckerContext &C) const {
Anna Zaksa7b1c472012-12-11 00:17:53 +00001216 if (C.wasInlined)
1217 return;
1218
Jordan Rose613f3c02013-03-09 00:59:10 +00001219 if (!isKnownDeallocObjCMethodName(Call))
1220 return;
Anna Zaks67291b92012-11-13 03:18:01 +00001221
Jordan Rose613f3c02013-03-09 00:59:10 +00001222 if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(Call))
1223 if (!*FreeWhenDone)
1224 return;
1225
1226 bool ReleasedAllocatedMemory;
1227 ProgramStateRef State = FreeMemAux(C, Call.getArgExpr(0),
1228 Call.getOriginExpr(), C.getState(),
1229 /*Hold=*/true, ReleasedAllocatedMemory,
1230 /*RetNullOnFailure=*/true);
1231
1232 C.addTransition(State);
Anna Zaks0d6989b2012-06-22 02:04:31 +00001233}
1234
Richard Smith852e9ce2013-11-27 01:46:48 +00001235ProgramStateRef
1236MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001237 const OwnershipAttr *Att,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001238 ProgramStateRef State) const {
1239 if (!State)
1240 return nullptr;
1241
Richard Smith852e9ce2013-11-27 01:46:48 +00001242 if (Att->getModule() != II_malloc)
Craig Topper0dbb7832014-05-27 02:45:47 +00001243 return nullptr;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001244
Joel E. Dennya6555112018-04-02 19:43:34 +00001245 OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
Ted Kremenekd21139a2010-07-31 01:52:11 +00001246 if (I != E) {
Joel E. Denny81508102018-03-13 14:51:22 +00001247 return MallocMemAux(C, CE, CE->getArg(I->getASTIndex()), UndefinedVal(),
1248 State);
Ted Kremenekd21139a2010-07-31 01:52:11 +00001249 }
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001250 return MallocMemAux(C, CE, UnknownVal(), UndefinedVal(), State);
1251}
1252
1253ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
1254 const CallExpr *CE,
1255 const Expr *SizeEx, SVal Init,
1256 ProgramStateRef State,
1257 AllocationFamily Family) {
1258 if (!State)
1259 return nullptr;
1260
George Karpenkovd703ec92018-01-17 20:27:29 +00001261 return MallocMemAux(C, CE, C.getSVal(SizeEx), Init, State, Family);
Ted Kremenekd21139a2010-07-31 01:52:11 +00001262}
1263
Anna Zaksc68bf4c2012-02-08 20:13:28 +00001264ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00001265 const CallExpr *CE,
Zhongxing Xu527ff6d2010-06-01 03:01:33 +00001266 SVal Size, SVal Init,
Anton Yartsev05789592013-03-28 17:05:19 +00001267 ProgramStateRef State,
1268 AllocationFamily Family) {
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001269 if (!State)
1270 return nullptr;
Anna Zaks3563fde2012-06-07 03:57:32 +00001271
Jordan Rosef69e65f2014-09-05 16:33:51 +00001272 // We expect the malloc functions to return a pointer.
1273 if (!Loc::isLocType(CE->getType()))
1274 return nullptr;
1275
Anna Zaks3563fde2012-06-07 03:57:32 +00001276 // Bind the return value to the symbolic value from the heap region.
1277 // TODO: We could rewrite post visit to eval call; 'malloc' does not have
1278 // side effects other than what we model here.
Ted Kremenekd94854a2012-08-22 06:26:15 +00001279 unsigned Count = C.blockCount();
Anna Zaks3563fde2012-06-07 03:57:32 +00001280 SValBuilder &svalBuilder = C.getSValBuilder();
1281 const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
David Blaikie2fdacbc2013-02-20 05:52:05 +00001282 DefinedSVal RetVal = svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count)
1283 .castAs<DefinedSVal>();
Anton Yartsev05789592013-03-28 17:05:19 +00001284 State = State->BindExpr(CE, C.getLocationContext(), RetVal);
Zhongxing Xu9cb53b82009-12-11 03:09:01 +00001285
Jordy Rose674bd552010-07-04 00:00:41 +00001286 // Fill the region with the initialization value.
Artem Dergachev806486c2018-05-04 21:56:51 +00001287 State = State->bindDefaultInitial(RetVal, Init, LCtx);
Zhongxing Xu527ff6d2010-06-01 03:01:33 +00001288
Jordy Rose674bd552010-07-04 00:00:41 +00001289 // Set the region's extent equal to the Size parameter.
Anna Zaks31886862012-02-10 01:11:00 +00001290 const SymbolicRegion *R =
Anna Zaks3563fde2012-06-07 03:57:32 +00001291 dyn_cast_or_null<SymbolicRegion>(RetVal.getAsRegion());
Anna Zaks199e8e52012-02-22 03:14:20 +00001292 if (!R)
Craig Topper0dbb7832014-05-27 02:45:47 +00001293 return nullptr;
David Blaikie05785d12013-02-20 22:23:23 +00001294 if (Optional<DefinedOrUnknownSVal> DefinedSize =
David Blaikie2fdacbc2013-02-20 05:52:05 +00001295 Size.getAs<DefinedOrUnknownSVal>()) {
Anna Zaks40a7eb32012-02-22 19:24:52 +00001296 SValBuilder &svalBuilder = C.getSValBuilder();
Anna Zaks199e8e52012-02-22 03:14:20 +00001297 DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
Anna Zaks199e8e52012-02-22 03:14:20 +00001298 DefinedOrUnknownSVal extentMatchesSize =
Anton Yartsev05789592013-03-28 17:05:19 +00001299 svalBuilder.evalEQ(State, Extent, *DefinedSize);
Anna Zaks31886862012-02-10 01:11:00 +00001300
Anton Yartsev05789592013-03-28 17:05:19 +00001301 State = State->assume(extentMatchesSize, true);
1302 assert(State);
Anna Zaks199e8e52012-02-22 03:14:20 +00001303 }
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001304
Anton Yartsev05789592013-03-28 17:05:19 +00001305 return MallocUpdateRefState(C, CE, State, Family);
Anna Zaks40a7eb32012-02-22 19:24:52 +00001306}
1307
1308ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C,
Anton Yartsev13df0362013-03-25 01:35:45 +00001309 const Expr *E,
Anton Yartsev05789592013-03-28 17:05:19 +00001310 ProgramStateRef State,
Artem Dergachev13b20262018-01-17 23:46:13 +00001311 AllocationFamily Family,
1312 Optional<SVal> RetVal) {
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001313 if (!State)
1314 return nullptr;
1315
Anna Zaks40a7eb32012-02-22 19:24:52 +00001316 // Get the return value.
Artem Dergachev13b20262018-01-17 23:46:13 +00001317 if (!RetVal)
1318 RetVal = C.getSVal(E);
Anna Zaks40a7eb32012-02-22 19:24:52 +00001319
1320 // We expect the malloc functions to return a pointer.
Artem Dergachev13b20262018-01-17 23:46:13 +00001321 if (!RetVal->getAs<Loc>())
Craig Topper0dbb7832014-05-27 02:45:47 +00001322 return nullptr;
Anna Zaks40a7eb32012-02-22 19:24:52 +00001323
Artem Dergachev13b20262018-01-17 23:46:13 +00001324 SymbolRef Sym = RetVal->getAsLocSymbol();
1325 // This is a return value of a function that was not inlined, such as malloc()
1326 // or new(). We've checked that in the caller. Therefore, it must be a symbol.
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001327 assert(Sym);
Ted Kremenek90af9092010-12-02 07:49:45 +00001328
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001329 // Set the symbol's state to Allocated.
Anton Yartsev05789592013-03-28 17:05:19 +00001330 return State->set<RegionState>(Sym, RefState::getAllocated(Family, E));
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001331}
1332
Anna Zaks40a7eb32012-02-22 19:24:52 +00001333ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C,
1334 const CallExpr *CE,
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001335 const OwnershipAttr *Att,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001336 ProgramStateRef State) const {
1337 if (!State)
1338 return nullptr;
1339
Richard Smith852e9ce2013-11-27 01:46:48 +00001340 if (Att->getModule() != II_malloc)
Craig Topper0dbb7832014-05-27 02:45:47 +00001341 return nullptr;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001342
Anna Zaksfe6eb672012-08-24 02:28:20 +00001343 bool ReleasedAllocated = false;
Anna Zaks8dc53af2012-03-01 22:06:06 +00001344
Aaron Ballmana82eaa72014-05-02 13:35:42 +00001345 for (const auto &Arg : Att->args()) {
Joel E. Denny81508102018-03-13 14:51:22 +00001346 ProgramStateRef StateI = FreeMemAux(
1347 C, CE, State, Arg.getASTIndex(),
1348 Att->getOwnKind() == OwnershipAttr::Holds, ReleasedAllocated);
Anna Zaks8dc53af2012-03-01 22:06:06 +00001349 if (StateI)
1350 State = StateI;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001351 }
Anna Zaks8dc53af2012-03-01 22:06:06 +00001352 return State;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001353}
1354
Ted Kremenek49b1e382012-01-26 21:29:00 +00001355ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
Anna Zaks31886862012-02-10 01:11:00 +00001356 const CallExpr *CE,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001357 ProgramStateRef State,
Anna Zaks31886862012-02-10 01:11:00 +00001358 unsigned Num,
Anna Zaksfe6eb672012-08-24 02:28:20 +00001359 bool Hold,
Anna Zaks67291b92012-11-13 03:18:01 +00001360 bool &ReleasedAllocated,
1361 bool ReturnsNullOnFailure) const {
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001362 if (!State)
1363 return nullptr;
1364
Anna Zaksb508d292012-04-10 23:41:11 +00001365 if (CE->getNumArgs() < (Num + 1))
Craig Topper0dbb7832014-05-27 02:45:47 +00001366 return nullptr;
Anna Zaksb508d292012-04-10 23:41:11 +00001367
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001368 return FreeMemAux(C, CE->getArg(Num), CE, State, Hold,
Anna Zaks67291b92012-11-13 03:18:01 +00001369 ReleasedAllocated, ReturnsNullOnFailure);
1370}
1371
Anna Zaksa14c1d02012-11-13 19:47:40 +00001372/// Checks if the previous call to free on the given symbol failed - if free
1373/// failed, returns true. Also, returns the corresponding return value symbol.
Benjamin Kramerba4c85e2012-11-22 15:02:44 +00001374static bool didPreviousFreeFail(ProgramStateRef State,
1375 SymbolRef Sym, SymbolRef &RetStatusSymbol) {
Anna Zaksa14c1d02012-11-13 19:47:40 +00001376 const SymbolRef *Ret = State->get<FreeReturnValue>(Sym);
Anna Zaks67291b92012-11-13 03:18:01 +00001377 if (Ret) {
1378 assert(*Ret && "We should not store the null return symbol");
1379 ConstraintManager &CMgr = State->getConstraintManager();
1380 ConditionTruthVal FreeFailed = CMgr.isNull(State, *Ret);
Anna Zaksa14c1d02012-11-13 19:47:40 +00001381 RetStatusSymbol = *Ret;
1382 return FreeFailed.isConstrainedTrue();
Anna Zaks67291b92012-11-13 03:18:01 +00001383 }
Anna Zaksa14c1d02012-11-13 19:47:40 +00001384 return false;
Anna Zaks0d6989b2012-06-22 02:04:31 +00001385}
1386
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001387AllocationFamily MallocChecker::getAllocationFamily(CheckerContext &C,
Anton Yartseve3377fb2013-04-04 23:46:29 +00001388 const Stmt *S) const {
1389 if (!S)
Anton Yartsev05789592013-03-28 17:05:19 +00001390 return AF_None;
1391
Anton Yartseve3377fb2013-04-04 23:46:29 +00001392 if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
Anton Yartsev05789592013-03-28 17:05:19 +00001393 const FunctionDecl *FD = C.getCalleeDecl(CE);
Anton Yartseve3377fb2013-04-04 23:46:29 +00001394
1395 if (!FD)
1396 FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
1397
Anton Yartsev05789592013-03-28 17:05:19 +00001398 ASTContext &Ctx = C.getASTContext();
1399
Anna Zaksd79b8402014-10-03 21:48:59 +00001400 if (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Any))
Anton Yartsev05789592013-03-28 17:05:19 +00001401 return AF_Malloc;
1402
1403 if (isStandardNewDelete(FD, Ctx)) {
1404 OverloadedOperatorKind Kind = FD->getOverloadedOperator();
Anton Yartseve3377fb2013-04-04 23:46:29 +00001405 if (Kind == OO_New || Kind == OO_Delete)
Anton Yartsev05789592013-03-28 17:05:19 +00001406 return AF_CXXNew;
Anton Yartseve3377fb2013-04-04 23:46:29 +00001407 else if (Kind == OO_Array_New || Kind == OO_Array_Delete)
Anton Yartsev05789592013-03-28 17:05:19 +00001408 return AF_CXXNewArray;
1409 }
1410
Anna Zaksd79b8402014-10-03 21:48:59 +00001411 if (isCMemFunction(FD, Ctx, AF_IfNameIndex, MemoryOperationKind::MOK_Any))
1412 return AF_IfNameIndex;
1413
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001414 if (isCMemFunction(FD, Ctx, AF_Alloca, MemoryOperationKind::MOK_Any))
1415 return AF_Alloca;
1416
Anton Yartsev05789592013-03-28 17:05:19 +00001417 return AF_None;
1418 }
1419
Anton Yartseve3377fb2013-04-04 23:46:29 +00001420 if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(S))
1421 return NE->isArray() ? AF_CXXNewArray : AF_CXXNew;
1422
1423 if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(S))
Anton Yartsev05789592013-03-28 17:05:19 +00001424 return DE->isArrayForm() ? AF_CXXNewArray : AF_CXXNew;
1425
Anton Yartseve3377fb2013-04-04 23:46:29 +00001426 if (isa<ObjCMessageExpr>(S))
Anton Yartsev05789592013-03-28 17:05:19 +00001427 return AF_Malloc;
1428
1429 return AF_None;
1430}
1431
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001432bool MallocChecker::printAllocDeallocName(raw_ostream &os, CheckerContext &C,
Anton Yartsev05789592013-03-28 17:05:19 +00001433 const Expr *E) const {
1434 if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
1435 // FIXME: This doesn't handle indirect calls.
1436 const FunctionDecl *FD = CE->getDirectCallee();
1437 if (!FD)
1438 return false;
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001439
Anton Yartsev05789592013-03-28 17:05:19 +00001440 os << *FD;
1441 if (!FD->isOverloadedOperator())
1442 os << "()";
1443 return true;
1444 }
1445
1446 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) {
1447 if (Msg->isInstanceMessage())
1448 os << "-";
1449 else
1450 os << "+";
Aaron Ballmanb190f972014-01-03 17:59:55 +00001451 Msg->getSelector().print(os);
Anton Yartsev05789592013-03-28 17:05:19 +00001452 return true;
1453 }
1454
1455 if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) {
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001456 os << "'"
Anton Yartsev05789592013-03-28 17:05:19 +00001457 << getOperatorSpelling(NE->getOperatorNew()->getOverloadedOperator())
1458 << "'";
1459 return true;
1460 }
1461
1462 if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(E)) {
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001463 os << "'"
Anton Yartsev05789592013-03-28 17:05:19 +00001464 << getOperatorSpelling(DE->getOperatorDelete()->getOverloadedOperator())
1465 << "'";
1466 return true;
1467 }
1468
1469 return false;
1470}
1471
1472void MallocChecker::printExpectedAllocName(raw_ostream &os, CheckerContext &C,
1473 const Expr *E) const {
1474 AllocationFamily Family = getAllocationFamily(C, E);
1475
1476 switch(Family) {
1477 case AF_Malloc: os << "malloc()"; return;
1478 case AF_CXXNew: os << "'new'"; return;
1479 case AF_CXXNewArray: os << "'new[]'"; return;
Anna Zaksd79b8402014-10-03 21:48:59 +00001480 case AF_IfNameIndex: os << "'if_nameindex()'"; return;
Reka Kovacs88ad7042018-07-20 15:14:49 +00001481 case AF_InnerBuffer: os << "container-specific allocator"; return;
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001482 case AF_Alloca:
Anton Yartsev05789592013-03-28 17:05:19 +00001483 case AF_None: llvm_unreachable("not a deallocation expression");
1484 }
1485}
1486
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001487void MallocChecker::printExpectedDeallocName(raw_ostream &os,
Anton Yartsev05789592013-03-28 17:05:19 +00001488 AllocationFamily Family) const {
1489 switch(Family) {
1490 case AF_Malloc: os << "free()"; return;
1491 case AF_CXXNew: os << "'delete'"; return;
1492 case AF_CXXNewArray: os << "'delete[]'"; return;
Anna Zaksd79b8402014-10-03 21:48:59 +00001493 case AF_IfNameIndex: os << "'if_freenameindex()'"; return;
Reka Kovacs88ad7042018-07-20 15:14:49 +00001494 case AF_InnerBuffer: os << "container-specific deallocator"; return;
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001495 case AF_Alloca:
1496 case AF_None: llvm_unreachable("suspicious argument");
Anton Yartsev05789592013-03-28 17:05:19 +00001497 }
1498}
1499
Anna Zaks0d6989b2012-06-22 02:04:31 +00001500ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
1501 const Expr *ArgExpr,
1502 const Expr *ParentExpr,
Anna Zaks67291b92012-11-13 03:18:01 +00001503 ProgramStateRef State,
Anna Zaksfe6eb672012-08-24 02:28:20 +00001504 bool Hold,
Anna Zaks67291b92012-11-13 03:18:01 +00001505 bool &ReleasedAllocated,
1506 bool ReturnsNullOnFailure) const {
Anna Zaks0d6989b2012-06-22 02:04:31 +00001507
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001508 if (!State)
1509 return nullptr;
1510
George Karpenkovd703ec92018-01-17 20:27:29 +00001511 SVal ArgVal = C.getSVal(ArgExpr);
David Blaikie2fdacbc2013-02-20 05:52:05 +00001512 if (!ArgVal.getAs<DefinedOrUnknownSVal>())
Craig Topper0dbb7832014-05-27 02:45:47 +00001513 return nullptr;
David Blaikie2fdacbc2013-02-20 05:52:05 +00001514 DefinedOrUnknownSVal location = ArgVal.castAs<DefinedOrUnknownSVal>();
Ted Kremenekd21139a2010-07-31 01:52:11 +00001515
1516 // Check for null dereferences.
David Blaikie2fdacbc2013-02-20 05:52:05 +00001517 if (!location.getAs<Loc>())
Craig Topper0dbb7832014-05-27 02:45:47 +00001518 return nullptr;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001519
Anna Zaksad01ef52012-02-14 00:26:13 +00001520 // The explicit NULL case, no operation is performed.
Ted Kremenek49b1e382012-01-26 21:29:00 +00001521 ProgramStateRef notNullState, nullState;
Benjamin Kramer867ea1d2014-03-02 13:01:17 +00001522 std::tie(notNullState, nullState) = State->assume(location);
Ted Kremenekd21139a2010-07-31 01:52:11 +00001523 if (nullState && !notNullState)
Craig Topper0dbb7832014-05-27 02:45:47 +00001524 return nullptr;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001525
Jordy Rose3597b212010-06-07 19:32:37 +00001526 // Unknown values could easily be okay
1527 // Undefined values are handled elsewhere
1528 if (ArgVal.isUnknownOrUndef())
Craig Topper0dbb7832014-05-27 02:45:47 +00001529 return nullptr;
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001530
Jordy Rose3597b212010-06-07 19:32:37 +00001531 const MemRegion *R = ArgVal.getAsRegion();
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001532
Jordy Rose3597b212010-06-07 19:32:37 +00001533 // Nonlocs can't be freed, of course.
1534 // Non-region locations (labels and fixed addresses) also shouldn't be freed.
1535 if (!R) {
Anton Yartsev05789592013-03-28 17:05:19 +00001536 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
Craig Topper0dbb7832014-05-27 02:45:47 +00001537 return nullptr;
Jordy Rose3597b212010-06-07 19:32:37 +00001538 }
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001539
Jordy Rose3597b212010-06-07 19:32:37 +00001540 R = R->StripCasts();
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001541
Jordy Rose3597b212010-06-07 19:32:37 +00001542 // Blocks might show up as heap data, but should not be free()d
1543 if (isa<BlockDataRegion>(R)) {
Anton Yartsev05789592013-03-28 17:05:19 +00001544 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
Craig Topper0dbb7832014-05-27 02:45:47 +00001545 return nullptr;
Jordy Rose3597b212010-06-07 19:32:37 +00001546 }
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001547
Jordy Rose3597b212010-06-07 19:32:37 +00001548 const MemSpaceRegion *MS = R->getMemorySpace();
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001549
1550 // Parameters, locals, statics, globals, and memory returned by
Anton Yartsevc38d7952015-03-03 22:58:46 +00001551 // __builtin_alloca() shouldn't be freed.
Jordy Rose3597b212010-06-07 19:32:37 +00001552 if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
1553 // FIXME: at the time this code was written, malloc() regions were
1554 // represented by conjured symbols, which are all in UnknownSpaceRegion.
1555 // This means that there isn't actually anything from HeapSpaceRegion
1556 // that should be freed, even though we allow it here.
1557 // Of course, free() can work on memory allocated outside the current
1558 // function, so UnknownSpaceRegion is always a possibility.
1559 // False negatives are better than false positives.
Anton Yartsevc38d7952015-03-03 22:58:46 +00001560
1561 if (isa<AllocaRegion>(R))
1562 ReportFreeAlloca(C, ArgVal, ArgExpr->getSourceRange());
1563 else
1564 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
1565
Craig Topper0dbb7832014-05-27 02:45:47 +00001566 return nullptr;
Jordy Rose3597b212010-06-07 19:32:37 +00001567 }
Anna Zaksc89ad072013-02-07 23:05:47 +00001568
1569 const SymbolicRegion *SrBase = dyn_cast<SymbolicRegion>(R->getBaseRegion());
Jordy Rose3597b212010-06-07 19:32:37 +00001570 // Various cases could lead to non-symbol values here.
1571 // For now, ignore them.
Anna Zaksc89ad072013-02-07 23:05:47 +00001572 if (!SrBase)
Craig Topper0dbb7832014-05-27 02:45:47 +00001573 return nullptr;
Jordy Rose3597b212010-06-07 19:32:37 +00001574
Anna Zaksc89ad072013-02-07 23:05:47 +00001575 SymbolRef SymBase = SrBase->getSymbol();
1576 const RefState *RsBase = State->get<RegionState>(SymBase);
Craig Topper0dbb7832014-05-27 02:45:47 +00001577 SymbolRef PreviousRetStatusSymbol = nullptr;
Zhongxing Xue2bdb9a2010-01-18 03:27:34 +00001578
Anton Yartseve3377fb2013-04-04 23:46:29 +00001579 if (RsBase) {
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001580
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001581 // Memory returned by alloca() shouldn't be freed.
1582 if (RsBase->getAllocationFamily() == AF_Alloca) {
1583 ReportFreeAlloca(C, ArgVal, ArgExpr->getSourceRange());
1584 return nullptr;
1585 }
1586
Anna Zaks93a21a82013-04-09 00:30:28 +00001587 // Check for double free first.
1588 if ((RsBase->isReleased() || RsBase->isRelinquished()) &&
Anton Yartseve3377fb2013-04-04 23:46:29 +00001589 !didPreviousFreeFail(State, SymBase, PreviousRetStatusSymbol)) {
1590 ReportDoubleFree(C, ParentExpr->getSourceRange(), RsBase->isReleased(),
1591 SymBase, PreviousRetStatusSymbol);
Craig Topper0dbb7832014-05-27 02:45:47 +00001592 return nullptr;
Anton Yartseve3377fb2013-04-04 23:46:29 +00001593
Anna Zaks93a21a82013-04-09 00:30:28 +00001594 // If the pointer is allocated or escaped, but we are now trying to free it,
1595 // check that the call to free is proper.
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001596 } else if (RsBase->isAllocated() || RsBase->isAllocatedOfSizeZero() ||
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00001597 RsBase->isEscaped()) {
Anna Zaks93a21a82013-04-09 00:30:28 +00001598
1599 // Check if an expected deallocation function matches the real one.
1600 bool DeallocMatchesAlloc =
1601 RsBase->getAllocationFamily() == getAllocationFamily(C, ParentExpr);
1602 if (!DeallocMatchesAlloc) {
1603 ReportMismatchedDealloc(C, ArgExpr->getSourceRange(),
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001604 ParentExpr, RsBase, SymBase, Hold);
Craig Topper0dbb7832014-05-27 02:45:47 +00001605 return nullptr;
Anna Zaks93a21a82013-04-09 00:30:28 +00001606 }
1607
1608 // Check if the memory location being freed is the actual location
1609 // allocated, or an offset.
1610 RegionOffset Offset = R->getAsOffset();
1611 if (Offset.isValid() &&
1612 !Offset.hasSymbolicOffset() &&
1613 Offset.getOffset() != 0) {
1614 const Expr *AllocExpr = cast<Expr>(RsBase->getStmt());
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001615 ReportOffsetFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
Anna Zaks93a21a82013-04-09 00:30:28 +00001616 AllocExpr);
Craig Topper0dbb7832014-05-27 02:45:47 +00001617 return nullptr;
Anna Zaks93a21a82013-04-09 00:30:28 +00001618 }
Anton Yartseve3377fb2013-04-04 23:46:29 +00001619 }
Anna Zaksc89ad072013-02-07 23:05:47 +00001620 }
1621
Daniel Marjamakia43a8f52017-05-02 11:46:12 +00001622 if (SymBase->getType()->isFunctionPointerType()) {
1623 ReportFunctionPointerFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
1624 return nullptr;
1625 }
1626
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001627 ReleasedAllocated = (RsBase != nullptr) && (RsBase->isAllocated() ||
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00001628 RsBase->isAllocatedOfSizeZero());
Anna Zaksfe6eb672012-08-24 02:28:20 +00001629
Anna Zaksa14c1d02012-11-13 19:47:40 +00001630 // Clean out the info on previous call to free return info.
Anna Zaksc89ad072013-02-07 23:05:47 +00001631 State = State->remove<FreeReturnValue>(SymBase);
Anna Zaksa14c1d02012-11-13 19:47:40 +00001632
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001633 // Keep track of the return value. If it is NULL, we will know that free
Anna Zaks67291b92012-11-13 03:18:01 +00001634 // failed.
1635 if (ReturnsNullOnFailure) {
1636 SVal RetVal = C.getSVal(ParentExpr);
1637 SymbolRef RetStatusSymbol = RetVal.getAsSymbol();
1638 if (RetStatusSymbol) {
Anna Zaksc89ad072013-02-07 23:05:47 +00001639 C.getSymbolManager().addSymbolDependency(SymBase, RetStatusSymbol);
1640 State = State->set<FreeReturnValue>(SymBase, RetStatusSymbol);
Anna Zaks67291b92012-11-13 03:18:01 +00001641 }
1642 }
1643
Anton Yartsev030bcdd2013-04-05 19:08:04 +00001644 AllocationFamily Family = RsBase ? RsBase->getAllocationFamily()
1645 : getAllocationFamily(C, ParentExpr);
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001646 // Normal free.
Anton Yartsev05789592013-03-28 17:05:19 +00001647 if (Hold)
Anna Zaksc89ad072013-02-07 23:05:47 +00001648 return State->set<RegionState>(SymBase,
Anton Yartsev05789592013-03-28 17:05:19 +00001649 RefState::getRelinquished(Family,
1650 ParentExpr));
1651
1652 return State->set<RegionState>(SymBase,
1653 RefState::getReleased(Family, ParentExpr));
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00001654}
1655
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001656Optional<MallocChecker::CheckKind>
Anton Yartsev2487dd62015-03-10 22:24:21 +00001657MallocChecker::getCheckIfTracked(AllocationFamily Family,
1658 bool IsALeakCheck) const {
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001659 switch (Family) {
Anna Zaksd79b8402014-10-03 21:48:59 +00001660 case AF_Malloc:
Anton Yartsev4eb394d2015-03-07 00:31:53 +00001661 case AF_Alloca:
1662 case AF_IfNameIndex: {
1663 if (ChecksEnabled[CK_MallocChecker])
1664 return CK_MallocChecker;
1665
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001666 return Optional<MallocChecker::CheckKind>();
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001667 }
1668 case AF_CXXNew:
Reka Kovacs18775fc2018-06-09 13:03:49 +00001669 case AF_CXXNewArray:
Reka Kovacs88ad7042018-07-20 15:14:49 +00001670 // FIXME: Add new CheckKind for AF_InnerBuffer.
1671 case AF_InnerBuffer: {
Anton Yartsev2487dd62015-03-10 22:24:21 +00001672 if (IsALeakCheck) {
1673 if (ChecksEnabled[CK_NewDeleteLeaksChecker])
1674 return CK_NewDeleteLeaksChecker;
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001675 }
Anton Yartsev2487dd62015-03-10 22:24:21 +00001676 else {
1677 if (ChecksEnabled[CK_NewDeleteChecker])
1678 return CK_NewDeleteChecker;
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001679 }
1680 return Optional<MallocChecker::CheckKind>();
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001681 }
1682 case AF_None: {
Anton Yartsev030bcdd2013-04-05 19:08:04 +00001683 llvm_unreachable("no family");
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001684 }
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001685 }
Anton Yartsev2f910042013-04-05 02:12:04 +00001686 llvm_unreachable("unhandled family");
Anton Yartseve3377fb2013-04-04 23:46:29 +00001687}
1688
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001689Optional<MallocChecker::CheckKind>
Anton Yartsev4eb394d2015-03-07 00:31:53 +00001690MallocChecker::getCheckIfTracked(CheckerContext &C,
Anton Yartsev2487dd62015-03-10 22:24:21 +00001691 const Stmt *AllocDeallocStmt,
1692 bool IsALeakCheck) const {
1693 return getCheckIfTracked(getAllocationFamily(C, AllocDeallocStmt),
1694 IsALeakCheck);
Anton Yartseve5c0c142015-02-18 00:39:06 +00001695}
1696
1697Optional<MallocChecker::CheckKind>
Anton Yartsev2487dd62015-03-10 22:24:21 +00001698MallocChecker::getCheckIfTracked(CheckerContext &C, SymbolRef Sym,
1699 bool IsALeakCheck) const {
Devin Coughlin81771732015-09-22 22:47:14 +00001700 if (C.getState()->contains<ReallocSizeZeroSymbols>(Sym))
1701 return CK_MallocChecker;
1702
Anton Yartsev030bcdd2013-04-05 19:08:04 +00001703 const RefState *RS = C.getState()->get<RegionState>(Sym);
1704 assert(RS);
Anton Yartsev2487dd62015-03-10 22:24:21 +00001705 return getCheckIfTracked(RS->getAllocationFamily(), IsALeakCheck);
Anton Yartseve3377fb2013-04-04 23:46:29 +00001706}
1707
Ted Kremenek5ef32db2011-08-12 23:37:29 +00001708bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
David Blaikie05785d12013-02-20 22:23:23 +00001709 if (Optional<nonloc::ConcreteInt> IntVal = V.getAs<nonloc::ConcreteInt>())
Jordy Rose3597b212010-06-07 19:32:37 +00001710 os << "an integer (" << IntVal->getValue() << ")";
David Blaikie05785d12013-02-20 22:23:23 +00001711 else if (Optional<loc::ConcreteInt> ConstAddr = V.getAs<loc::ConcreteInt>())
Jordy Rose3597b212010-06-07 19:32:37 +00001712 os << "a constant address (" << ConstAddr->getValue() << ")";
David Blaikie05785d12013-02-20 22:23:23 +00001713 else if (Optional<loc::GotoLabel> Label = V.getAs<loc::GotoLabel>())
Chris Lattner5a9b1ec2011-02-17 05:38:27 +00001714 os << "the address of the label '" << Label->getLabel()->getName() << "'";
Jordy Rose3597b212010-06-07 19:32:37 +00001715 else
1716 return false;
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001717
Jordy Rose3597b212010-06-07 19:32:37 +00001718 return true;
1719}
1720
Ted Kremenek5ef32db2011-08-12 23:37:29 +00001721bool MallocChecker::SummarizeRegion(raw_ostream &os,
Jordy Rose3597b212010-06-07 19:32:37 +00001722 const MemRegion *MR) {
1723 switch (MR->getKind()) {
Artem Dergachev73f018e2016-01-13 13:49:29 +00001724 case MemRegion::FunctionCodeRegionKind: {
1725 const NamedDecl *FD = cast<FunctionCodeRegion>(MR)->getDecl();
Jordy Rose3597b212010-06-07 19:32:37 +00001726 if (FD)
Benjamin Kramerb89514a2011-10-14 18:45:37 +00001727 os << "the address of the function '" << *FD << '\'';
Jordy Rose3597b212010-06-07 19:32:37 +00001728 else
1729 os << "the address of a function";
1730 return true;
1731 }
Artem Dergachev73f018e2016-01-13 13:49:29 +00001732 case MemRegion::BlockCodeRegionKind:
Jordy Rose3597b212010-06-07 19:32:37 +00001733 os << "block text";
1734 return true;
1735 case MemRegion::BlockDataRegionKind:
1736 // FIXME: where the block came from?
1737 os << "a block";
1738 return true;
1739 default: {
1740 const MemSpaceRegion *MS = MR->getMemorySpace();
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001741
Anna Zaks8158ef02012-01-04 23:54:01 +00001742 if (isa<StackLocalsSpaceRegion>(MS)) {
Jordy Rose3597b212010-06-07 19:32:37 +00001743 const VarRegion *VR = dyn_cast<VarRegion>(MR);
1744 const VarDecl *VD;
1745 if (VR)
1746 VD = VR->getDecl();
1747 else
Craig Topper0dbb7832014-05-27 02:45:47 +00001748 VD = nullptr;
1749
Jordy Rose3597b212010-06-07 19:32:37 +00001750 if (VD)
1751 os << "the address of the local variable '" << VD->getName() << "'";
1752 else
1753 os << "the address of a local stack variable";
1754 return true;
1755 }
Anna Zaks8158ef02012-01-04 23:54:01 +00001756
1757 if (isa<StackArgumentsSpaceRegion>(MS)) {
Jordy Rose3597b212010-06-07 19:32:37 +00001758 const VarRegion *VR = dyn_cast<VarRegion>(MR);
1759 const VarDecl *VD;
1760 if (VR)
1761 VD = VR->getDecl();
1762 else
Craig Topper0dbb7832014-05-27 02:45:47 +00001763 VD = nullptr;
1764
Jordy Rose3597b212010-06-07 19:32:37 +00001765 if (VD)
1766 os << "the address of the parameter '" << VD->getName() << "'";
1767 else
1768 os << "the address of a parameter";
1769 return true;
1770 }
Anna Zaks8158ef02012-01-04 23:54:01 +00001771
1772 if (isa<GlobalsSpaceRegion>(MS)) {
Jordy Rose3597b212010-06-07 19:32:37 +00001773 const VarRegion *VR = dyn_cast<VarRegion>(MR);
1774 const VarDecl *VD;
1775 if (VR)
1776 VD = VR->getDecl();
1777 else
Craig Topper0dbb7832014-05-27 02:45:47 +00001778 VD = nullptr;
1779
Jordy Rose3597b212010-06-07 19:32:37 +00001780 if (VD) {
1781 if (VD->isStaticLocal())
1782 os << "the address of the static variable '" << VD->getName() << "'";
1783 else
1784 os << "the address of the global variable '" << VD->getName() << "'";
1785 } else
1786 os << "the address of a global variable";
1787 return true;
1788 }
Anna Zaks8158ef02012-01-04 23:54:01 +00001789
1790 return false;
Jordy Rose3597b212010-06-07 19:32:37 +00001791 }
1792 }
1793}
1794
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001795void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
1796 SourceRange Range,
Anton Yartsev05789592013-03-28 17:05:19 +00001797 const Expr *DeallocExpr) const {
1798
Anton Yartsev4eb394d2015-03-07 00:31:53 +00001799 if (!ChecksEnabled[CK_MallocChecker] &&
1800 !ChecksEnabled[CK_NewDeleteChecker])
1801 return;
1802
1803 Optional<MallocChecker::CheckKind> CheckKind =
1804 getCheckIfTracked(C, DeallocExpr);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001805 if (!CheckKind.hasValue())
Anton Yartseve3377fb2013-04-04 23:46:29 +00001806 return;
1807
Devin Coughline39bd402015-09-16 22:03:05 +00001808 if (ExplodedNode *N = C.generateErrorNode()) {
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001809 if (!BT_BadFree[*CheckKind])
Artem Dergachevb6a513d2017-05-03 11:47:13 +00001810 BT_BadFree[*CheckKind].reset(new BugType(
1811 CheckNames[*CheckKind], "Bad free", categories::MemoryError));
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001812
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001813 SmallString<100> buf;
Jordy Rose3597b212010-06-07 19:32:37 +00001814 llvm::raw_svector_ostream os(buf);
Anton Yartsev05789592013-03-28 17:05:19 +00001815
Jordy Rose3597b212010-06-07 19:32:37 +00001816 const MemRegion *MR = ArgVal.getAsRegion();
Anton Yartsev05789592013-03-28 17:05:19 +00001817 while (const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(MR))
1818 MR = ER->getSuperRegion();
1819
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001820 os << "Argument to ";
1821 if (!printAllocDeallocName(os, C, DeallocExpr))
1822 os << "deallocator";
Anton Yartsev05789592013-03-28 17:05:19 +00001823
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001824 os << " is ";
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001825 bool Summarized = MR ? SummarizeRegion(os, MR)
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001826 : SummarizeValue(os, ArgVal);
1827 if (Summarized)
1828 os << ", which is not memory allocated by ";
1829 else
1830 os << "not memory allocated by ";
Anton Yartsev05789592013-03-28 17:05:19 +00001831
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001832 printExpectedAllocName(os, C, DeallocExpr);
Anton Yartsev05789592013-03-28 17:05:19 +00001833
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001834 auto R = llvm::make_unique<BugReport>(*BT_BadFree[*CheckKind], os.str(), N);
Ted Kremenek1e809b42012-03-09 01:13:14 +00001835 R->markInteresting(MR);
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001836 R->addRange(Range);
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001837 C.emitReport(std::move(R));
Jordy Rose3597b212010-06-07 19:32:37 +00001838 }
1839}
1840
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001841void MallocChecker::ReportFreeAlloca(CheckerContext &C, SVal ArgVal,
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001842 SourceRange Range) const {
1843
Anton Yartsev4eb394d2015-03-07 00:31:53 +00001844 Optional<MallocChecker::CheckKind> CheckKind;
1845
1846 if (ChecksEnabled[CK_MallocChecker])
1847 CheckKind = CK_MallocChecker;
1848 else if (ChecksEnabled[CK_MismatchedDeallocatorChecker])
1849 CheckKind = CK_MismatchedDeallocatorChecker;
1850 else
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001851 return;
1852
Devin Coughline39bd402015-09-16 22:03:05 +00001853 if (ExplodedNode *N = C.generateErrorNode()) {
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001854 if (!BT_FreeAlloca[*CheckKind])
Artem Dergachevb6a513d2017-05-03 11:47:13 +00001855 BT_FreeAlloca[*CheckKind].reset(new BugType(
1856 CheckNames[*CheckKind], "Free alloca()", categories::MemoryError));
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001857
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001858 auto R = llvm::make_unique<BugReport>(
1859 *BT_FreeAlloca[*CheckKind],
1860 "Memory allocated by alloca() should not be deallocated", N);
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001861 R->markInteresting(ArgVal.getAsRegion());
1862 R->addRange(Range);
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001863 C.emitReport(std::move(R));
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001864 }
1865}
1866
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001867void MallocChecker::ReportMismatchedDealloc(CheckerContext &C,
Anton Yartseve3377fb2013-04-04 23:46:29 +00001868 SourceRange Range,
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001869 const Expr *DeallocExpr,
Anton Yartsevf0593d62013-04-05 11:25:10 +00001870 const RefState *RS,
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001871 SymbolRef Sym,
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001872 bool OwnershipTransferred) const {
Anton Yartsev05789592013-03-28 17:05:19 +00001873
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001874 if (!ChecksEnabled[CK_MismatchedDeallocatorChecker])
Anton Yartsev05789592013-03-28 17:05:19 +00001875 return;
1876
Devin Coughline39bd402015-09-16 22:03:05 +00001877 if (ExplodedNode *N = C.generateErrorNode()) {
Anton Yartseve3377fb2013-04-04 23:46:29 +00001878 if (!BT_MismatchedDealloc)
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001879 BT_MismatchedDealloc.reset(
1880 new BugType(CheckNames[CK_MismatchedDeallocatorChecker],
Artem Dergachevb6a513d2017-05-03 11:47:13 +00001881 "Bad deallocator", categories::MemoryError));
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001882
Anton Yartsev05789592013-03-28 17:05:19 +00001883 SmallString<100> buf;
1884 llvm::raw_svector_ostream os(buf);
1885
1886 const Expr *AllocExpr = cast<Expr>(RS->getStmt());
1887 SmallString<20> AllocBuf;
1888 llvm::raw_svector_ostream AllocOs(AllocBuf);
1889 SmallString<20> DeallocBuf;
1890 llvm::raw_svector_ostream DeallocOs(DeallocBuf);
1891
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001892 if (OwnershipTransferred) {
1893 if (printAllocDeallocName(DeallocOs, C, DeallocExpr))
1894 os << DeallocOs.str() << " cannot";
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001895 else
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001896 os << "Cannot";
Anton Yartsev05789592013-03-28 17:05:19 +00001897
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001898 os << " take ownership of memory";
Anton Yartsev05789592013-03-28 17:05:19 +00001899
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001900 if (printAllocDeallocName(AllocOs, C, AllocExpr))
1901 os << " allocated by " << AllocOs.str();
1902 } else {
1903 os << "Memory";
1904 if (printAllocDeallocName(AllocOs, C, AllocExpr))
1905 os << " allocated by " << AllocOs.str();
1906
1907 os << " should be deallocated by ";
1908 printExpectedDeallocName(os, RS->getAllocationFamily());
1909
1910 if (printAllocDeallocName(DeallocOs, C, DeallocExpr))
1911 os << ", not " << DeallocOs.str();
1912 }
Anton Yartsev05789592013-03-28 17:05:19 +00001913
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001914 auto R = llvm::make_unique<BugReport>(*BT_MismatchedDealloc, os.str(), N);
Anton Yartsevf0593d62013-04-05 11:25:10 +00001915 R->markInteresting(Sym);
Anton Yartsev05789592013-03-28 17:05:19 +00001916 R->addRange(Range);
David Blaikie91e79022014-09-04 23:54:33 +00001917 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001918 C.emitReport(std::move(R));
Anton Yartsev05789592013-03-28 17:05:19 +00001919 }
1920}
1921
Anna Zaksc89ad072013-02-07 23:05:47 +00001922void MallocChecker::ReportOffsetFree(CheckerContext &C, SVal ArgVal,
Anton Yartsev05789592013-03-28 17:05:19 +00001923 SourceRange Range, const Expr *DeallocExpr,
1924 const Expr *AllocExpr) const {
1925
Anton Yartsev05789592013-03-28 17:05:19 +00001926
Anton Yartsev4eb394d2015-03-07 00:31:53 +00001927 if (!ChecksEnabled[CK_MallocChecker] &&
1928 !ChecksEnabled[CK_NewDeleteChecker])
1929 return;
1930
1931 Optional<MallocChecker::CheckKind> CheckKind =
1932 getCheckIfTracked(C, AllocExpr);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001933 if (!CheckKind.hasValue())
Anton Yartseve3377fb2013-04-04 23:46:29 +00001934 return;
1935
Devin Coughline39bd402015-09-16 22:03:05 +00001936 ExplodedNode *N = C.generateErrorNode();
Craig Topper0dbb7832014-05-27 02:45:47 +00001937 if (!N)
Anna Zaksc89ad072013-02-07 23:05:47 +00001938 return;
1939
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001940 if (!BT_OffsetFree[*CheckKind])
Artem Dergachevb6a513d2017-05-03 11:47:13 +00001941 BT_OffsetFree[*CheckKind].reset(new BugType(
1942 CheckNames[*CheckKind], "Offset free", categories::MemoryError));
Anna Zaksc89ad072013-02-07 23:05:47 +00001943
1944 SmallString<100> buf;
1945 llvm::raw_svector_ostream os(buf);
Anton Yartsev05789592013-03-28 17:05:19 +00001946 SmallString<20> AllocNameBuf;
1947 llvm::raw_svector_ostream AllocNameOs(AllocNameBuf);
Anna Zaksc89ad072013-02-07 23:05:47 +00001948
1949 const MemRegion *MR = ArgVal.getAsRegion();
1950 assert(MR && "Only MemRegion based symbols can have offset free errors");
1951
1952 RegionOffset Offset = MR->getAsOffset();
1953 assert((Offset.isValid() &&
1954 !Offset.hasSymbolicOffset() &&
1955 Offset.getOffset() != 0) &&
1956 "Only symbols with a valid offset can have offset free errors");
1957
1958 int offsetBytes = Offset.getOffset() / C.getASTContext().getCharWidth();
1959
Anton Yartsev05789592013-03-28 17:05:19 +00001960 os << "Argument to ";
1961 if (!printAllocDeallocName(os, C, DeallocExpr))
1962 os << "deallocator";
1963 os << " is offset by "
Anna Zaksc89ad072013-02-07 23:05:47 +00001964 << offsetBytes
1965 << " "
1966 << ((abs(offsetBytes) > 1) ? "bytes" : "byte")
Anton Yartsev05789592013-03-28 17:05:19 +00001967 << " from the start of ";
1968 if (AllocExpr && printAllocDeallocName(AllocNameOs, C, AllocExpr))
1969 os << "memory allocated by " << AllocNameOs.str();
1970 else
1971 os << "allocated memory";
Anna Zaksc89ad072013-02-07 23:05:47 +00001972
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001973 auto R = llvm::make_unique<BugReport>(*BT_OffsetFree[*CheckKind], os.str(), N);
Anna Zaksc89ad072013-02-07 23:05:47 +00001974 R->markInteresting(MR->getBaseRegion());
1975 R->addRange(Range);
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001976 C.emitReport(std::move(R));
Anna Zaksc89ad072013-02-07 23:05:47 +00001977}
1978
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001979void MallocChecker::ReportUseAfterFree(CheckerContext &C, SourceRange Range,
1980 SymbolRef Sym) const {
1981
Anton Yartsev4eb394d2015-03-07 00:31:53 +00001982 if (!ChecksEnabled[CK_MallocChecker] &&
1983 !ChecksEnabled[CK_NewDeleteChecker])
1984 return;
1985
1986 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001987 if (!CheckKind.hasValue())
Anton Yartseve3377fb2013-04-04 23:46:29 +00001988 return;
1989
Devin Coughline39bd402015-09-16 22:03:05 +00001990 if (ExplodedNode *N = C.generateErrorNode()) {
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001991 if (!BT_UseFree[*CheckKind])
1992 BT_UseFree[*CheckKind].reset(new BugType(
Artem Dergachevb6a513d2017-05-03 11:47:13 +00001993 CheckNames[*CheckKind], "Use-after-free", categories::MemoryError));
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001994
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001995 auto R = llvm::make_unique<BugReport>(*BT_UseFree[*CheckKind],
1996 "Use of memory after it is freed", N);
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001997
1998 R->markInteresting(Sym);
1999 R->addRange(Range);
David Blaikie91e79022014-09-04 23:54:33 +00002000 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
Reka Kovacse453e602018-07-07 19:27:18 +00002001
2002 const RefState *RS = C.getState()->get<RegionState>(Sym);
Reka Kovacs88ad7042018-07-20 15:14:49 +00002003 if (RS->getAllocationFamily() == AF_InnerBuffer)
2004 R->addVisitor(allocation_state::getInnerPointerBRVisitor(Sym));
Reka Kovacse453e602018-07-07 19:27:18 +00002005
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002006 C.emitReport(std::move(R));
Anton Yartsev59ed15b2013-03-13 14:39:10 +00002007 }
2008}
2009
2010void MallocChecker::ReportDoubleFree(CheckerContext &C, SourceRange Range,
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002011 bool Released, SymbolRef Sym,
Anton Yartsev6c2af432013-03-13 17:07:32 +00002012 SymbolRef PrevSym) const {
Anton Yartsev59ed15b2013-03-13 14:39:10 +00002013
Anton Yartsev4eb394d2015-03-07 00:31:53 +00002014 if (!ChecksEnabled[CK_MallocChecker] &&
2015 !ChecksEnabled[CK_NewDeleteChecker])
2016 return;
2017
2018 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002019 if (!CheckKind.hasValue())
Anton Yartseve3377fb2013-04-04 23:46:29 +00002020 return;
2021
Devin Coughline39bd402015-09-16 22:03:05 +00002022 if (ExplodedNode *N = C.generateErrorNode()) {
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002023 if (!BT_DoubleFree[*CheckKind])
Artem Dergachevb6a513d2017-05-03 11:47:13 +00002024 BT_DoubleFree[*CheckKind].reset(new BugType(
2025 CheckNames[*CheckKind], "Double free", categories::MemoryError));
Anton Yartsev59ed15b2013-03-13 14:39:10 +00002026
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002027 auto R = llvm::make_unique<BugReport>(
2028 *BT_DoubleFree[*CheckKind],
2029 (Released ? "Attempt to free released memory"
2030 : "Attempt to free non-owned memory"),
2031 N);
Anton Yartsev59ed15b2013-03-13 14:39:10 +00002032 R->addRange(Range);
Anton Yartsev6c2af432013-03-13 17:07:32 +00002033 R->markInteresting(Sym);
2034 if (PrevSym)
2035 R->markInteresting(PrevSym);
David Blaikie91e79022014-09-04 23:54:33 +00002036 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002037 C.emitReport(std::move(R));
Anton Yartsev59ed15b2013-03-13 14:39:10 +00002038 }
2039}
2040
Jordan Rose656fdd52014-01-08 18:46:55 +00002041void MallocChecker::ReportDoubleDelete(CheckerContext &C, SymbolRef Sym) const {
2042
Anton Yartsev4eb394d2015-03-07 00:31:53 +00002043 if (!ChecksEnabled[CK_NewDeleteChecker])
2044 return;
2045
2046 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002047 if (!CheckKind.hasValue())
Jordan Rose656fdd52014-01-08 18:46:55 +00002048 return;
2049
Devin Coughline39bd402015-09-16 22:03:05 +00002050 if (ExplodedNode *N = C.generateErrorNode()) {
Jordan Rose656fdd52014-01-08 18:46:55 +00002051 if (!BT_DoubleDelete)
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002052 BT_DoubleDelete.reset(new BugType(CheckNames[CK_NewDeleteChecker],
Artem Dergachevb6a513d2017-05-03 11:47:13 +00002053 "Double delete",
2054 categories::MemoryError));
Jordan Rose656fdd52014-01-08 18:46:55 +00002055
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002056 auto R = llvm::make_unique<BugReport>(
2057 *BT_DoubleDelete, "Attempt to delete released memory", N);
Jordan Rose656fdd52014-01-08 18:46:55 +00002058
2059 R->markInteresting(Sym);
David Blaikie91e79022014-09-04 23:54:33 +00002060 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002061 C.emitReport(std::move(R));
Jordan Rose656fdd52014-01-08 18:46:55 +00002062 }
2063}
2064
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002065void MallocChecker::ReportUseZeroAllocated(CheckerContext &C,
2066 SourceRange Range,
2067 SymbolRef Sym) const {
2068
2069 if (!ChecksEnabled[CK_MallocChecker] &&
2070 !ChecksEnabled[CK_NewDeleteChecker])
2071 return;
2072
2073 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
2074
2075 if (!CheckKind.hasValue())
2076 return;
2077
Devin Coughline39bd402015-09-16 22:03:05 +00002078 if (ExplodedNode *N = C.generateErrorNode()) {
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002079 if (!BT_UseZerroAllocated[*CheckKind])
Artem Dergachevb6a513d2017-05-03 11:47:13 +00002080 BT_UseZerroAllocated[*CheckKind].reset(
2081 new BugType(CheckNames[*CheckKind], "Use of zero allocated",
2082 categories::MemoryError));
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002083
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002084 auto R = llvm::make_unique<BugReport>(*BT_UseZerroAllocated[*CheckKind],
2085 "Use of zero-allocated memory", N);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002086
2087 R->addRange(Range);
2088 if (Sym) {
2089 R->markInteresting(Sym);
2090 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
2091 }
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002092 C.emitReport(std::move(R));
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002093 }
2094}
2095
Daniel Marjamakia43a8f52017-05-02 11:46:12 +00002096void MallocChecker::ReportFunctionPointerFree(CheckerContext &C, SVal ArgVal,
2097 SourceRange Range,
2098 const Expr *FreeExpr) const {
2099 if (!ChecksEnabled[CK_MallocChecker])
2100 return;
2101
2102 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, FreeExpr);
2103 if (!CheckKind.hasValue())
2104 return;
2105
2106 if (ExplodedNode *N = C.generateErrorNode()) {
2107 if (!BT_BadFree[*CheckKind])
Artem Dergachev9849f592018-02-08 23:28:29 +00002108 BT_BadFree[*CheckKind].reset(new BugType(
2109 CheckNames[*CheckKind], "Bad free", categories::MemoryError));
Daniel Marjamakia43a8f52017-05-02 11:46:12 +00002110
2111 SmallString<100> Buf;
2112 llvm::raw_svector_ostream Os(Buf);
2113
2114 const MemRegion *MR = ArgVal.getAsRegion();
2115 while (const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(MR))
2116 MR = ER->getSuperRegion();
2117
2118 Os << "Argument to ";
2119 if (!printAllocDeallocName(Os, C, FreeExpr))
2120 Os << "deallocator";
2121
2122 Os << " is a function pointer";
2123
2124 auto R = llvm::make_unique<BugReport>(*BT_BadFree[*CheckKind], Os.str(), N);
2125 R->markInteresting(MR);
2126 R->addRange(Range);
2127 C.emitReport(std::move(R));
2128 }
2129}
2130
Leslie Zhaie3986c52017-04-26 05:33:14 +00002131ProgramStateRef MallocChecker::ReallocMemAux(CheckerContext &C,
2132 const CallExpr *CE,
2133 bool FreesOnFail,
Daniel Marjamakia43a8f52017-05-02 11:46:12 +00002134 ProgramStateRef State,
Leslie Zhaie3986c52017-04-26 05:33:14 +00002135 bool SuffixWithN) const {
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00002136 if (!State)
2137 return nullptr;
2138
Leslie Zhaie3986c52017-04-26 05:33:14 +00002139 if (SuffixWithN && CE->getNumArgs() < 3)
2140 return nullptr;
2141 else if (CE->getNumArgs() < 2)
Craig Topper0dbb7832014-05-27 02:45:47 +00002142 return nullptr;
Anna Zaksb508d292012-04-10 23:41:11 +00002143
Ted Kremenek90af9092010-12-02 07:49:45 +00002144 const Expr *arg0Expr = CE->getArg(0);
George Karpenkovd703ec92018-01-17 20:27:29 +00002145 SVal Arg0Val = C.getSVal(arg0Expr);
David Blaikie2fdacbc2013-02-20 05:52:05 +00002146 if (!Arg0Val.getAs<DefinedOrUnknownSVal>())
Craig Topper0dbb7832014-05-27 02:45:47 +00002147 return nullptr;
David Blaikie2fdacbc2013-02-20 05:52:05 +00002148 DefinedOrUnknownSVal arg0Val = Arg0Val.castAs<DefinedOrUnknownSVal>();
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00002149
Ted Kremenek9d0bb1e2010-12-01 21:28:31 +00002150 SValBuilder &svalBuilder = C.getSValBuilder();
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00002151
Ted Kremenek90af9092010-12-02 07:49:45 +00002152 DefinedOrUnknownSVal PtrEQ =
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00002153 svalBuilder.evalEQ(State, arg0Val, svalBuilder.makeNull());
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00002154
Leslie Zhaie3986c52017-04-26 05:33:14 +00002155 // Get the size argument.
Lenny Maiorani005b5c12011-04-27 14:49:29 +00002156 const Expr *Arg1 = CE->getArg(1);
Lenny Maiorani005b5c12011-04-27 14:49:29 +00002157
2158 // Get the value of the size argument.
George Karpenkovd703ec92018-01-17 20:27:29 +00002159 SVal TotalSize = C.getSVal(Arg1);
Leslie Zhaie3986c52017-04-26 05:33:14 +00002160 if (SuffixWithN)
2161 TotalSize = evalMulForBufferSize(C, Arg1, CE->getArg(2));
2162 if (!TotalSize.getAs<DefinedOrUnknownSVal>())
Craig Topper0dbb7832014-05-27 02:45:47 +00002163 return nullptr;
Lenny Maiorani005b5c12011-04-27 14:49:29 +00002164
2165 // Compare the size argument to 0.
2166 DefinedOrUnknownSVal SizeZero =
Leslie Zhaie3986c52017-04-26 05:33:14 +00002167 svalBuilder.evalEQ(State, TotalSize.castAs<DefinedOrUnknownSVal>(),
Lenny Maiorani005b5c12011-04-27 14:49:29 +00002168 svalBuilder.makeIntValWithPtrWidth(0, false));
2169
Anna Zaksd56c8792012-02-13 18:05:39 +00002170 ProgramStateRef StatePtrIsNull, StatePtrNotNull;
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00002171 std::tie(StatePtrIsNull, StatePtrNotNull) = State->assume(PtrEQ);
Anna Zaksd56c8792012-02-13 18:05:39 +00002172 ProgramStateRef StateSizeIsZero, StateSizeNotZero;
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00002173 std::tie(StateSizeIsZero, StateSizeNotZero) = State->assume(SizeZero);
Anna Zaksd56c8792012-02-13 18:05:39 +00002174 // We only assume exceptional states if they are definitely true; if the
2175 // state is under-constrained, assume regular realloc behavior.
2176 bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull;
2177 bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero;
2178
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002179 // If the ptr is NULL and the size is not 0, the call is equivalent to
Lenny Maiorani005b5c12011-04-27 14:49:29 +00002180 // malloc(size).
Leslie Zhaie3986c52017-04-26 05:33:14 +00002181 if (PrtIsNull && !SizeIsZero) {
2182 ProgramStateRef stateMalloc = MallocMemAux(C, CE, TotalSize,
Anna Zaksd56c8792012-02-13 18:05:39 +00002183 UndefinedVal(), StatePtrIsNull);
Anna Zaks40a7eb32012-02-22 19:24:52 +00002184 return stateMalloc;
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00002185 }
2186
Anna Zaksd56c8792012-02-13 18:05:39 +00002187 if (PrtIsNull && SizeIsZero)
Devin Coughlin81771732015-09-22 22:47:14 +00002188 return State;
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00002189
Anna Zaks8fd0f2a2012-02-13 20:57:07 +00002190 // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size).
Anna Zaksd56c8792012-02-13 18:05:39 +00002191 assert(!PrtIsNull);
Anna Zaks8fd0f2a2012-02-13 20:57:07 +00002192 SymbolRef FromPtr = arg0Val.getAsSymbol();
George Karpenkovd703ec92018-01-17 20:27:29 +00002193 SVal RetVal = C.getSVal(CE);
Anna Zaks8fd0f2a2012-02-13 20:57:07 +00002194 SymbolRef ToPtr = RetVal.getAsSymbol();
2195 if (!FromPtr || !ToPtr)
Craig Topper0dbb7832014-05-27 02:45:47 +00002196 return nullptr;
Anna Zaksd56c8792012-02-13 18:05:39 +00002197
Anna Zaksfe6eb672012-08-24 02:28:20 +00002198 bool ReleasedAllocated = false;
2199
Anna Zaksd56c8792012-02-13 18:05:39 +00002200 // If the size is 0, free the memory.
2201 if (SizeIsZero)
Anna Zaksfe6eb672012-08-24 02:28:20 +00002202 if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero, 0,
2203 false, ReleasedAllocated)){
Anna Zaksd56c8792012-02-13 18:05:39 +00002204 // The semantics of the return value are:
2205 // If size was equal to 0, either NULL or a pointer suitable to be passed
Anna Zaks52242a62012-08-03 18:30:18 +00002206 // to free() is returned. We just free the input pointer and do not add
2207 // any constrains on the output pointer.
Anna Zaks40a7eb32012-02-22 19:24:52 +00002208 return stateFree;
Anna Zaksd56c8792012-02-13 18:05:39 +00002209 }
2210
2211 // Default behavior.
Anna Zaksfe6eb672012-08-24 02:28:20 +00002212 if (ProgramStateRef stateFree =
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00002213 FreeMemAux(C, CE, State, 0, false, ReleasedAllocated)) {
Anna Zaksfe6eb672012-08-24 02:28:20 +00002214
Leslie Zhaie3986c52017-04-26 05:33:14 +00002215 ProgramStateRef stateRealloc = MallocMemAux(C, CE, TotalSize,
Anna Zaksd56c8792012-02-13 18:05:39 +00002216 UnknownVal(), stateFree);
Anna Zaks8fd0f2a2012-02-13 20:57:07 +00002217 if (!stateRealloc)
Craig Topper0dbb7832014-05-27 02:45:47 +00002218 return nullptr;
Anna Zaksfe6eb672012-08-24 02:28:20 +00002219
Anna Zaks75cfbb62012-09-12 22:57:34 +00002220 ReallocPairKind Kind = RPToBeFreedAfterFailure;
2221 if (FreesOnFail)
2222 Kind = RPIsFreeOnFailure;
2223 else if (!ReleasedAllocated)
2224 Kind = RPDoNotTrackAfterFailure;
2225
Anna Zaksfe6eb672012-08-24 02:28:20 +00002226 // Record the info about the reallocated symbol so that we could properly
2227 // process failed reallocation.
Anna Zaksac068142012-02-15 00:11:25 +00002228 stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr,
Anna Zaks75cfbb62012-09-12 22:57:34 +00002229 ReallocPair(FromPtr, Kind));
Anna Zaksfe6eb672012-08-24 02:28:20 +00002230 // The reallocated symbol should stay alive for as long as the new symbol.
Anna Zaksad01ef52012-02-14 00:26:13 +00002231 C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
Anna Zaks40a7eb32012-02-22 19:24:52 +00002232 return stateRealloc;
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00002233 }
Craig Topper0dbb7832014-05-27 02:45:47 +00002234 return nullptr;
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00002235}
Zhongxing Xuc4902a52009-11-13 07:25:27 +00002236
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002237ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00002238 ProgramStateRef State) {
2239 if (!State)
2240 return nullptr;
2241
Anna Zaksb508d292012-04-10 23:41:11 +00002242 if (CE->getNumArgs() < 2)
Craig Topper0dbb7832014-05-27 02:45:47 +00002243 return nullptr;
Anna Zaksb508d292012-04-10 23:41:11 +00002244
Ted Kremenek9d0bb1e2010-12-01 21:28:31 +00002245 SValBuilder &svalBuilder = C.getSValBuilder();
Ted Kremenek90af9092010-12-02 07:49:45 +00002246 SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
Leslie Zhaie3986c52017-04-26 05:33:14 +00002247 SVal TotalSize = evalMulForBufferSize(C, CE->getArg(0), CE->getArg(1));
Zhongxing Xu527ff6d2010-06-01 03:01:33 +00002248
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00002249 return MallocMemAux(C, CE, TotalSize, zeroVal, State);
Zhongxing Xu527ff6d2010-06-01 03:01:33 +00002250}
2251
Anna Zaksfc2e1532012-03-21 19:45:08 +00002252LeakInfo
Anna Zaksdf901a42012-02-23 21:38:21 +00002253MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
2254 CheckerContext &C) const {
Anna Zaks43ffba22012-02-27 23:40:55 +00002255 const LocationContext *LeakContext = N->getLocationContext();
Anna Zaksdf901a42012-02-23 21:38:21 +00002256 // Walk the ExplodedGraph backwards and find the first node that referred to
2257 // the tracked symbol.
2258 const ExplodedNode *AllocNode = N;
Craig Topper0dbb7832014-05-27 02:45:47 +00002259 const MemRegion *ReferenceRegion = nullptr;
Anna Zaksdf901a42012-02-23 21:38:21 +00002260
2261 while (N) {
Anna Zaksfc2e1532012-03-21 19:45:08 +00002262 ProgramStateRef State = N->getState();
2263 if (!State->get<RegionState>(Sym))
Anna Zaksdf901a42012-02-23 21:38:21 +00002264 break;
Anna Zaksfc2e1532012-03-21 19:45:08 +00002265
2266 // Find the most recent expression bound to the symbol in the current
2267 // context.
Anna Zaks7c19abe2013-04-10 21:42:02 +00002268 if (!ReferenceRegion) {
2269 if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) {
2270 SVal Val = State->getSVal(MR);
2271 if (Val.getAsLocSymbol() == Sym) {
Anna Zaks07804ef2013-04-10 22:56:33 +00002272 const VarRegion* VR = MR->getBaseRegion()->getAs<VarRegion>();
Anna Zaks7c19abe2013-04-10 21:42:02 +00002273 // Do not show local variables belonging to a function other than
2274 // where the error is reported.
2275 if (!VR ||
George Karpenkovdd18b112018-06-27 01:51:55 +00002276 (VR->getStackFrame() == LeakContext->getStackFrame()))
Anna Zaks7c19abe2013-04-10 21:42:02 +00002277 ReferenceRegion = MR;
2278 }
2279 }
Benjamin Kramerc25c5e02012-03-21 21:03:48 +00002280 }
Anna Zaksfc2e1532012-03-21 19:45:08 +00002281
Anna Zaks486a0ff2015-02-05 01:02:53 +00002282 // Allocation node, is the last node in the current or parent context in
2283 // which the symbol was tracked.
2284 const LocationContext *NContext = N->getLocationContext();
2285 if (NContext == LeakContext ||
2286 NContext->isParentOf(LeakContext))
Anna Zaks43ffba22012-02-27 23:40:55 +00002287 AllocNode = N;
Craig Topper0dbb7832014-05-27 02:45:47 +00002288 N = N->pred_empty() ? nullptr : *(N->pred_begin());
Anna Zaksdf901a42012-02-23 21:38:21 +00002289 }
2290
Anna Zaksa043d0c2013-01-08 00:25:29 +00002291 return LeakInfo(AllocNode, ReferenceRegion);
Anna Zaksdf901a42012-02-23 21:38:21 +00002292}
2293
Anna Zaksd3571e5a2012-02-11 21:02:40 +00002294void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
2295 CheckerContext &C) const {
Anton Yartsev05789592013-03-28 17:05:19 +00002296
Anton Yartsev4eb394d2015-03-07 00:31:53 +00002297 if (!ChecksEnabled[CK_MallocChecker] &&
2298 !ChecksEnabled[CK_NewDeleteLeaksChecker])
Anton Yartsev6e499252013-04-05 02:25:02 +00002299 return;
2300
Anton Yartsev9907fc92015-03-04 23:18:21 +00002301 const RefState *RS = C.getState()->get<RegionState>(Sym);
Anton Yartsev4eb394d2015-03-07 00:31:53 +00002302 assert(RS && "cannot leak an untracked symbol");
2303 AllocationFamily Family = RS->getAllocationFamily();
Anton Yartsev2487dd62015-03-10 22:24:21 +00002304
2305 if (Family == AF_Alloca)
Anton Yartsev4eb394d2015-03-07 00:31:53 +00002306 return;
2307
Anton Yartsev2487dd62015-03-10 22:24:21 +00002308 Optional<MallocChecker::CheckKind>
2309 CheckKind = getCheckIfTracked(Family, true);
Anton Yartsev4eb394d2015-03-07 00:31:53 +00002310
Anton Yartsev2487dd62015-03-10 22:24:21 +00002311 if (!CheckKind.hasValue())
Anton Yartsev9907fc92015-03-04 23:18:21 +00002312 return;
2313
Anna Zaksd3571e5a2012-02-11 21:02:40 +00002314 assert(N);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002315 if (!BT_Leak[*CheckKind]) {
Artem Dergachevb6a513d2017-05-03 11:47:13 +00002316 BT_Leak[*CheckKind].reset(new BugType(CheckNames[*CheckKind], "Memory leak",
2317 categories::MemoryError));
Anna Zaksd3571e5a2012-02-11 21:02:40 +00002318 // Leaks should not be reported if they are post-dominated by a sink:
2319 // (1) Sinks are higher importance bugs.
2320 // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
2321 // with __noreturn functions such as assert() or exit(). We choose not
2322 // to report leaks on such paths.
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002323 BT_Leak[*CheckKind]->setSuppressOnSink(true);
Anna Zaksd3571e5a2012-02-11 21:02:40 +00002324 }
2325
Anna Zaksdf901a42012-02-23 21:38:21 +00002326 // Most bug reports are cached at the location where they occurred.
2327 // With leaks, we want to unique them by the location where they were
2328 // allocated, and only report a single path.
Anna Zaks43ffba22012-02-27 23:40:55 +00002329 PathDiagnosticLocation LocUsedForUniqueing;
Craig Topper0dbb7832014-05-27 02:45:47 +00002330 const ExplodedNode *AllocNode = nullptr;
2331 const MemRegion *Region = nullptr;
Benjamin Kramer867ea1d2014-03-02 13:01:17 +00002332 std::tie(AllocNode, Region) = getAllocationSite(N, Sym, C);
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002333
Gabor Horvath6ee4f902016-08-18 07:54:50 +00002334 const Stmt *AllocationStmt = PathDiagnosticLocation::getStmt(AllocNode);
Anton Yartsev6e499252013-04-05 02:25:02 +00002335 if (AllocationStmt)
Anna Zaksa043d0c2013-01-08 00:25:29 +00002336 LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocationStmt,
2337 C.getSourceManager(),
2338 AllocNode->getLocationContext());
Anna Zaksdf901a42012-02-23 21:38:21 +00002339
Anna Zaksfc2e1532012-03-21 19:45:08 +00002340 SmallString<200> buf;
2341 llvm::raw_svector_ostream os(buf);
Jordan Rosed86b3bd2012-08-08 18:23:36 +00002342 if (Region && Region->canPrintPretty()) {
Anna Zaks6cea7d92013-04-12 18:40:21 +00002343 os << "Potential leak of memory pointed to by ";
Jordan Rosed86b3bd2012-08-08 18:23:36 +00002344 Region->printPretty(os);
Anna Zaksa1de8562013-04-06 00:41:36 +00002345 } else {
2346 os << "Potential memory leak";
Anna Zaksfc2e1532012-03-21 19:45:08 +00002347 }
2348
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002349 auto R = llvm::make_unique<BugReport>(
2350 *BT_Leak[*CheckKind], os.str(), N, LocUsedForUniqueing,
2351 AllocNode->getLocationContext()->getDecl());
Ted Kremenek1e809b42012-03-09 01:13:14 +00002352 R->markInteresting(Sym);
David Blaikie91e79022014-09-04 23:54:33 +00002353 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym, true));
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002354 C.emitReport(std::move(R));
Anna Zaksd3571e5a2012-02-11 21:02:40 +00002355}
2356
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +00002357void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
2358 CheckerContext &C) const
Ted Kremenek90af9092010-12-02 07:49:45 +00002359{
Zhongxing Xubce831f2010-08-15 08:19:57 +00002360 if (!SymReaper.hasDeadSymbols())
2361 return;
Zhongxing Xuc7460962009-11-13 07:48:11 +00002362
Ted Kremenek49b1e382012-01-26 21:29:00 +00002363 ProgramStateRef state = C.getState();
Zhongxing Xubce831f2010-08-15 08:19:57 +00002364 RegionStateTy RS = state->get<RegionState>();
Jordy Rose82584992010-08-18 04:33:47 +00002365 RegionStateTy::Factory &F = state->get_context<RegionState>();
Zhongxing Xubce831f2010-08-15 08:19:57 +00002366
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002367 SmallVector<SymbolRef, 2> Errors;
Zhongxing Xubce831f2010-08-15 08:19:57 +00002368 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
2369 if (SymReaper.isDead(I->first)) {
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002370 if (I->second.isAllocated() || I->second.isAllocatedOfSizeZero())
Anna Zaks78edc2f2012-02-09 06:48:19 +00002371 Errors.push_back(I->first);
Jordy Rose82584992010-08-18 04:33:47 +00002372 // Remove the dead symbol from the map.
Ted Kremenekb3b56c62010-11-24 00:54:37 +00002373 RS = F.remove(RS, I->first);
Ted Kremeneke227f492011-07-28 23:07:51 +00002374
Zhongxing Xuc7460962009-11-13 07:48:11 +00002375 }
2376 }
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002377
Anna Zaksd56c8792012-02-13 18:05:39 +00002378 // Cleanup the Realloc Pairs Map.
Jordan Rose0c153cb2012-11-02 01:54:06 +00002379 ReallocPairsTy RP = state->get<ReallocPairs>();
2380 for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
Anna Zaksac068142012-02-15 00:11:25 +00002381 if (SymReaper.isDead(I->first) ||
2382 SymReaper.isDead(I->second.ReallocatedSym)) {
Anna Zaksd56c8792012-02-13 18:05:39 +00002383 state = state->remove<ReallocPairs>(I->first);
2384 }
2385 }
2386
Anna Zaks67291b92012-11-13 03:18:01 +00002387 // Cleanup the FreeReturnValue Map.
2388 FreeReturnValueTy FR = state->get<FreeReturnValue>();
2389 for (FreeReturnValueTy::iterator I = FR.begin(), E = FR.end(); I != E; ++I) {
2390 if (SymReaper.isDead(I->first) ||
2391 SymReaper.isDead(I->second)) {
2392 state = state->remove<FreeReturnValue>(I->first);
2393 }
2394 }
2395
Anna Zaksdf901a42012-02-23 21:38:21 +00002396 // Generate leak node.
Anna Zaks58a2c4e2012-10-29 22:51:54 +00002397 ExplodedNode *N = C.getPredecessor();
2398 if (!Errors.empty()) {
Anton Yartsev6a619222014-02-17 18:25:34 +00002399 static CheckerProgramPointTag Tag("MallocChecker", "DeadSymbolsLeak");
Devin Coughline39bd402015-09-16 22:03:05 +00002400 N = C.generateNonFatalErrorNode(C.getState(), &Tag);
2401 if (N) {
2402 for (SmallVectorImpl<SymbolRef>::iterator
Craig Topper2341c0d2013-07-04 03:08:24 +00002403 I = Errors.begin(), E = Errors.end(); I != E; ++I) {
Devin Coughline39bd402015-09-16 22:03:05 +00002404 reportLeak(*I, N, C);
2405 }
Anna Zaks78edc2f2012-02-09 06:48:19 +00002406 }
Ted Kremeneke227f492011-07-28 23:07:51 +00002407 }
Anna Zaks58a2c4e2012-10-29 22:51:54 +00002408
Anna Zaksdf901a42012-02-23 21:38:21 +00002409 C.addTransition(state->set<RegionState>(RS), N);
Zhongxing Xuc4902a52009-11-13 07:25:27 +00002410}
Zhongxing Xu4668c7e2009-11-17 07:54:15 +00002411
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00002412void MallocChecker::checkPreCall(const CallEvent &Call,
2413 CheckerContext &C) const {
2414
Jordan Rose656fdd52014-01-08 18:46:55 +00002415 if (const CXXDestructorCall *DC = dyn_cast<CXXDestructorCall>(&Call)) {
2416 SymbolRef Sym = DC->getCXXThisVal().getAsSymbol();
2417 if (!Sym || checkDoubleDelete(Sym, C))
2418 return;
2419 }
2420
Anna Zaks46d01602012-05-18 01:16:10 +00002421 // We will check for double free in the post visit.
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00002422 if (const AnyFunctionCall *FC = dyn_cast<AnyFunctionCall>(&Call)) {
2423 const FunctionDecl *FD = FC->getDecl();
2424 if (!FD)
2425 return;
Anton Yartsev13df0362013-03-25 01:35:45 +00002426
Anna Zaksd79b8402014-10-03 21:48:59 +00002427 ASTContext &Ctx = C.getASTContext();
Gabor Horvathe40c71c2015-03-04 17:59:34 +00002428 if (ChecksEnabled[CK_MallocChecker] &&
Anna Zaksd79b8402014-10-03 21:48:59 +00002429 (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Free) ||
2430 isCMemFunction(FD, Ctx, AF_IfNameIndex,
2431 MemoryOperationKind::MOK_Free)))
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00002432 return;
Anna Zaks3d348342012-02-14 21:55:24 +00002433
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002434 if (ChecksEnabled[CK_NewDeleteChecker] &&
Anna Zaksd79b8402014-10-03 21:48:59 +00002435 isStandardNewDelete(FD, Ctx))
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00002436 return;
2437 }
2438
2439 // Check if the callee of a method is deleted.
2440 if (const CXXInstanceCall *CC = dyn_cast<CXXInstanceCall>(&Call)) {
2441 SymbolRef Sym = CC->getCXXThisVal().getAsSymbol();
2442 if (!Sym || checkUseAfterFree(Sym, C, CC->getCXXThisExpr()))
2443 return;
2444 }
2445
2446 // Check arguments for being used after free.
2447 for (unsigned I = 0, E = Call.getNumArgs(); I != E; ++I) {
2448 SVal ArgSVal = Call.getArgSVal(I);
2449 if (ArgSVal.getAs<Loc>()) {
2450 SymbolRef Sym = ArgSVal.getAsSymbol();
Anna Zaks3d348342012-02-14 21:55:24 +00002451 if (!Sym)
2452 continue;
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00002453 if (checkUseAfterFree(Sym, C, Call.getArgExpr(I)))
Anna Zaks3d348342012-02-14 21:55:24 +00002454 return;
2455 }
2456 }
2457}
2458
Reka Kovacs122171e2018-08-02 23:02:08 +00002459void MallocChecker::checkPreStmt(const ReturnStmt *S,
2460 CheckerContext &C) const {
2461 checkEscapeOnReturn(S, C);
2462}
2463
2464// In the CFG, automatic destructors come after the return statement.
2465// This callback checks for returning memory that is freed by automatic
2466// destructors, as those cannot be reached in checkPreStmt().
2467void MallocChecker::checkEndFunction(const ReturnStmt *S,
2468 CheckerContext &C) const {
2469 checkEscapeOnReturn(S, C);
2470}
2471
2472void MallocChecker::checkEscapeOnReturn(const ReturnStmt *S,
2473 CheckerContext &C) const {
2474 if (!S)
2475 return;
2476
Anna Zaksa1b227b2012-02-08 23:16:56 +00002477 const Expr *E = S->getRetValue();
2478 if (!E)
2479 return;
Anna Zaks3aa52252012-02-11 21:44:39 +00002480
2481 // Check if we are returning a symbol.
Jordan Rose356279c2012-08-08 18:23:31 +00002482 ProgramStateRef State = C.getState();
George Karpenkovd703ec92018-01-17 20:27:29 +00002483 SVal RetVal = C.getSVal(E);
Anna Zaks4ca45b12012-02-22 02:36:01 +00002484 SymbolRef Sym = RetVal.getAsSymbol();
2485 if (!Sym)
2486 // If we are returning a field of the allocated struct or an array element,
2487 // the callee could still free the memory.
2488 // TODO: This logic should be a part of generic symbol escape callback.
2489 if (const MemRegion *MR = RetVal.getAsRegion())
2490 if (isa<FieldRegion>(MR) || isa<ElementRegion>(MR))
2491 if (const SymbolicRegion *BMR =
2492 dyn_cast<SymbolicRegion>(MR->getBaseRegion()))
2493 Sym = BMR->getSymbol();
Zhongxing Xu23baa012009-11-17 08:58:18 +00002494
Anna Zaks3aa52252012-02-11 21:44:39 +00002495 // Check if we are returning freed memory.
Jordan Rose356279c2012-08-08 18:23:31 +00002496 if (Sym)
Jordan Rosef1f26142012-11-15 19:11:33 +00002497 checkUseAfterFree(Sym, C, E);
Zhongxing Xu23baa012009-11-17 08:58:18 +00002498}
Zhongxing Xub0e15df2009-12-31 06:13:07 +00002499
Anna Zaks9fe80982012-03-22 00:57:20 +00002500// TODO: Blocks should be either inlined or should call invalidate regions
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002501// upon invocation. After that's in place, special casing here will not be
Anna Zaks9fe80982012-03-22 00:57:20 +00002502// needed.
2503void MallocChecker::checkPostStmt(const BlockExpr *BE,
2504 CheckerContext &C) const {
2505
2506 // Scan the BlockDecRefExprs for any object the retain count checker
2507 // may be tracking.
2508 if (!BE->getBlockDecl()->hasCaptures())
2509 return;
2510
2511 ProgramStateRef state = C.getState();
2512 const BlockDataRegion *R =
George Karpenkovd703ec92018-01-17 20:27:29 +00002513 cast<BlockDataRegion>(C.getSVal(BE).getAsRegion());
Anna Zaks9fe80982012-03-22 00:57:20 +00002514
2515 BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
2516 E = R->referenced_vars_end();
2517
2518 if (I == E)
2519 return;
2520
2521 SmallVector<const MemRegion*, 10> Regions;
2522 const LocationContext *LC = C.getLocationContext();
2523 MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager();
2524
2525 for ( ; I != E; ++I) {
Ted Kremenekbcf90532012-12-06 07:17:20 +00002526 const VarRegion *VR = I.getCapturedRegion();
Anna Zaks9fe80982012-03-22 00:57:20 +00002527 if (VR->getSuperRegion() == R) {
2528 VR = MemMgr.getVarRegion(VR->getDecl(), LC);
2529 }
2530 Regions.push_back(VR);
2531 }
2532
2533 state =
2534 state->scanReachableSymbols<StopTrackingCallback>(Regions.data(),
2535 Regions.data() + Regions.size()).getState();
2536 C.addTransition(state);
2537}
2538
Anna Zaks46d01602012-05-18 01:16:10 +00002539bool MallocChecker::isReleased(SymbolRef Sym, CheckerContext &C) const {
Anna Zaksa1b227b2012-02-08 23:16:56 +00002540 assert(Sym);
2541 const RefState *RS = C.getState()->get<RegionState>(Sym);
Anna Zaks46d01602012-05-18 01:16:10 +00002542 return (RS && RS->isReleased());
2543}
2544
2545bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
2546 const Stmt *S) const {
Anna Zaksa1b227b2012-02-08 23:16:56 +00002547
Jordan Rose656fdd52014-01-08 18:46:55 +00002548 if (isReleased(Sym, C)) {
Anton Yartsev59ed15b2013-03-13 14:39:10 +00002549 ReportUseAfterFree(C, S->getSourceRange(), Sym);
2550 return true;
Anna Zaksa1b227b2012-02-08 23:16:56 +00002551 }
Anton Yartsev59ed15b2013-03-13 14:39:10 +00002552
Anna Zaksa1b227b2012-02-08 23:16:56 +00002553 return false;
2554}
2555
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002556void MallocChecker::checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C,
2557 const Stmt *S) const {
2558 assert(Sym);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002559
Devin Coughlin81771732015-09-22 22:47:14 +00002560 if (const RefState *RS = C.getState()->get<RegionState>(Sym)) {
2561 if (RS->isAllocatedOfSizeZero())
2562 ReportUseZeroAllocated(C, RS->getStmt()->getSourceRange(), Sym);
2563 }
2564 else if (C.getState()->contains<ReallocSizeZeroSymbols>(Sym)) {
2565 ReportUseZeroAllocated(C, S->getSourceRange(), Sym);
2566 }
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002567}
2568
Jordan Rose656fdd52014-01-08 18:46:55 +00002569bool MallocChecker::checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const {
2570
2571 if (isReleased(Sym, C)) {
2572 ReportDoubleDelete(C, Sym);
2573 return true;
2574 }
2575 return false;
2576}
2577
Zhongxing Xu1bb6a1a2010-03-10 04:58:55 +00002578// Check if the location is a freed symbolic region.
Anna Zaks3e0f4152011-10-06 00:43:15 +00002579void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
2580 CheckerContext &C) const {
Zhongxing Xu1bb6a1a2010-03-10 04:58:55 +00002581 SymbolRef Sym = l.getLocSymbolInBase();
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002582 if (Sym) {
Anna Zaks46d01602012-05-18 01:16:10 +00002583 checkUseAfterFree(Sym, C, S);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002584 checkUseZeroAllocated(Sym, C, S);
2585 }
Zhongxing Xu1bb6a1a2010-03-10 04:58:55 +00002586}
Ted Kremenekd21139a2010-07-31 01:52:11 +00002587
Anna Zaksbb1ef902012-02-11 21:02:35 +00002588// If a symbolic region is assumed to NULL (or another constant), stop tracking
2589// it - assuming that allocation failed on this path.
2590ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state,
2591 SVal Cond,
2592 bool Assumption) const {
2593 RegionStateTy RS = state->get<RegionState>();
Anna Zaksbb1ef902012-02-11 21:02:35 +00002594 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
Ted Kremenek244e1d72012-09-07 22:31:01 +00002595 // If the symbol is assumed to be NULL, remove it from consideration.
Jordan Rose14fe9f32012-11-01 00:18:27 +00002596 ConstraintManager &CMgr = state->getConstraintManager();
2597 ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
2598 if (AllocFailed.isConstrainedTrue())
Anna Zaksbb1ef902012-02-11 21:02:35 +00002599 state = state->remove<RegionState>(I.getKey());
2600 }
2601
Anna Zaksd56c8792012-02-13 18:05:39 +00002602 // Realloc returns 0 when reallocation fails, which means that we should
2603 // restore the state of the pointer being reallocated.
Jordan Rose0c153cb2012-11-02 01:54:06 +00002604 ReallocPairsTy RP = state->get<ReallocPairs>();
2605 for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
Ted Kremenek244e1d72012-09-07 22:31:01 +00002606 // If the symbol is assumed to be NULL, remove it from consideration.
Jordan Rose14fe9f32012-11-01 00:18:27 +00002607 ConstraintManager &CMgr = state->getConstraintManager();
2608 ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
Jordan Rose40bb12492012-11-01 00:25:15 +00002609 if (!AllocFailed.isConstrainedTrue())
Anna Zaks75cfbb62012-09-12 22:57:34 +00002610 continue;
Jordan Rose14fe9f32012-11-01 00:18:27 +00002611
Anna Zaks75cfbb62012-09-12 22:57:34 +00002612 SymbolRef ReallocSym = I.getData().ReallocatedSym;
2613 if (const RefState *RS = state->get<RegionState>(ReallocSym)) {
2614 if (RS->isReleased()) {
2615 if (I.getData().Kind == RPToBeFreedAfterFailure)
Anna Zaksac068142012-02-15 00:11:25 +00002616 state = state->set<RegionState>(ReallocSym,
Anton Yartsev05789592013-03-28 17:05:19 +00002617 RefState::getAllocated(RS->getAllocationFamily(), RS->getStmt()));
Anna Zaks75cfbb62012-09-12 22:57:34 +00002618 else if (I.getData().Kind == RPDoNotTrackAfterFailure)
2619 state = state->remove<RegionState>(ReallocSym);
2620 else
2621 assert(I.getData().Kind == RPIsFreeOnFailure);
Anna Zaksd56c8792012-02-13 18:05:39 +00002622 }
Anna Zaksd56c8792012-02-13 18:05:39 +00002623 }
Anna Zaks75cfbb62012-09-12 22:57:34 +00002624 state = state->remove<ReallocPairs>(I.getKey());
Anna Zaksd56c8792012-02-13 18:05:39 +00002625 }
2626
Anna Zaksbb1ef902012-02-11 21:02:35 +00002627 return state;
2628}
2629
Anna Zaks8ebeb642013-06-08 00:29:29 +00002630bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002631 const CallEvent *Call,
2632 ProgramStateRef State,
2633 SymbolRef &EscapingSymbol) const {
Jordan Rose7ab01822012-07-02 19:27:51 +00002634 assert(Call);
Craig Topper0dbb7832014-05-27 02:45:47 +00002635 EscapingSymbol = nullptr;
2636
Jordan Rose2a833ca2014-01-15 17:25:15 +00002637 // For now, assume that any C++ or block call can free memory.
Anna Zaks7ac344a2012-02-24 23:56:53 +00002638 // TODO: If we want to be more optimistic here, we'll need to make sure that
2639 // regions escape to C++ containers. They seem to do that even now, but for
2640 // mysterious reasons.
Jordan Rose2a833ca2014-01-15 17:25:15 +00002641 if (!(isa<SimpleFunctionCall>(Call) || isa<ObjCMethodCall>(Call)))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002642 return true;
Anna Zaks7ac344a2012-02-24 23:56:53 +00002643
Jordan Rose742920c2012-07-02 19:27:35 +00002644 // Check Objective-C messages by selector name.
Jordan Rose6bad4902012-07-02 19:27:56 +00002645 if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) {
Jordan Rose7ab01822012-07-02 19:27:51 +00002646 // If it's not a framework call, or if it takes a callback, assume it
2647 // can free memory.
Anna Zaksfe1eca52015-10-27 20:19:45 +00002648 if (!Call->isInSystemHeader() || Call->argumentsMayEscape())
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002649 return true;
Anna Zaks06a77fc2012-02-28 01:54:22 +00002650
Jordan Rose613f3c02013-03-09 00:59:10 +00002651 // If it's a method we know about, handle it explicitly post-call.
2652 // This should happen before the "freeWhenDone" check below.
2653 if (isKnownDeallocObjCMethodName(*Msg))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002654 return false;
Anna Zaks886dfb82012-06-20 23:35:57 +00002655
Jordan Rose613f3c02013-03-09 00:59:10 +00002656 // If there's a "freeWhenDone" parameter, but the method isn't one we know
2657 // about, we can't be sure that the object will use free() to deallocate the
2658 // memory, so we can't model it explicitly. The best we can do is use it to
2659 // decide whether the pointer escapes.
2660 if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(*Msg))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002661 return *FreeWhenDone;
Anna Zaks7ac344a2012-02-24 23:56:53 +00002662
Jordan Rose613f3c02013-03-09 00:59:10 +00002663 // If the first selector piece ends with "NoCopy", and there is no
2664 // "freeWhenDone" parameter set to zero, we know ownership is being
2665 // transferred. Again, though, we can't be sure that the object will use
2666 // free() to deallocate the memory, so we can't model it explicitly.
2667 StringRef FirstSlot = Msg->getSelector().getNameForSlot(0);
Jordan Rose742920c2012-07-02 19:27:35 +00002668 if (FirstSlot.endswith("NoCopy"))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002669 return true;
Anna Zaks12a8b902012-03-05 17:42:10 +00002670
Anna Zaks42908c72012-06-19 05:10:32 +00002671 // If the first selector starts with addPointer, insertPointer,
2672 // or replacePointer, assume we are dealing with NSPointerArray or similar.
2673 // This is similar to C++ containers (vector); we still might want to check
Jordan Rose742920c2012-07-02 19:27:35 +00002674 // that the pointers get freed by following the container itself.
2675 if (FirstSlot.startswith("addPointer") ||
2676 FirstSlot.startswith("insertPointer") ||
Jordan Rose514f9352014-01-07 21:39:48 +00002677 FirstSlot.startswith("replacePointer") ||
2678 FirstSlot.equals("valueWithPointer")) {
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002679 return true;
Anna Zaks42908c72012-06-19 05:10:32 +00002680 }
2681
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002682 // We should escape receiver on call to 'init'. This is especially relevant
2683 // to the receiver, as the corresponding symbol is usually not referenced
2684 // after the call.
2685 if (Msg->getMethodFamily() == OMF_init) {
2686 EscapingSymbol = Msg->getReceiverSVal().getAsSymbol();
2687 return true;
2688 }
Anna Zaks737926b2013-05-31 22:39:13 +00002689
Jordan Rose742920c2012-07-02 19:27:35 +00002690 // Otherwise, assume that the method does not free memory.
2691 // Most framework methods do not free memory.
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002692 return false;
Anna Zaks3d348342012-02-14 21:55:24 +00002693 }
2694
Jordan Rose742920c2012-07-02 19:27:35 +00002695 // At this point the only thing left to handle is straight function calls.
Jordan Rose2a833ca2014-01-15 17:25:15 +00002696 const FunctionDecl *FD = cast<SimpleFunctionCall>(Call)->getDecl();
Jordan Rose742920c2012-07-02 19:27:35 +00002697 if (!FD)
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002698 return true;
Anna Zaks7ac344a2012-02-24 23:56:53 +00002699
Jordan Rose742920c2012-07-02 19:27:35 +00002700 ASTContext &ASTC = State->getStateManager().getContext();
2701
2702 // If it's one of the allocation functions we can reason about, we model
2703 // its behavior explicitly.
2704 if (isMemFunction(FD, ASTC))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002705 return false;
Jordan Rose742920c2012-07-02 19:27:35 +00002706
2707 // If it's not a system call, assume it frees memory.
2708 if (!Call->isInSystemHeader())
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002709 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00002710
2711 // White list the system functions whose arguments escape.
2712 const IdentifierInfo *II = FD->getIdentifier();
2713 if (!II)
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002714 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00002715 StringRef FName = II->getName();
2716
Jordan Rose742920c2012-07-02 19:27:35 +00002717 // White list the 'XXXNoCopy' CoreFoundation functions.
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002718 // We specifically check these before
Jordan Rose742920c2012-07-02 19:27:35 +00002719 if (FName.endswith("NoCopy")) {
2720 // Look for the deallocator argument. We know that the memory ownership
2721 // is not transferred only if the deallocator argument is
2722 // 'kCFAllocatorNull'.
2723 for (unsigned i = 1; i < Call->getNumArgs(); ++i) {
2724 const Expr *ArgE = Call->getArgExpr(i)->IgnoreParenCasts();
2725 if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) {
2726 StringRef DeallocatorName = DE->getFoundDecl()->getName();
2727 if (DeallocatorName == "kCFAllocatorNull")
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002728 return false;
Jordan Rose742920c2012-07-02 19:27:35 +00002729 }
2730 }
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002731 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00002732 }
2733
Jordan Rose742920c2012-07-02 19:27:35 +00002734 // Associating streams with malloced buffers. The pointer can escape if
Jordan Rose7ab01822012-07-02 19:27:51 +00002735 // 'closefn' is specified (and if that function does free memory),
2736 // but it will not if closefn is not specified.
Jordan Rose742920c2012-07-02 19:27:35 +00002737 // Currently, we do not inspect the 'closefn' function (PR12101).
2738 if (FName == "funopen")
Jordan Rose7ab01822012-07-02 19:27:51 +00002739 if (Call->getNumArgs() >= 4 && Call->getArgSVal(4).isConstant(0))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002740 return false;
Jordan Rose742920c2012-07-02 19:27:35 +00002741
2742 // Do not warn on pointers passed to 'setbuf' when used with std streams,
2743 // these leaks might be intentional when setting the buffer for stdio.
2744 // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer
2745 if (FName == "setbuf" || FName =="setbuffer" ||
2746 FName == "setlinebuf" || FName == "setvbuf") {
2747 if (Call->getNumArgs() >= 1) {
2748 const Expr *ArgE = Call->getArgExpr(0)->IgnoreParenCasts();
2749 if (const DeclRefExpr *ArgDRE = dyn_cast<DeclRefExpr>(ArgE))
2750 if (const VarDecl *D = dyn_cast<VarDecl>(ArgDRE->getDecl()))
2751 if (D->getCanonicalDecl()->getName().find("std") != StringRef::npos)
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002752 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00002753 }
2754 }
2755
2756 // A bunch of other functions which either take ownership of a pointer or
2757 // wrap the result up in a struct or object, meaning it can be freed later.
2758 // (See RetainCountChecker.) Not all the parameters here are invalidated,
2759 // but the Malloc checker cannot differentiate between them. The right way
2760 // of doing this would be to implement a pointer escapes callback.
2761 if (FName == "CGBitmapContextCreate" ||
2762 FName == "CGBitmapContextCreateWithData" ||
2763 FName == "CVPixelBufferCreateWithBytes" ||
2764 FName == "CVPixelBufferCreateWithPlanarBytes" ||
2765 FName == "OSAtomicEnqueue") {
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002766 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00002767 }
2768
Anna Zaks03f48332016-01-06 00:32:56 +00002769 if (FName == "postEvent" &&
2770 FD->getQualifiedNameAsString() == "QCoreApplication::postEvent") {
2771 return true;
2772 }
2773
2774 if (FName == "postEvent" &&
2775 FD->getQualifiedNameAsString() == "QCoreApplication::postEvent") {
2776 return true;
2777 }
2778
Artem Dergachev85c92112016-12-16 12:21:55 +00002779 if (FName == "connectImpl" &&
2780 FD->getQualifiedNameAsString() == "QObject::connectImpl") {
2781 return true;
2782 }
2783
Jordan Rose7ab01822012-07-02 19:27:51 +00002784 // Handle cases where we know a buffer's /address/ can escape.
2785 // Note that the above checks handle some special cases where we know that
2786 // even though the address escapes, it's still our responsibility to free the
2787 // buffer.
2788 if (Call->argumentsMayEscape())
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002789 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00002790
2791 // Otherwise, assume that the function does not free memory.
2792 // Most system calls do not free the memory.
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002793 return false;
Anna Zaks3d348342012-02-14 21:55:24 +00002794}
2795
Anna Zaks333481b2013-03-28 23:15:29 +00002796static bool retTrue(const RefState *RS) {
2797 return true;
2798}
2799
2800static bool checkIfNewOrNewArrayFamily(const RefState *RS) {
2801 return (RS->getAllocationFamily() == AF_CXXNewArray ||
2802 RS->getAllocationFamily() == AF_CXXNew);
2803}
2804
Anna Zaksdc154152012-12-20 00:38:25 +00002805ProgramStateRef MallocChecker::checkPointerEscape(ProgramStateRef State,
2806 const InvalidatedSymbols &Escaped,
Anna Zaksacdc13c2013-02-07 23:05:43 +00002807 const CallEvent *Call,
2808 PointerEscapeKind Kind) const {
Anna Zaks333481b2013-03-28 23:15:29 +00002809 return checkPointerEscapeAux(State, Escaped, Call, Kind, &retTrue);
2810}
2811
2812ProgramStateRef MallocChecker::checkConstPointerEscape(ProgramStateRef State,
2813 const InvalidatedSymbols &Escaped,
2814 const CallEvent *Call,
2815 PointerEscapeKind Kind) const {
2816 return checkPointerEscapeAux(State, Escaped, Call, Kind,
2817 &checkIfNewOrNewArrayFamily);
2818}
2819
2820ProgramStateRef MallocChecker::checkPointerEscapeAux(ProgramStateRef State,
2821 const InvalidatedSymbols &Escaped,
2822 const CallEvent *Call,
2823 PointerEscapeKind Kind,
2824 bool(*CheckRefState)(const RefState*)) const {
Jordan Rose613f3c02013-03-09 00:59:10 +00002825 // If we know that the call does not free memory, or we want to process the
2826 // call later, keep tracking the top level arguments.
Craig Topper0dbb7832014-05-27 02:45:47 +00002827 SymbolRef EscapingSymbol = nullptr;
Jordan Rose757fbb02013-05-10 17:07:16 +00002828 if (Kind == PSK_DirectEscapeOnCall &&
Anna Zaks8ebeb642013-06-08 00:29:29 +00002829 !mayFreeAnyEscapedMemoryOrIsModeledExplicitly(Call, State,
2830 EscapingSymbol) &&
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002831 !EscapingSymbol) {
Anna Zaks3d348342012-02-14 21:55:24 +00002832 return State;
Anna Zaksacdc13c2013-02-07 23:05:43 +00002833 }
Anna Zaks3d348342012-02-14 21:55:24 +00002834
Anna Zaksdc154152012-12-20 00:38:25 +00002835 for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
Anna Zaks333481b2013-03-28 23:15:29 +00002836 E = Escaped.end();
2837 I != E; ++I) {
Anna Zaksbb1ef902012-02-11 21:02:35 +00002838 SymbolRef sym = *I;
Anna Zaksdc154152012-12-20 00:38:25 +00002839
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002840 if (EscapingSymbol && EscapingSymbol != sym)
2841 continue;
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002842
Anna Zaks0d6989b2012-06-22 02:04:31 +00002843 if (const RefState *RS = State->get<RegionState>(sym)) {
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002844 if ((RS->isAllocated() || RS->isAllocatedOfSizeZero()) &&
2845 CheckRefState(RS)) {
Anna Zaks23a62012012-08-09 00:42:24 +00002846 State = State->remove<RegionState>(sym);
Anna Zaks93a21a82013-04-09 00:30:28 +00002847 State = State->set<RegionState>(sym, RefState::getEscaped(RS));
2848 }
Anna Zaks0d6989b2012-06-22 02:04:31 +00002849 }
Anna Zaksbb1ef902012-02-11 21:02:35 +00002850 }
Anna Zaks3d348342012-02-14 21:55:24 +00002851 return State;
Ted Kremenekd21139a2010-07-31 01:52:11 +00002852}
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +00002853
Jordy Rosebf38f202012-03-18 07:43:35 +00002854static SymbolRef findFailedReallocSymbol(ProgramStateRef currState,
2855 ProgramStateRef prevState) {
Jordan Rose0c153cb2012-11-02 01:54:06 +00002856 ReallocPairsTy currMap = currState->get<ReallocPairs>();
2857 ReallocPairsTy prevMap = prevState->get<ReallocPairs>();
Jordy Rosebf38f202012-03-18 07:43:35 +00002858
Jordan Rose0c153cb2012-11-02 01:54:06 +00002859 for (ReallocPairsTy::iterator I = prevMap.begin(), E = prevMap.end();
Jordy Rosebf38f202012-03-18 07:43:35 +00002860 I != E; ++I) {
2861 SymbolRef sym = I.getKey();
2862 if (!currMap.lookup(sym))
2863 return sym;
2864 }
2865
Craig Topper0dbb7832014-05-27 02:45:47 +00002866 return nullptr;
Jordy Rosebf38f202012-03-18 07:43:35 +00002867}
2868
Artem Dergachevff1fc212018-03-21 00:49:47 +00002869static bool isReferenceCountingPointerDestructor(const CXXDestructorDecl *DD) {
2870 if (const IdentifierInfo *II = DD->getParent()->getIdentifier()) {
2871 StringRef N = II->getName();
2872 if (N.contains_lower("ptr") || N.contains_lower("pointer")) {
2873 if (N.contains_lower("ref") || N.contains_lower("cnt") ||
2874 N.contains_lower("intrusive") || N.contains_lower("shared")) {
2875 return true;
2876 }
2877 }
2878 }
2879 return false;
2880}
2881
David Blaikie0a0c2752017-01-05 17:26:53 +00002882std::shared_ptr<PathDiagnosticPiece> MallocChecker::MallocBugVisitor::VisitNode(
2883 const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
2884 BugReport &BR) {
Reka Kovacs8707cd12018-07-07 17:22:45 +00002885
2886 ProgramStateRef state = N->getState();
2887 ProgramStateRef statePrev = PrevN->getState();
2888
2889 const RefState *RS = state->get<RegionState>(Sym);
2890 const RefState *RSPrev = statePrev->get<RegionState>(Sym);
2891
Artem Dergachev5337efc2018-02-27 21:19:33 +00002892 const Stmt *S = PathDiagnosticLocation::getStmt(N);
Reka Kovacs8707cd12018-07-07 17:22:45 +00002893 // When dealing with containers, we sometimes want to give a note
2894 // even if the statement is missing.
Reka Kovacs88ad7042018-07-20 15:14:49 +00002895 if (!S && (!RS || RS->getAllocationFamily() != AF_InnerBuffer))
Artem Dergachev5337efc2018-02-27 21:19:33 +00002896 return nullptr;
2897
2898 const LocationContext *CurrentLC = N->getLocationContext();
2899
2900 // If we find an atomic fetch_add or fetch_sub within the destructor in which
2901 // the pointer was released (before the release), this is likely a destructor
2902 // of a shared pointer.
2903 // Because we don't model atomics, and also because we don't know that the
2904 // original reference count is positive, we should not report use-after-frees
2905 // on objects deleted in such destructors. This can probably be improved
2906 // through better shared pointer modeling.
2907 if (ReleaseDestructorLC) {
2908 if (const auto *AE = dyn_cast<AtomicExpr>(S)) {
2909 AtomicExpr::AtomicOp Op = AE->getOp();
2910 if (Op == AtomicExpr::AO__c11_atomic_fetch_add ||
2911 Op == AtomicExpr::AO__c11_atomic_fetch_sub) {
2912 if (ReleaseDestructorLC == CurrentLC ||
2913 ReleaseDestructorLC->isParentOf(CurrentLC)) {
2914 BR.markInvalid(getTag(), S);
2915 }
2916 }
2917 }
2918 }
2919
Jordan Rose681cce92012-07-10 22:07:42 +00002920 // FIXME: We will eventually need to handle non-statement-based events
2921 // (__attribute__((cleanup))).
2922
Anna Zaks2b5bb972012-02-09 06:25:51 +00002923 // Find out if this is an interesting point and what is the kind.
Reka Kovacsa14a2fe2018-07-19 17:43:09 +00002924 StringRef Msg;
Gabor Horvath6ee4f902016-08-18 07:54:50 +00002925 StackHintGeneratorForSymbol *StackHint = nullptr;
Reka Kovacs52dd98b2018-07-19 15:44:46 +00002926 SmallString<256> Buf;
2927 llvm::raw_svector_ostream OS(Buf);
Reka Kovacs88ad7042018-07-20 15:14:49 +00002928
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002929 if (Mode == Normal) {
Anna Zaks1ff57d52012-03-15 21:13:02 +00002930 if (isAllocated(RS, RSPrev, S)) {
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002931 Msg = "Memory is allocated";
Anna Zaksa7f457a2012-03-16 23:44:28 +00002932 StackHint = new StackHintGeneratorForSymbol(Sym,
2933 "Returned allocated memory");
Anna Zaks1ff57d52012-03-15 21:13:02 +00002934 } else if (isReleased(RS, RSPrev, S)) {
Reka Kovacs8707cd12018-07-07 17:22:45 +00002935 const auto Family = RS->getAllocationFamily();
Reka Kovacsc18ecc82018-07-19 15:10:06 +00002936 switch (Family) {
Reka Kovacs8707cd12018-07-07 17:22:45 +00002937 case AF_Alloca:
2938 case AF_Malloc:
2939 case AF_CXXNew:
2940 case AF_CXXNewArray:
2941 case AF_IfNameIndex:
2942 Msg = "Memory is released";
2943 break;
Reka Kovacs88ad7042018-07-20 15:14:49 +00002944 case AF_InnerBuffer: {
Reka Kovacsc18ecc82018-07-19 15:10:06 +00002945 OS << "Inner pointer invalidated by call to ";
2946 if (N->getLocation().getKind() == ProgramPoint::PostImplicitCallKind) {
2947 OS << "destructor";
2948 } else {
2949 OS << "'";
2950 const Stmt *S = RS->getStmt();
2951 if (const auto *MemCallE = dyn_cast<CXXMemberCallExpr>(S)) {
2952 OS << MemCallE->getMethodDecl()->getNameAsString();
2953 } else if (const auto *OpCallE = dyn_cast<CXXOperatorCallExpr>(S)) {
2954 OS << OpCallE->getDirectCallee()->getNameAsString();
Reka Kovacsc74cfc42018-07-30 15:43:45 +00002955 } else if (const auto *CallE = dyn_cast<CallExpr>(S)) {
2956 auto &CEMgr = BRC.getStateManager().getCallEventManager();
2957 CallEventRef<> Call = CEMgr.getSimpleCall(CallE, state, CurrentLC);
2958 const auto *D = dyn_cast_or_null<NamedDecl>(Call->getDecl());
2959 OS << (D ? D->getNameAsString() : "unknown");
Reka Kovacsc18ecc82018-07-19 15:10:06 +00002960 }
2961 OS << "'";
2962 }
Reka Kovacsa14a2fe2018-07-19 17:43:09 +00002963 Msg = OS.str();
Reka Kovacs8707cd12018-07-07 17:22:45 +00002964 break;
Reka Kovacsc18ecc82018-07-19 15:10:06 +00002965 }
Reka Kovacs8707cd12018-07-07 17:22:45 +00002966 case AF_None:
Reka Kovacs8707cd12018-07-07 17:22:45 +00002967 llvm_unreachable("Unhandled allocation family!");
2968 }
Anna Zaksa7f457a2012-03-16 23:44:28 +00002969 StackHint = new StackHintGeneratorForSymbol(Sym,
Anna Zakse4cfcd42013-04-16 00:22:55 +00002970 "Returning; memory was released");
Artem Dergachev5337efc2018-02-27 21:19:33 +00002971
Artem Dergachevff1fc212018-03-21 00:49:47 +00002972 // See if we're releasing memory while inlining a destructor
2973 // (or one of its callees). This turns on various common
2974 // false positive suppressions.
2975 bool FoundAnyDestructor = false;
Artem Dergachev5337efc2018-02-27 21:19:33 +00002976 for (const LocationContext *LC = CurrentLC; LC; LC = LC->getParent()) {
Artem Dergachevff1fc212018-03-21 00:49:47 +00002977 if (const auto *DD = dyn_cast<CXXDestructorDecl>(LC->getDecl())) {
2978 if (isReferenceCountingPointerDestructor(DD)) {
2979 // This immediately looks like a reference-counting destructor.
2980 // We're bad at guessing the original reference count of the object,
2981 // so suppress the report for now.
2982 BR.markInvalid(getTag(), DD);
2983 } else if (!FoundAnyDestructor) {
2984 assert(!ReleaseDestructorLC &&
2985 "There can be only one release point!");
2986 // Suspect that it's a reference counting pointer destructor.
2987 // On one of the next nodes might find out that it has atomic
2988 // reference counting operations within it (see the code above),
2989 // and if so, we'd conclude that it likely is a reference counting
2990 // pointer destructor.
George Karpenkovdd18b112018-06-27 01:51:55 +00002991 ReleaseDestructorLC = LC->getStackFrame();
Artem Dergachevff1fc212018-03-21 00:49:47 +00002992 // It is unlikely that releasing memory is delegated to a destructor
2993 // inside a destructor of a shared pointer, because it's fairly hard
2994 // to pass the information that the pointer indeed needs to be
2995 // released into it. So we're only interested in the innermost
2996 // destructor.
2997 FoundAnyDestructor = true;
2998 }
Artem Dergachev5337efc2018-02-27 21:19:33 +00002999 }
3000 }
Anna Zaks0d6989b2012-06-22 02:04:31 +00003001 } else if (isRelinquished(RS, RSPrev, S)) {
Alp Toker5faf0c02013-12-02 03:50:25 +00003002 Msg = "Memory ownership is transferred";
Anna Zaks0d6989b2012-06-22 02:04:31 +00003003 StackHint = new StackHintGeneratorForSymbol(Sym, "");
Anna Zaks1ff57d52012-03-15 21:13:02 +00003004 } else if (isReallocFailedCheck(RS, RSPrev, S)) {
Anna Zaks9eb7bc82012-02-16 22:26:07 +00003005 Mode = ReallocationFailed;
3006 Msg = "Reallocation failed";
Anna Zakscba4f292012-03-16 23:24:20 +00003007 StackHint = new StackHintGeneratorForReallocationFailed(Sym,
Anna Zaksa7f457a2012-03-16 23:44:28 +00003008 "Reallocation failed");
Jordy Rosebf38f202012-03-18 07:43:35 +00003009
Jordy Rose21ff76e2012-03-24 03:15:09 +00003010 if (SymbolRef sym = findFailedReallocSymbol(state, statePrev)) {
3011 // Is it possible to fail two reallocs WITHOUT testing in between?
3012 assert((!FailedReallocSymbol || FailedReallocSymbol == sym) &&
3013 "We only support one failed realloc at a time.");
Jordy Rosebf38f202012-03-18 07:43:35 +00003014 BR.markInteresting(sym);
Jordy Rose21ff76e2012-03-24 03:15:09 +00003015 FailedReallocSymbol = sym;
3016 }
Anna Zaks9eb7bc82012-02-16 22:26:07 +00003017 }
3018
3019 // We are in a special mode if a reallocation failed later in the path.
3020 } else if (Mode == ReallocationFailed) {
Jordy Rose21ff76e2012-03-24 03:15:09 +00003021 assert(FailedReallocSymbol && "No symbol to look for.");
Anna Zaks9eb7bc82012-02-16 22:26:07 +00003022
Jordy Rose21ff76e2012-03-24 03:15:09 +00003023 // Is this is the first appearance of the reallocated symbol?
3024 if (!statePrev->get<RegionState>(FailedReallocSymbol)) {
Jordy Rose21ff76e2012-03-24 03:15:09 +00003025 // We're at the reallocation point.
3026 Msg = "Attempt to reallocate memory";
3027 StackHint = new StackHintGeneratorForSymbol(Sym,
3028 "Returned reallocated memory");
Craig Topper0dbb7832014-05-27 02:45:47 +00003029 FailedReallocSymbol = nullptr;
Jordy Rose21ff76e2012-03-24 03:15:09 +00003030 Mode = Normal;
3031 }
Anna Zaks9eb7bc82012-02-16 22:26:07 +00003032 }
3033
Reka Kovacsa14a2fe2018-07-19 17:43:09 +00003034 if (Msg.empty())
Craig Topper0dbb7832014-05-27 02:45:47 +00003035 return nullptr;
Anna Zakscba4f292012-03-16 23:24:20 +00003036 assert(StackHint);
Anna Zaks2b5bb972012-02-09 06:25:51 +00003037
3038 // Generate the extra diagnostic.
Reka Kovacs8707cd12018-07-07 17:22:45 +00003039 PathDiagnosticLocation Pos;
3040 if (!S) {
Reka Kovacs88ad7042018-07-20 15:14:49 +00003041 assert(RS->getAllocationFamily() == AF_InnerBuffer);
Reka Kovacs8707cd12018-07-07 17:22:45 +00003042 auto PostImplCall = N->getLocation().getAs<PostImplicitCall>();
3043 if (!PostImplCall)
3044 return nullptr;
3045 Pos = PathDiagnosticLocation(PostImplCall->getLocation(),
3046 BRC.getSourceManager());
3047 } else {
3048 Pos = PathDiagnosticLocation(S, BRC.getSourceManager(),
3049 N->getLocationContext());
3050 }
3051
David Blaikie0a0c2752017-01-05 17:26:53 +00003052 return std::make_shared<PathDiagnosticEventPiece>(Pos, Msg, true, StackHint);
Anna Zaks2b5bb972012-02-09 06:25:51 +00003053}
3054
Anna Zaks263b7e02012-05-02 00:05:20 +00003055void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State,
3056 const char *NL, const char *Sep) const {
3057
3058 RegionStateTy RS = State->get<RegionState>();
3059
Ted Kremenek6fcefb52013-01-03 01:30:12 +00003060 if (!RS.isEmpty()) {
Anton Yartsev6a619222014-02-17 18:25:34 +00003061 Out << Sep << "MallocChecker :" << NL;
Ted Kremenek6fcefb52013-01-03 01:30:12 +00003062 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
Anton Yartsev6a619222014-02-17 18:25:34 +00003063 const RefState *RefS = State->get<RegionState>(I.getKey());
3064 AllocationFamily Family = RefS->getAllocationFamily();
Anton Yartsev4eb394d2015-03-07 00:31:53 +00003065 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
Anton Yartsev2487dd62015-03-10 22:24:21 +00003066 if (!CheckKind.hasValue())
3067 CheckKind = getCheckIfTracked(Family, true);
Anton Yartsev4eb394d2015-03-07 00:31:53 +00003068
Ted Kremenek6fcefb52013-01-03 01:30:12 +00003069 I.getKey()->dumpToStream(Out);
3070 Out << " : ";
3071 I.getData().dump(Out);
Anton Yartsev6a619222014-02-17 18:25:34 +00003072 if (CheckKind.hasValue())
3073 Out << " (" << CheckNames[*CheckKind].getName() << ")";
Ted Kremenek6fcefb52013-01-03 01:30:12 +00003074 Out << NL;
3075 }
3076 }
Anna Zaks263b7e02012-05-02 00:05:20 +00003077}
Anna Zaks2b5bb972012-02-09 06:25:51 +00003078
Reka Kovacs18775fc2018-06-09 13:03:49 +00003079namespace clang {
3080namespace ento {
3081namespace allocation_state {
3082
3083ProgramStateRef
3084markReleased(ProgramStateRef State, SymbolRef Sym, const Expr *Origin) {
Reka Kovacs88ad7042018-07-20 15:14:49 +00003085 AllocationFamily Family = AF_InnerBuffer;
Reka Kovacs18775fc2018-06-09 13:03:49 +00003086 return State->set<RegionState>(Sym, RefState::getReleased(Family, Origin));
3087}
3088
3089} // end namespace allocation_state
3090} // end namespace ento
3091} // end namespace clang
3092
Anna Zakse4cfcd42013-04-16 00:22:55 +00003093void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) {
3094 registerCStringCheckerBasic(mgr);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00003095 MallocChecker *checker = mgr.registerChecker<MallocChecker>();
Gabor Horvathe40c71c2015-03-04 17:59:34 +00003096 checker->IsOptimistic = mgr.getAnalyzerOptions().getBooleanOption(
3097 "Optimistic", false, checker);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00003098 checker->ChecksEnabled[MallocChecker::CK_NewDeleteLeaksChecker] = true;
3099 checker->CheckNames[MallocChecker::CK_NewDeleteLeaksChecker] =
3100 mgr.getCurrentCheckName();
Ted Kremenek3a0678e2015-09-08 03:50:52 +00003101 // We currently treat NewDeleteLeaks checker as a subchecker of NewDelete
Anna Zakse4cfcd42013-04-16 00:22:55 +00003102 // checker.
Gabor Horvathb77bc6b2018-01-06 10:51:00 +00003103 if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker]) {
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00003104 checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker] = true;
Gabor Horvathb77bc6b2018-01-06 10:51:00 +00003105 // FIXME: This does not set the correct name, but without this workaround
3106 // no name will be set at all.
3107 checker->CheckNames[MallocChecker::CK_NewDeleteChecker] =
3108 mgr.getCurrentCheckName();
3109 }
Anna Zakse4cfcd42013-04-16 00:22:55 +00003110}
Anton Yartsev7af0aa82013-04-12 23:25:40 +00003111
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00003112#define REGISTER_CHECKER(name) \
3113 void ento::register##name(CheckerManager &mgr) { \
3114 registerCStringCheckerBasic(mgr); \
3115 MallocChecker *checker = mgr.registerChecker<MallocChecker>(); \
Gabor Horvathe40c71c2015-03-04 17:59:34 +00003116 checker->IsOptimistic = mgr.getAnalyzerOptions().getBooleanOption( \
3117 "Optimistic", false, checker); \
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00003118 checker->ChecksEnabled[MallocChecker::CK_##name] = true; \
3119 checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \
3120 }
Anna Zakscd37bf42012-02-08 23:16:52 +00003121
Gabor Horvathe40c71c2015-03-04 17:59:34 +00003122REGISTER_CHECKER(MallocChecker)
Anton Yartsev13df0362013-03-25 01:35:45 +00003123REGISTER_CHECKER(NewDeleteChecker)
Anton Yartsev05789592013-03-28 17:05:19 +00003124REGISTER_CHECKER(MismatchedDeallocatorChecker)