blob: 8fb255c4232561bd391f41db1b862f738f6f4daf [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"
Anna Zaks199e8e52012-02-22 03:14:20 +000033#include <climits>
Benjamin Kramercfeacf52016-05-27 14:27:13 +000034#include <utility>
Anna Zaks199e8e52012-02-22 03:14:20 +000035
Zhongxing Xu88cca6b2009-11-12 08:38:56 +000036using namespace clang;
Ted Kremenek98857c92010-12-23 07:20:52 +000037using namespace ento;
Zhongxing Xu88cca6b2009-11-12 08:38:56 +000038
39namespace {
40
Anton Yartsev05789592013-03-28 17:05:19 +000041// Used to check correspondence between allocators and deallocators.
42enum AllocationFamily {
43 AF_None,
44 AF_Malloc,
45 AF_CXXNew,
Anna Zaksd79b8402014-10-03 21:48:59 +000046 AF_CXXNewArray,
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +000047 AF_IfNameIndex,
48 AF_Alloca
Anton Yartsev05789592013-03-28 17:05:19 +000049};
50
Zhongxing Xu1239de12009-12-11 00:55:44 +000051class RefState {
Anna Zaks9050ffd2012-06-20 20:57:46 +000052 enum Kind { // Reference to allocated memory.
53 Allocated,
Anton Yartsevb50f4ba2015-04-14 14:18:04 +000054 // Reference to zero-allocated memory.
55 AllocatedOfSizeZero,
Anna Zaks9050ffd2012-06-20 20:57:46 +000056 // Reference to released/freed memory.
57 Released,
Alp Toker5faf0c02013-12-02 03:50:25 +000058 // The responsibility for freeing resources has transferred from
Anna Zaks9050ffd2012-06-20 20:57:46 +000059 // this reference. A relinquished symbol should not be freed.
Anna Zaks93a21a82013-04-09 00:30:28 +000060 Relinquished,
61 // We are no longer guaranteed to have observed all manipulations
62 // of this pointer/memory. For example, it could have been
63 // passed as a parameter to an opaque function.
64 Escaped
65 };
Anton Yartsev05789592013-03-28 17:05:19 +000066
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000067 const Stmt *S;
Anton Yartsevb50f4ba2015-04-14 14:18:04 +000068 unsigned K : 3; // Kind enum, but stored as a bitfield.
Ted Kremenek3a0678e2015-09-08 03:50:52 +000069 unsigned Family : 29; // Rest of 32-bit word, currently just an allocation
Anton Yartsev05789592013-03-28 17:05:19 +000070 // family.
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000071
Ted Kremenek3a0678e2015-09-08 03:50:52 +000072 RefState(Kind k, const Stmt *s, unsigned family)
Anna Zaks93a21a82013-04-09 00:30:28 +000073 : S(s), K(k), Family(family) {
74 assert(family != AF_None);
75 }
Zhongxing Xu1239de12009-12-11 00:55:44 +000076public:
Anna Zaks9050ffd2012-06-20 20:57:46 +000077 bool isAllocated() const { return K == Allocated; }
Anton Yartsevb50f4ba2015-04-14 14:18:04 +000078 bool isAllocatedOfSizeZero() const { return K == AllocatedOfSizeZero; }
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000079 bool isReleased() const { return K == Released; }
Anna Zaks9050ffd2012-06-20 20:57:46 +000080 bool isRelinquished() const { return K == Relinquished; }
Anna Zaks93a21a82013-04-09 00:30:28 +000081 bool isEscaped() const { return K == Escaped; }
82 AllocationFamily getAllocationFamily() const {
Anton Yartsev05789592013-03-28 17:05:19 +000083 return (AllocationFamily)Family;
84 }
Anna Zaksd56c8792012-02-13 18:05:39 +000085 const Stmt *getStmt() const { return S; }
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000086
87 bool operator==(const RefState &X) const {
Anton Yartsev05789592013-03-28 17:05:19 +000088 return K == X.K && S == X.S && Family == X.Family;
Zhongxing Xu4668c7e2009-11-17 07:54:15 +000089 }
90
Anton Yartsev05789592013-03-28 17:05:19 +000091 static RefState getAllocated(unsigned family, const Stmt *s) {
92 return RefState(Allocated, s, family);
Zhongxing Xub0e15df2009-12-31 06:13:07 +000093 }
Anton Yartsevb50f4ba2015-04-14 14:18:04 +000094 static RefState getAllocatedOfSizeZero(const RefState *RS) {
95 return RefState(AllocatedOfSizeZero, RS->getStmt(),
96 RS->getAllocationFamily());
97 }
Ted Kremenek3a0678e2015-09-08 03:50:52 +000098 static RefState getReleased(unsigned family, const Stmt *s) {
Anton Yartsev05789592013-03-28 17:05:19 +000099 return RefState(Released, s, family);
100 }
101 static RefState getRelinquished(unsigned family, const Stmt *s) {
102 return RefState(Relinquished, s, family);
Ted Kremenek0bbf24d2010-08-06 21:12:55 +0000103 }
Anna Zaks93a21a82013-04-09 00:30:28 +0000104 static RefState getEscaped(const RefState *RS) {
105 return RefState(Escaped, RS->getStmt(), RS->getAllocationFamily());
106 }
Zhongxing Xu4668c7e2009-11-17 07:54:15 +0000107
108 void Profile(llvm::FoldingSetNodeID &ID) const {
109 ID.AddInteger(K);
110 ID.AddPointer(S);
Anton Yartsev05789592013-03-28 17:05:19 +0000111 ID.AddInteger(Family);
Zhongxing Xu4668c7e2009-11-17 07:54:15 +0000112 }
Ted Kremenek6fcefb52013-01-03 01:30:12 +0000113
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000114 void dump(raw_ostream &OS) const {
Jordan Rose6adadb92014-01-23 03:59:01 +0000115 switch (static_cast<Kind>(K)) {
116#define CASE(ID) case ID: OS << #ID; break;
117 CASE(Allocated)
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000118 CASE(AllocatedOfSizeZero)
Jordan Rose6adadb92014-01-23 03:59:01 +0000119 CASE(Released)
120 CASE(Relinquished)
121 CASE(Escaped)
122 }
Ted Kremenek6fcefb52013-01-03 01:30:12 +0000123 }
124
Alp Tokeref6b0072014-01-04 13:47:14 +0000125 LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); }
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000126};
127
Anna Zaks75cfbb62012-09-12 22:57:34 +0000128enum ReallocPairKind {
129 RPToBeFreedAfterFailure,
130 // The symbol has been freed when reallocation failed.
131 RPIsFreeOnFailure,
132 // The symbol does not need to be freed after reallocation fails.
133 RPDoNotTrackAfterFailure
134};
135
Anna Zaksfe6eb672012-08-24 02:28:20 +0000136/// \class ReallocPair
137/// \brief Stores information about the symbol being reallocated by a call to
138/// 'realloc' to allow modeling failed reallocation later in the path.
Anna Zaksac068142012-02-15 00:11:25 +0000139struct ReallocPair {
Anna Zaksfe6eb672012-08-24 02:28:20 +0000140 // \brief The symbol which realloc reallocated.
Anna Zaksac068142012-02-15 00:11:25 +0000141 SymbolRef ReallocatedSym;
Anna Zaks75cfbb62012-09-12 22:57:34 +0000142 ReallocPairKind Kind;
Anna Zaksfe6eb672012-08-24 02:28:20 +0000143
Anna Zaks75cfbb62012-09-12 22:57:34 +0000144 ReallocPair(SymbolRef S, ReallocPairKind K) :
145 ReallocatedSym(S), Kind(K) {}
Anna Zaksac068142012-02-15 00:11:25 +0000146 void Profile(llvm::FoldingSetNodeID &ID) const {
Anna Zaks75cfbb62012-09-12 22:57:34 +0000147 ID.AddInteger(Kind);
Anna Zaksac068142012-02-15 00:11:25 +0000148 ID.AddPointer(ReallocatedSym);
149 }
150 bool operator==(const ReallocPair &X) const {
151 return ReallocatedSym == X.ReallocatedSym &&
Anna Zaks75cfbb62012-09-12 22:57:34 +0000152 Kind == X.Kind;
Anna Zaksac068142012-02-15 00:11:25 +0000153 }
154};
155
Anna Zaksa043d0c2013-01-08 00:25:29 +0000156typedef std::pair<const ExplodedNode*, const MemRegion*> LeakInfo;
Anna Zaksfc2e1532012-03-21 19:45:08 +0000157
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000158class MallocChecker : public Checker<check::DeadSymbols,
Anna Zaksdc154152012-12-20 00:38:25 +0000159 check::PointerEscape,
Anna Zaks333481b2013-03-28 23:15:29 +0000160 check::ConstPointerEscape,
Ted Kremenek778d2bb2012-01-04 23:48:37 +0000161 check::PreStmt<ReturnStmt>,
Anton Yartsevcb2ccd62013-04-10 22:21:41 +0000162 check::PreCall,
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000163 check::PostStmt<CallExpr>,
Anton Yartsev13df0362013-03-25 01:35:45 +0000164 check::PostStmt<CXXNewExpr>,
Artem Dergachev13b20262018-01-17 23:46:13 +0000165 check::NewAllocator,
Anton Yartsev13df0362013-03-25 01:35:45 +0000166 check::PreStmt<CXXDeleteExpr>,
Anna Zaks9fe80982012-03-22 00:57:20 +0000167 check::PostStmt<BlockExpr>,
Anna Zaks67291b92012-11-13 03:18:01 +0000168 check::PostObjCMessage,
Ted Kremenek778d2bb2012-01-04 23:48:37 +0000169 check::Location,
Anna Zaksdc154152012-12-20 00:38:25 +0000170 eval::Assume>
Ted Kremenek778d2bb2012-01-04 23:48:37 +0000171{
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000172public:
Craig Topper0dbb7832014-05-27 02:45:47 +0000173 MallocChecker()
Anna Zaks30d46682016-03-08 01:21:51 +0000174 : II_alloca(nullptr), II_win_alloca(nullptr), II_malloc(nullptr),
175 II_free(nullptr), II_realloc(nullptr), II_calloc(nullptr),
176 II_valloc(nullptr), II_reallocf(nullptr), II_strndup(nullptr),
177 II_strdup(nullptr), II_win_strdup(nullptr), II_kmalloc(nullptr),
178 II_if_nameindex(nullptr), II_if_freenameindex(nullptr),
Anna Zaksbbec97c2017-03-09 00:01:01 +0000179 II_wcsdup(nullptr), II_win_wcsdup(nullptr), II_g_malloc(nullptr),
180 II_g_malloc0(nullptr), II_g_realloc(nullptr), II_g_try_malloc(nullptr),
181 II_g_try_malloc0(nullptr), II_g_try_realloc(nullptr),
Leslie Zhaie3986c52017-04-26 05:33:14 +0000182 II_g_free(nullptr), II_g_memdup(nullptr), II_g_malloc_n(nullptr),
183 II_g_malloc0_n(nullptr), II_g_realloc_n(nullptr),
184 II_g_try_malloc_n(nullptr), II_g_try_malloc0_n(nullptr),
185 II_g_try_realloc_n(nullptr) {}
Anna Zakscd37bf42012-02-08 23:16:52 +0000186
187 /// In pessimistic mode, the checker assumes that it does not know which
188 /// functions might free the memory.
Alexander Kornienko4aca9b12014-02-11 21:49:21 +0000189 enum CheckKind {
Gabor Horvathe40c71c2015-03-04 17:59:34 +0000190 CK_MallocChecker,
Alexander Kornienko4aca9b12014-02-11 21:49:21 +0000191 CK_NewDeleteChecker,
192 CK_NewDeleteLeaksChecker,
193 CK_MismatchedDeallocatorChecker,
194 CK_NumCheckKinds
Anna Zakscd37bf42012-02-08 23:16:52 +0000195 };
196
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000197 enum class MemoryOperationKind {
Anna Zaksd79b8402014-10-03 21:48:59 +0000198 MOK_Allocate,
199 MOK_Free,
200 MOK_Any
201 };
202
Gabor Horvathe40c71c2015-03-04 17:59:34 +0000203 DefaultBool IsOptimistic;
204
Alexander Kornienko4aca9b12014-02-11 21:49:21 +0000205 DefaultBool ChecksEnabled[CK_NumCheckKinds];
206 CheckName CheckNames[CK_NumCheckKinds];
Anna Zakscd37bf42012-02-08 23:16:52 +0000207
Anton Yartsevcb2ccd62013-04-10 22:21:41 +0000208 void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000209 void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
Anton Yartsev13df0362013-03-25 01:35:45 +0000210 void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const;
Artem Dergachev13b20262018-01-17 23:46:13 +0000211 void checkNewAllocator(const CXXNewExpr *NE, SVal Target,
212 CheckerContext &C) const;
Anton Yartsev13df0362013-03-25 01:35:45 +0000213 void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
Anna Zaks67291b92012-11-13 03:18:01 +0000214 void checkPostObjCMessage(const ObjCMethodCall &Call, CheckerContext &C) const;
Anna Zaks9fe80982012-03-22 00:57:20 +0000215 void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +0000216 void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +0000217 void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
Ted Kremenek49b1e382012-01-26 21:29:00 +0000218 ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +0000219 bool Assumption) const;
Anna Zaks3e0f4152011-10-06 00:43:15 +0000220 void checkLocation(SVal l, bool isLoad, const Stmt *S,
221 CheckerContext &C) const;
Anna Zaksdc154152012-12-20 00:38:25 +0000222
223 ProgramStateRef checkPointerEscape(ProgramStateRef State,
224 const InvalidatedSymbols &Escaped,
Anna Zaksacdc13c2013-02-07 23:05:43 +0000225 const CallEvent *Call,
226 PointerEscapeKind Kind) const;
Anna Zaks333481b2013-03-28 23:15:29 +0000227 ProgramStateRef checkConstPointerEscape(ProgramStateRef State,
228 const InvalidatedSymbols &Escaped,
229 const CallEvent *Call,
230 PointerEscapeKind Kind) const;
Zhongxing Xub0e15df2009-12-31 06:13:07 +0000231
Anna Zaks263b7e02012-05-02 00:05:20 +0000232 void printState(raw_ostream &Out, ProgramStateRef State,
Craig Topperfb6b25b2014-03-15 04:29:04 +0000233 const char *NL, const char *Sep) const override;
Anna Zaks263b7e02012-05-02 00:05:20 +0000234
Zhongxing Xuc4902a52009-11-13 07:25:27 +0000235private:
Ahmed Charlesb8984322014-03-07 20:03:18 +0000236 mutable std::unique_ptr<BugType> BT_DoubleFree[CK_NumCheckKinds];
237 mutable std::unique_ptr<BugType> BT_DoubleDelete;
238 mutable std::unique_ptr<BugType> BT_Leak[CK_NumCheckKinds];
239 mutable std::unique_ptr<BugType> BT_UseFree[CK_NumCheckKinds];
240 mutable std::unique_ptr<BugType> BT_BadFree[CK_NumCheckKinds];
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000241 mutable std::unique_ptr<BugType> BT_FreeAlloca[CK_NumCheckKinds];
Ahmed Charlesb8984322014-03-07 20:03:18 +0000242 mutable std::unique_ptr<BugType> BT_MismatchedDealloc;
243 mutable std::unique_ptr<BugType> BT_OffsetFree[CK_NumCheckKinds];
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000244 mutable std::unique_ptr<BugType> BT_UseZerroAllocated[CK_NumCheckKinds];
Anna Zaks30d46682016-03-08 01:21:51 +0000245 mutable IdentifierInfo *II_alloca, *II_win_alloca, *II_malloc, *II_free,
246 *II_realloc, *II_calloc, *II_valloc, *II_reallocf,
247 *II_strndup, *II_strdup, *II_win_strdup, *II_kmalloc,
248 *II_if_nameindex, *II_if_freenameindex, *II_wcsdup,
Anna Zaksbbec97c2017-03-09 00:01:01 +0000249 *II_win_wcsdup, *II_g_malloc, *II_g_malloc0,
250 *II_g_realloc, *II_g_try_malloc, *II_g_try_malloc0,
Leslie Zhaie3986c52017-04-26 05:33:14 +0000251 *II_g_try_realloc, *II_g_free, *II_g_memdup,
252 *II_g_malloc_n, *II_g_malloc0_n, *II_g_realloc_n,
253 *II_g_try_malloc_n, *II_g_try_malloc0_n,
254 *II_g_try_realloc_n;
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000255 mutable Optional<uint64_t> KernelZeroFlagVal;
Alexander Kornienko4aca9b12014-02-11 21:49:21 +0000256
Anna Zaks3d348342012-02-14 21:55:24 +0000257 void initIdentifierInfo(ASTContext &C) const;
258
Anton Yartsev05789592013-03-28 17:05:19 +0000259 /// \brief Determine family of a deallocation expression.
Anton Yartseve3377fb2013-04-04 23:46:29 +0000260 AllocationFamily getAllocationFamily(CheckerContext &C, const Stmt *S) const;
Anton Yartsev05789592013-03-28 17:05:19 +0000261
262 /// \brief Print names of allocators and deallocators.
263 ///
264 /// \returns true on success.
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000265 bool printAllocDeallocName(raw_ostream &os, CheckerContext &C,
Anton Yartsev05789592013-03-28 17:05:19 +0000266 const Expr *E) const;
267
268 /// \brief Print expected name of an allocator based on the deallocator's
269 /// family derived from the DeallocExpr.
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000270 void printExpectedAllocName(raw_ostream &os, CheckerContext &C,
Anton Yartsev05789592013-03-28 17:05:19 +0000271 const Expr *DeallocExpr) const;
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000272 /// \brief Print expected name of a deallocator based on the allocator's
Anton Yartsev05789592013-03-28 17:05:19 +0000273 /// family.
274 void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) const;
275
Jordan Rose613f3c02013-03-09 00:59:10 +0000276 ///@{
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000277 /// Check if this is one of the functions which can allocate/reallocate memory
Anna Zaks3d348342012-02-14 21:55:24 +0000278 /// pointed to by one of its arguments.
279 bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const;
Anna Zaksd79b8402014-10-03 21:48:59 +0000280 bool isCMemFunction(const FunctionDecl *FD,
281 ASTContext &C,
282 AllocationFamily Family,
Benjamin Kramer719772c2014-10-03 22:20:30 +0000283 MemoryOperationKind MemKind) const;
Anton Yartsev13df0362013-03-25 01:35:45 +0000284 bool isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const;
Jordan Rose613f3c02013-03-09 00:59:10 +0000285 ///@}
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000286
Artem Dergachev13b20262018-01-17 23:46:13 +0000287 /// \brief Process C++ operator new()'s allocation, which is the part of C++
288 /// new-expression that goes before the constructor.
289 void processNewAllocation(const CXXNewExpr *NE, CheckerContext &C,
290 SVal Target) const;
291
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000292 /// \brief Perform a zero-allocation check.
Artem Dergachev13b20262018-01-17 23:46:13 +0000293 /// The optional \p RetVal parameter specifies the newly allocated pointer
294 /// value; if unspecified, the value of expression \p E is used.
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000295 ProgramStateRef ProcessZeroAllocation(CheckerContext &C, const Expr *E,
296 const unsigned AllocationSizeArg,
Artem Dergachev13b20262018-01-17 23:46:13 +0000297 ProgramStateRef State,
298 Optional<SVal> RetVal = None) const;
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000299
Richard Smith852e9ce2013-11-27 01:46:48 +0000300 ProgramStateRef MallocMemReturnsAttr(CheckerContext &C,
301 const CallExpr *CE,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000302 const OwnershipAttr* Att,
303 ProgramStateRef State) const;
Ted Kremenek49b1e382012-01-26 21:29:00 +0000304 static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000305 const Expr *SizeEx, SVal Init,
306 ProgramStateRef State,
307 AllocationFamily Family = AF_Malloc);
Ted Kremenek49b1e382012-01-26 21:29:00 +0000308 static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000309 SVal SizeEx, SVal Init,
310 ProgramStateRef State,
311 AllocationFamily Family = AF_Malloc);
Zhongxing Xu527ff6d2010-06-01 03:01:33 +0000312
Gabor Horvath73040272016-09-19 20:39:52 +0000313 static ProgramStateRef addExtentSize(CheckerContext &C, const CXXNewExpr *NE,
Artem Dergachev13b20262018-01-17 23:46:13 +0000314 ProgramStateRef State, SVal Target);
Gabor Horvath73040272016-09-19 20:39:52 +0000315
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000316 // Check if this malloc() for special flags. At present that means M_ZERO or
317 // __GFP_ZERO (in which case, treat it like calloc).
318 llvm::Optional<ProgramStateRef>
319 performKernelMalloc(const CallExpr *CE, CheckerContext &C,
320 const ProgramStateRef &State) const;
321
Anna Zaks40a7eb32012-02-22 19:24:52 +0000322 /// Update the RefState to reflect the new memory allocation.
Artem Dergachev13b20262018-01-17 23:46:13 +0000323 /// The optional \p RetVal parameter specifies the newly allocated pointer
324 /// value; if unspecified, the value of expression \p E is used.
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000325 static ProgramStateRef
Anton Yartsev05789592013-03-28 17:05:19 +0000326 MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State,
Artem Dergachev13b20262018-01-17 23:46:13 +0000327 AllocationFamily Family = AF_Malloc,
328 Optional<SVal> RetVal = None);
Anna Zaks40a7eb32012-02-22 19:24:52 +0000329
330 ProgramStateRef FreeMemAttr(CheckerContext &C, const CallExpr *CE,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000331 const OwnershipAttr* Att,
332 ProgramStateRef State) const;
Ted Kremenek49b1e382012-01-26 21:29:00 +0000333 ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE,
Anna Zaks0d6989b2012-06-22 02:04:31 +0000334 ProgramStateRef state, unsigned Num,
Anna Zaksfe6eb672012-08-24 02:28:20 +0000335 bool Hold,
Anna Zaks67291b92012-11-13 03:18:01 +0000336 bool &ReleasedAllocated,
337 bool ReturnsNullOnFailure = false) const;
Anna Zaks0d6989b2012-06-22 02:04:31 +0000338 ProgramStateRef FreeMemAux(CheckerContext &C, const Expr *Arg,
339 const Expr *ParentExpr,
Anna Zaks67291b92012-11-13 03:18:01 +0000340 ProgramStateRef State,
Anna Zaksfe6eb672012-08-24 02:28:20 +0000341 bool Hold,
Anna Zaks67291b92012-11-13 03:18:01 +0000342 bool &ReleasedAllocated,
343 bool ReturnsNullOnFailure = false) const;
Zhongxing Xuc0484fa2009-12-12 12:29:38 +0000344
Leslie Zhaie3986c52017-04-26 05:33:14 +0000345 ProgramStateRef ReallocMemAux(CheckerContext &C, const CallExpr *CE,
346 bool FreesMemOnFailure,
347 ProgramStateRef State,
348 bool SuffixWithN = false) const;
349 static SVal evalMulForBufferSize(CheckerContext &C, const Expr *Blocks,
350 const Expr *BlockBytes);
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000351 static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE,
352 ProgramStateRef State);
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000353
Anna Zaks46d01602012-05-18 01:16:10 +0000354 ///\brief Check if the memory associated with this symbol was released.
355 bool isReleased(SymbolRef Sym, CheckerContext &C) const;
356
Anton Yartsev13df0362013-03-25 01:35:45 +0000357 bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const;
Anna Zaksa1b227b2012-02-08 23:16:56 +0000358
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000359 void checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C,
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000360 const Stmt *S) const;
361
Jordan Rose656fdd52014-01-08 18:46:55 +0000362 bool checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const;
363
Anna Zaksa4bc5e12013-05-31 23:47:32 +0000364 /// Check if the function is known free memory, or if it is
Jordan Rose613f3c02013-03-09 00:59:10 +0000365 /// "interesting" and should be modeled explicitly.
366 ///
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000367 /// \param [out] EscapingSymbol A function might not free memory in general,
Anna Zaks8ebeb642013-06-08 00:29:29 +0000368 /// but could be known to free a particular symbol. In this case, false is
Anna Zaksa4bc5e12013-05-31 23:47:32 +0000369 /// returned and the single escaping symbol is returned through the out
370 /// parameter.
371 ///
Jordan Rose613f3c02013-03-09 00:59:10 +0000372 /// We assume that pointers do not escape through calls to system functions
373 /// not handled by this checker.
Anna Zaks8ebeb642013-06-08 00:29:29 +0000374 bool mayFreeAnyEscapedMemoryOrIsModeledExplicitly(const CallEvent *Call,
Anna Zaksa4bc5e12013-05-31 23:47:32 +0000375 ProgramStateRef State,
376 SymbolRef &EscapingSymbol) const;
Anna Zaks3d348342012-02-14 21:55:24 +0000377
Anna Zaks333481b2013-03-28 23:15:29 +0000378 // Implementation of the checkPointerEscape callabcks.
379 ProgramStateRef checkPointerEscapeAux(ProgramStateRef State,
380 const InvalidatedSymbols &Escaped,
381 const CallEvent *Call,
382 PointerEscapeKind Kind,
383 bool(*CheckRefState)(const RefState*)) const;
384
Anton Yartsev1e2bc9b2013-04-11 00:05:20 +0000385 ///@{
386 /// Tells if a given family/call/symbol is tracked by the current checker.
Anton Yartsev4eb394d2015-03-07 00:31:53 +0000387 /// Sets CheckKind to the kind of the checker responsible for this
388 /// family/call/symbol.
Anton Yartsev2487dd62015-03-10 22:24:21 +0000389 Optional<CheckKind> getCheckIfTracked(AllocationFamily Family,
390 bool IsALeakCheck = false) const;
Anton Yartsev4eb394d2015-03-07 00:31:53 +0000391 Optional<CheckKind> getCheckIfTracked(CheckerContext &C,
Anton Yartsev2487dd62015-03-10 22:24:21 +0000392 const Stmt *AllocDeallocStmt,
393 bool IsALeakCheck = false) const;
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000394 Optional<CheckKind> getCheckIfTracked(CheckerContext &C, SymbolRef Sym,
Anton Yartsev2487dd62015-03-10 22:24:21 +0000395 bool IsALeakCheck = false) const;
Anton Yartsev1e2bc9b2013-04-11 00:05:20 +0000396 ///@}
Ted Kremenek5ef32db2011-08-12 23:37:29 +0000397 static bool SummarizeValue(raw_ostream &os, SVal V);
398 static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000399 void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
Anton Yartsev05789592013-03-28 17:05:19 +0000400 const Expr *DeallocExpr) const;
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000401 void ReportFreeAlloca(CheckerContext &C, SVal ArgVal,
402 SourceRange Range) const;
Anton Yartseve3377fb2013-04-04 23:46:29 +0000403 void ReportMismatchedDealloc(CheckerContext &C, SourceRange Range,
Anton Yartsevf0593d62013-04-05 11:25:10 +0000404 const Expr *DeallocExpr, const RefState *RS,
Anton Yartsevf5bccce2013-09-16 17:51:25 +0000405 SymbolRef Sym, bool OwnershipTransferred) const;
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000406 void ReportOffsetFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
407 const Expr *DeallocExpr,
Craig Topper0dbb7832014-05-27 02:45:47 +0000408 const Expr *AllocExpr = nullptr) const;
Anton Yartsev59ed15b2013-03-13 14:39:10 +0000409 void ReportUseAfterFree(CheckerContext &C, SourceRange Range,
410 SymbolRef Sym) const;
411 void ReportDoubleFree(CheckerContext &C, SourceRange Range, bool Released,
Anton Yartsev6c2af432013-03-13 17:07:32 +0000412 SymbolRef Sym, SymbolRef PrevSym) const;
Anna Zaks2b5bb972012-02-09 06:25:51 +0000413
Jordan Rose656fdd52014-01-08 18:46:55 +0000414 void ReportDoubleDelete(CheckerContext &C, SymbolRef Sym) const;
415
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000416 void ReportUseZeroAllocated(CheckerContext &C, SourceRange Range,
417 SymbolRef Sym) const;
418
Daniel Marjamakia43a8f52017-05-02 11:46:12 +0000419 void ReportFunctionPointerFree(CheckerContext &C, SVal ArgVal,
420 SourceRange Range, const Expr *FreeExpr) const;
421
Anna Zaksdf901a42012-02-23 21:38:21 +0000422 /// Find the location of the allocation for Sym on the path leading to the
423 /// exploded node N.
Anna Zaksfc2e1532012-03-21 19:45:08 +0000424 LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
425 CheckerContext &C) const;
Anna Zaksdf901a42012-02-23 21:38:21 +0000426
Anna Zaksd3571e5a2012-02-11 21:02:40 +0000427 void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const;
428
Anna Zaks2b5bb972012-02-09 06:25:51 +0000429 /// The bug visitor which allows us to print extra diagnostics along the
430 /// BugReport path. For example, showing the allocation site of the leaked
431 /// region.
David Blaikie6951e3e2015-08-13 22:58:37 +0000432 class MallocBugVisitor final
433 : public BugReporterVisitorImpl<MallocBugVisitor> {
Anna Zaks2b5bb972012-02-09 06:25:51 +0000434 protected:
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000435 enum NotificationMode {
436 Normal,
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000437 ReallocationFailed
438 };
439
Anna Zaks2b5bb972012-02-09 06:25:51 +0000440 // The allocated region symbol tracked by the main analysis.
441 SymbolRef Sym;
442
Anna Zaks62cce9e2012-05-10 01:37:40 +0000443 // The mode we are in, i.e. what kind of diagnostics will be emitted.
444 NotificationMode Mode;
Jordy Rose21ff76e2012-03-24 03:15:09 +0000445
Anna Zaks62cce9e2012-05-10 01:37:40 +0000446 // A symbol from when the primary region should have been reallocated.
447 SymbolRef FailedReallocSymbol;
Jordy Rose21ff76e2012-03-24 03:15:09 +0000448
Artem Dergachev5337efc2018-02-27 21:19:33 +0000449 // A C++ destructor stack frame in which memory was released. Used for
450 // miscellaneous false positive suppression.
451 const StackFrameContext *ReleaseDestructorLC;
452
Anna Zaks62cce9e2012-05-10 01:37:40 +0000453 bool IsLeak;
454
455 public:
456 MallocBugVisitor(SymbolRef S, bool isLeak = false)
Artem Dergachev5337efc2018-02-27 21:19:33 +0000457 : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr),
458 ReleaseDestructorLC(nullptr), IsLeak(isLeak) {}
459
460 static void *getTag() {
461 static int Tag = 0;
462 return &Tag;
463 }
Jordy Rose21ff76e2012-03-24 03:15:09 +0000464
Craig Topperfb6b25b2014-03-15 04:29:04 +0000465 void Profile(llvm::FoldingSetNodeID &ID) const override {
Artem Dergachev5337efc2018-02-27 21:19:33 +0000466 ID.AddPointer(getTag());
Anna Zaks2b5bb972012-02-09 06:25:51 +0000467 ID.AddPointer(Sym);
468 }
469
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000470 inline bool isAllocated(const RefState *S, const RefState *SPrev,
471 const Stmt *Stmt) {
Anna Zaks2b5bb972012-02-09 06:25:51 +0000472 // Did not track -> allocated. Other state (released) -> allocated.
Anton Yartsev13df0362013-03-25 01:35:45 +0000473 return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXNewExpr>(Stmt)) &&
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000474 (S && (S->isAllocated() || S->isAllocatedOfSizeZero())) &&
475 (!SPrev || !(SPrev->isAllocated() ||
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000476 SPrev->isAllocatedOfSizeZero())));
Anna Zaks2b5bb972012-02-09 06:25:51 +0000477 }
478
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000479 inline bool isReleased(const RefState *S, const RefState *SPrev,
480 const Stmt *Stmt) {
Anna Zaks2b5bb972012-02-09 06:25:51 +0000481 // Did not track -> released. Other state (allocated) -> released.
Anton Yartsev13df0362013-03-25 01:35:45 +0000482 return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXDeleteExpr>(Stmt)) &&
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000483 (S && S->isReleased()) && (!SPrev || !SPrev->isReleased()));
484 }
485
Anna Zaks0d6989b2012-06-22 02:04:31 +0000486 inline bool isRelinquished(const RefState *S, const RefState *SPrev,
487 const Stmt *Stmt) {
488 // Did not track -> relinquished. Other state (allocated) -> relinquished.
489 return (Stmt && (isa<CallExpr>(Stmt) || isa<ObjCMessageExpr>(Stmt) ||
490 isa<ObjCPropertyRefExpr>(Stmt)) &&
491 (S && S->isRelinquished()) &&
492 (!SPrev || !SPrev->isRelinquished()));
493 }
494
Anna Zaks9eb7bc82012-02-16 22:26:07 +0000495 inline bool isReallocFailedCheck(const RefState *S, const RefState *SPrev,
496 const Stmt *Stmt) {
497 // If the expression is not a call, and the state change is
498 // released -> allocated, it must be the realloc return value
499 // check. If we have to handle more cases here, it might be cleaner just
500 // to track this extra bit in the state itself.
501 return ((!Stmt || !isa<CallExpr>(Stmt)) &&
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000502 (S && (S->isAllocated() || S->isAllocatedOfSizeZero())) &&
503 (SPrev && !(SPrev->isAllocated() ||
504 SPrev->isAllocatedOfSizeZero())));
Anna Zaks2b5bb972012-02-09 06:25:51 +0000505 }
506
David Blaikie0a0c2752017-01-05 17:26:53 +0000507 std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
508 const ExplodedNode *PrevN,
509 BugReporterContext &BRC,
510 BugReport &BR) override;
Anna Zaks62cce9e2012-05-10 01:37:40 +0000511
David Blaikied15481c2014-08-29 18:18:43 +0000512 std::unique_ptr<PathDiagnosticPiece>
513 getEndPath(BugReporterContext &BRC, const ExplodedNode *EndPathNode,
514 BugReport &BR) override {
Anna Zaks62cce9e2012-05-10 01:37:40 +0000515 if (!IsLeak)
Craig Topper0dbb7832014-05-27 02:45:47 +0000516 return nullptr;
Anna Zaks62cce9e2012-05-10 01:37:40 +0000517
518 PathDiagnosticLocation L =
519 PathDiagnosticLocation::createEndOfPath(EndPathNode,
520 BRC.getSourceManager());
521 // Do not add the statement itself as a range in case of leak.
David Blaikied15481c2014-08-29 18:18:43 +0000522 return llvm::make_unique<PathDiagnosticEventPiece>(L, BR.getDescription(),
523 false);
Anna Zaks62cce9e2012-05-10 01:37:40 +0000524 }
525
Anna Zakscba4f292012-03-16 23:24:20 +0000526 private:
527 class StackHintGeneratorForReallocationFailed
528 : public StackHintGeneratorForSymbol {
529 public:
530 StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M)
531 : StackHintGeneratorForSymbol(S, M) {}
532
Craig Topperfb6b25b2014-03-15 04:29:04 +0000533 std::string getMessageForArg(const Expr *ArgE,
534 unsigned ArgIndex) override {
Jordan Rosec102b352012-09-22 01:24:42 +0000535 // Printed parameters start at 1, not 0.
536 ++ArgIndex;
537
Anna Zakscba4f292012-03-16 23:24:20 +0000538 SmallString<200> buf;
539 llvm::raw_svector_ostream os(buf);
540
Jordan Rosec102b352012-09-22 01:24:42 +0000541 os << "Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex)
542 << " parameter failed";
Anna Zakscba4f292012-03-16 23:24:20 +0000543
544 return os.str();
545 }
546
Craig Topperfb6b25b2014-03-15 04:29:04 +0000547 std::string getMessageForReturn(const CallExpr *CallExpr) override {
Anna Zaksa7f457a2012-03-16 23:44:28 +0000548 return "Reallocation of returned value failed";
Anna Zakscba4f292012-03-16 23:24:20 +0000549 }
550 };
Anna Zaks2b5bb972012-02-09 06:25:51 +0000551 };
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000552};
Kovarththanan Rajaratnam65c65662009-11-28 06:07:30 +0000553} // end anonymous namespace
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000554
Jordan Rose0c153cb2012-11-02 01:54:06 +0000555REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState)
556REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair)
Devin Coughlin81771732015-09-22 22:47:14 +0000557REGISTER_SET_WITH_PROGRAMSTATE(ReallocSizeZeroSymbols, SymbolRef)
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000558
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000559// A map from the freed symbol to the symbol representing the return value of
Anna Zaks67291b92012-11-13 03:18:01 +0000560// the free function.
561REGISTER_MAP_WITH_PROGRAMSTATE(FreeReturnValue, SymbolRef, SymbolRef)
562
Anna Zaksbb1ef902012-02-11 21:02:35 +0000563namespace {
David Blaikie903c2932015-08-13 22:50:09 +0000564class StopTrackingCallback final : public SymbolVisitor {
Anna Zaksbb1ef902012-02-11 21:02:35 +0000565 ProgramStateRef state;
566public:
Benjamin Kramercfeacf52016-05-27 14:27:13 +0000567 StopTrackingCallback(ProgramStateRef st) : state(std::move(st)) {}
Anna Zaksbb1ef902012-02-11 21:02:35 +0000568 ProgramStateRef getState() const { return state; }
569
Craig Topperfb6b25b2014-03-15 04:29:04 +0000570 bool VisitSymbol(SymbolRef sym) override {
Anna Zaksbb1ef902012-02-11 21:02:35 +0000571 state = state->remove<RegionState>(sym);
572 return true;
573 }
574};
575} // end anonymous namespace
576
Anna Zaks3d348342012-02-14 21:55:24 +0000577void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const {
Anna Zaksb3436602012-05-18 22:47:40 +0000578 if (II_malloc)
579 return;
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000580 II_alloca = &Ctx.Idents.get("alloca");
Anna Zaksb3436602012-05-18 22:47:40 +0000581 II_malloc = &Ctx.Idents.get("malloc");
582 II_free = &Ctx.Idents.get("free");
583 II_realloc = &Ctx.Idents.get("realloc");
584 II_reallocf = &Ctx.Idents.get("reallocf");
585 II_calloc = &Ctx.Idents.get("calloc");
586 II_valloc = &Ctx.Idents.get("valloc");
587 II_strdup = &Ctx.Idents.get("strdup");
588 II_strndup = &Ctx.Idents.get("strndup");
Anna Zaks30d46682016-03-08 01:21:51 +0000589 II_wcsdup = &Ctx.Idents.get("wcsdup");
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000590 II_kmalloc = &Ctx.Idents.get("kmalloc");
Anna Zaksd79b8402014-10-03 21:48:59 +0000591 II_if_nameindex = &Ctx.Idents.get("if_nameindex");
592 II_if_freenameindex = &Ctx.Idents.get("if_freenameindex");
Anna Zaks30d46682016-03-08 01:21:51 +0000593
594 //MSVC uses `_`-prefixed instead, so we check for them too.
595 II_win_strdup = &Ctx.Idents.get("_strdup");
596 II_win_wcsdup = &Ctx.Idents.get("_wcsdup");
597 II_win_alloca = &Ctx.Idents.get("_alloca");
Anna Zaksbbec97c2017-03-09 00:01:01 +0000598
599 // Glib
600 II_g_malloc = &Ctx.Idents.get("g_malloc");
601 II_g_malloc0 = &Ctx.Idents.get("g_malloc0");
602 II_g_realloc = &Ctx.Idents.get("g_realloc");
603 II_g_try_malloc = &Ctx.Idents.get("g_try_malloc");
604 II_g_try_malloc0 = &Ctx.Idents.get("g_try_malloc0");
605 II_g_try_realloc = &Ctx.Idents.get("g_try_realloc");
606 II_g_free = &Ctx.Idents.get("g_free");
607 II_g_memdup = &Ctx.Idents.get("g_memdup");
Leslie Zhaie3986c52017-04-26 05:33:14 +0000608 II_g_malloc_n = &Ctx.Idents.get("g_malloc_n");
609 II_g_malloc0_n = &Ctx.Idents.get("g_malloc0_n");
610 II_g_realloc_n = &Ctx.Idents.get("g_realloc_n");
611 II_g_try_malloc_n = &Ctx.Idents.get("g_try_malloc_n");
612 II_g_try_malloc0_n = &Ctx.Idents.get("g_try_malloc0_n");
613 II_g_try_realloc_n = &Ctx.Idents.get("g_try_realloc_n");
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000614}
615
Anna Zaks3d348342012-02-14 21:55:24 +0000616bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const {
Anna Zaksd79b8402014-10-03 21:48:59 +0000617 if (isCMemFunction(FD, C, AF_Malloc, MemoryOperationKind::MOK_Any))
Anna Zaks46d01602012-05-18 01:16:10 +0000618 return true;
619
Anna Zaksd79b8402014-10-03 21:48:59 +0000620 if (isCMemFunction(FD, C, AF_IfNameIndex, MemoryOperationKind::MOK_Any))
Anna Zaks46d01602012-05-18 01:16:10 +0000621 return true;
622
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000623 if (isCMemFunction(FD, C, AF_Alloca, MemoryOperationKind::MOK_Any))
624 return true;
625
Anton Yartsev13df0362013-03-25 01:35:45 +0000626 if (isStandardNewDelete(FD, C))
627 return true;
628
Anna Zaks46d01602012-05-18 01:16:10 +0000629 return false;
630}
631
Anna Zaksd79b8402014-10-03 21:48:59 +0000632bool MallocChecker::isCMemFunction(const FunctionDecl *FD,
633 ASTContext &C,
634 AllocationFamily Family,
Benjamin Kramer719772c2014-10-03 22:20:30 +0000635 MemoryOperationKind MemKind) const {
Anna Zaksd1ff1cb2012-02-15 02:12:00 +0000636 if (!FD)
637 return false;
Anna Zaks46d01602012-05-18 01:16:10 +0000638
Anna Zaksd79b8402014-10-03 21:48:59 +0000639 bool CheckFree = (MemKind == MemoryOperationKind::MOK_Any ||
640 MemKind == MemoryOperationKind::MOK_Free);
641 bool CheckAlloc = (MemKind == MemoryOperationKind::MOK_Any ||
642 MemKind == MemoryOperationKind::MOK_Allocate);
643
Jordan Rose6cd16c52012-07-10 23:13:01 +0000644 if (FD->getKind() == Decl::Function) {
Anna Zaksd79b8402014-10-03 21:48:59 +0000645 const IdentifierInfo *FunI = FD->getIdentifier();
Jordan Rose6cd16c52012-07-10 23:13:01 +0000646 initIdentifierInfo(C);
Anna Zaks3d348342012-02-14 21:55:24 +0000647
Anna Zaksd79b8402014-10-03 21:48:59 +0000648 if (Family == AF_Malloc && CheckFree) {
Anna Zaksbbec97c2017-03-09 00:01:01 +0000649 if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf ||
650 FunI == II_g_free)
Anna Zaksd79b8402014-10-03 21:48:59 +0000651 return true;
652 }
653
654 if (Family == AF_Malloc && CheckAlloc) {
655 if (FunI == II_malloc || FunI == II_realloc || FunI == II_reallocf ||
656 FunI == II_calloc || FunI == II_valloc || FunI == II_strdup ||
Anna Zaks30d46682016-03-08 01:21:51 +0000657 FunI == II_win_strdup || FunI == II_strndup || FunI == II_wcsdup ||
Anna Zaksbbec97c2017-03-09 00:01:01 +0000658 FunI == II_win_wcsdup || FunI == II_kmalloc ||
659 FunI == II_g_malloc || FunI == II_g_malloc0 ||
660 FunI == II_g_realloc || FunI == II_g_try_malloc ||
661 FunI == II_g_try_malloc0 || FunI == II_g_try_realloc ||
Leslie Zhaie3986c52017-04-26 05:33:14 +0000662 FunI == II_g_memdup || FunI == II_g_malloc_n ||
663 FunI == II_g_malloc0_n || FunI == II_g_realloc_n ||
664 FunI == II_g_try_malloc_n || FunI == II_g_try_malloc0_n ||
665 FunI == II_g_try_realloc_n)
Anna Zaksd79b8402014-10-03 21:48:59 +0000666 return true;
667 }
668
669 if (Family == AF_IfNameIndex && CheckFree) {
670 if (FunI == II_if_freenameindex)
671 return true;
672 }
673
674 if (Family == AF_IfNameIndex && CheckAlloc) {
675 if (FunI == II_if_nameindex)
676 return true;
677 }
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000678
679 if (Family == AF_Alloca && CheckAlloc) {
Anna Zaks30d46682016-03-08 01:21:51 +0000680 if (FunI == II_alloca || FunI == II_win_alloca)
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000681 return true;
682 }
Jordan Rose6cd16c52012-07-10 23:13:01 +0000683 }
Anna Zaks3d348342012-02-14 21:55:24 +0000684
Anna Zaksd79b8402014-10-03 21:48:59 +0000685 if (Family != AF_Malloc)
Anna Zaks46d01602012-05-18 01:16:10 +0000686 return false;
687
Gabor Horvathe40c71c2015-03-04 17:59:34 +0000688 if (IsOptimistic && FD->hasAttrs()) {
Anna Zaksd79b8402014-10-03 21:48:59 +0000689 for (const auto *I : FD->specific_attrs<OwnershipAttr>()) {
690 OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind();
691 if(OwnKind == OwnershipAttr::Takes || OwnKind == OwnershipAttr::Holds) {
692 if (CheckFree)
693 return true;
694 } else if (OwnKind == OwnershipAttr::Returns) {
695 if (CheckAlloc)
696 return true;
697 }
698 }
Jordan Rose6cd16c52012-07-10 23:13:01 +0000699 }
Anna Zaks3d348342012-02-14 21:55:24 +0000700
Anna Zaks3d348342012-02-14 21:55:24 +0000701 return false;
702}
703
Anton Yartsev8b662702013-03-28 16:10:38 +0000704// Tells if the callee is one of the following:
705// 1) A global non-placement new/delete operator function.
706// 2) A global placement operator function with the single placement argument
707// of type std::nothrow_t.
Anton Yartsev13df0362013-03-25 01:35:45 +0000708bool MallocChecker::isStandardNewDelete(const FunctionDecl *FD,
709 ASTContext &C) const {
710 if (!FD)
711 return false;
712
713 OverloadedOperatorKind Kind = FD->getOverloadedOperator();
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000714 if (Kind != OO_New && Kind != OO_Array_New &&
Anton Yartsev13df0362013-03-25 01:35:45 +0000715 Kind != OO_Delete && Kind != OO_Array_Delete)
716 return false;
717
Anton Yartsev8b662702013-03-28 16:10:38 +0000718 // Skip all operator new/delete methods.
719 if (isa<CXXMethodDecl>(FD))
Anton Yartsev13df0362013-03-25 01:35:45 +0000720 return false;
721
722 // Return true if tested operator is a standard placement nothrow operator.
723 if (FD->getNumParams() == 2) {
724 QualType T = FD->getParamDecl(1)->getType();
725 if (const IdentifierInfo *II = T.getBaseTypeIdentifier())
726 return II->getName().equals("nothrow_t");
727 }
728
729 // Skip placement operators.
730 if (FD->getNumParams() != 1 || FD->isVariadic())
731 return false;
732
733 // One of the standard new/new[]/delete/delete[] non-placement operators.
734 return true;
735}
736
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000737llvm::Optional<ProgramStateRef> MallocChecker::performKernelMalloc(
738 const CallExpr *CE, CheckerContext &C, const ProgramStateRef &State) const {
739 // 3-argument malloc(), as commonly used in {Free,Net,Open}BSD Kernels:
740 //
741 // void *malloc(unsigned long size, struct malloc_type *mtp, int flags);
742 //
743 // One of the possible flags is M_ZERO, which means 'give me back an
744 // allocation which is already zeroed', like calloc.
745
746 // 2-argument kmalloc(), as used in the Linux kernel:
747 //
748 // void *kmalloc(size_t size, gfp_t flags);
749 //
750 // Has the similar flag value __GFP_ZERO.
751
752 // This logic is largely cloned from O_CREAT in UnixAPIChecker, maybe some
753 // code could be shared.
754
755 ASTContext &Ctx = C.getASTContext();
756 llvm::Triple::OSType OS = Ctx.getTargetInfo().getTriple().getOS();
757
758 if (!KernelZeroFlagVal.hasValue()) {
759 if (OS == llvm::Triple::FreeBSD)
760 KernelZeroFlagVal = 0x0100;
761 else if (OS == llvm::Triple::NetBSD)
762 KernelZeroFlagVal = 0x0002;
763 else if (OS == llvm::Triple::OpenBSD)
764 KernelZeroFlagVal = 0x0008;
765 else if (OS == llvm::Triple::Linux)
766 // __GFP_ZERO
767 KernelZeroFlagVal = 0x8000;
768 else
769 // FIXME: We need a more general way of getting the M_ZERO value.
770 // See also: O_CREAT in UnixAPIChecker.cpp.
771
772 // Fall back to normal malloc behavior on platforms where we don't
773 // know M_ZERO.
774 return None;
775 }
776
777 // We treat the last argument as the flags argument, and callers fall-back to
778 // normal malloc on a None return. This works for the FreeBSD kernel malloc
779 // as well as Linux kmalloc.
780 if (CE->getNumArgs() < 2)
781 return None;
782
783 const Expr *FlagsEx = CE->getArg(CE->getNumArgs() - 1);
George Karpenkovd703ec92018-01-17 20:27:29 +0000784 const SVal V = C.getSVal(FlagsEx);
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000785 if (!V.getAs<NonLoc>()) {
786 // The case where 'V' can be a location can only be due to a bad header,
787 // so in this case bail out.
788 return None;
789 }
790
791 NonLoc Flags = V.castAs<NonLoc>();
792 NonLoc ZeroFlag = C.getSValBuilder()
793 .makeIntVal(KernelZeroFlagVal.getValue(), FlagsEx->getType())
794 .castAs<NonLoc>();
795 SVal MaskedFlagsUC = C.getSValBuilder().evalBinOpNN(State, BO_And,
796 Flags, ZeroFlag,
797 FlagsEx->getType());
798 if (MaskedFlagsUC.isUnknownOrUndef())
799 return None;
800 DefinedSVal MaskedFlags = MaskedFlagsUC.castAs<DefinedSVal>();
801
802 // Check if maskedFlags is non-zero.
803 ProgramStateRef TrueState, FalseState;
804 std::tie(TrueState, FalseState) = State->assume(MaskedFlags);
805
806 // If M_ZERO is set, treat this like calloc (initialized).
807 if (TrueState && !FalseState) {
808 SVal ZeroVal = C.getSValBuilder().makeZeroVal(Ctx.CharTy);
809 return MallocMemAux(C, CE, CE->getArg(0), ZeroVal, TrueState);
810 }
811
812 return None;
813}
814
Leslie Zhaie3986c52017-04-26 05:33:14 +0000815SVal MallocChecker::evalMulForBufferSize(CheckerContext &C, const Expr *Blocks,
816 const Expr *BlockBytes) {
817 SValBuilder &SB = C.getSValBuilder();
818 SVal BlocksVal = C.getSVal(Blocks);
819 SVal BlockBytesVal = C.getSVal(BlockBytes);
820 ProgramStateRef State = C.getState();
821 SVal TotalSize = SB.evalBinOp(State, BO_Mul, BlocksVal, BlockBytesVal,
822 SB.getContext().getSizeType());
823 return TotalSize;
824}
825
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000826void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
Jordan Rosed6e5fd52012-09-20 01:55:32 +0000827 if (C.wasInlined)
828 return;
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000829
Anna Zaksc68bf4c2012-02-08 20:13:28 +0000830 const FunctionDecl *FD = C.getCalleeDecl(CE);
831 if (!FD)
832 return;
Zhongxing Xu88cca6b2009-11-12 08:38:56 +0000833
Anna Zaks40a7eb32012-02-22 19:24:52 +0000834 ProgramStateRef State = C.getState();
Anna Zaksfe6eb672012-08-24 02:28:20 +0000835 bool ReleasedAllocatedMemory = false;
Jordan Rose6cd16c52012-07-10 23:13:01 +0000836
837 if (FD->getKind() == Decl::Function) {
838 initIdentifierInfo(C.getASTContext());
839 IdentifierInfo *FunI = FD->getIdentifier();
840
Anna Zaksbbec97c2017-03-09 00:01:01 +0000841 if (FunI == II_malloc || FunI == II_g_malloc || FunI == II_g_try_malloc) {
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000842 if (CE->getNumArgs() < 1)
843 return;
844 if (CE->getNumArgs() < 3) {
845 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000846 if (CE->getNumArgs() == 1)
847 State = ProcessZeroAllocation(C, CE, 0, State);
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000848 } else if (CE->getNumArgs() == 3) {
849 llvm::Optional<ProgramStateRef> MaybeState =
850 performKernelMalloc(CE, C, State);
851 if (MaybeState.hasValue())
852 State = MaybeState.getValue();
853 else
854 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
855 }
856 } else if (FunI == II_kmalloc) {
Devin Coughlin684d19d2016-10-16 22:19:03 +0000857 if (CE->getNumArgs() < 1)
858 return;
Jordan Rose6b33c6f2014-03-26 17:05:46 +0000859 llvm::Optional<ProgramStateRef> MaybeState =
860 performKernelMalloc(CE, C, State);
861 if (MaybeState.hasValue())
862 State = MaybeState.getValue();
863 else
864 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
865 } else if (FunI == II_valloc) {
Anton Yartseve3377fb2013-04-04 23:46:29 +0000866 if (CE->getNumArgs() < 1)
867 return;
868 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000869 State = ProcessZeroAllocation(C, CE, 0, State);
Anna Zaksbbec97c2017-03-09 00:01:01 +0000870 } else if (FunI == II_realloc || FunI == II_g_realloc ||
871 FunI == II_g_try_realloc) {
Leslie Zhaie3986c52017-04-26 05:33:14 +0000872 State = ReallocMemAux(C, CE, false, State);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000873 State = ProcessZeroAllocation(C, CE, 1, State);
Anton Yartseve3377fb2013-04-04 23:46:29 +0000874 } else if (FunI == II_reallocf) {
Leslie Zhaie3986c52017-04-26 05:33:14 +0000875 State = ReallocMemAux(C, CE, true, State);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000876 State = ProcessZeroAllocation(C, CE, 1, State);
Anton Yartseve3377fb2013-04-04 23:46:29 +0000877 } else if (FunI == II_calloc) {
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000878 State = CallocMem(C, CE, State);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000879 State = ProcessZeroAllocation(C, CE, 0, State);
880 State = ProcessZeroAllocation(C, CE, 1, State);
Anna Zaksbbec97c2017-03-09 00:01:01 +0000881 } else if (FunI == II_free || FunI == II_g_free) {
Anton Yartseve3377fb2013-04-04 23:46:29 +0000882 State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
Anna Zaks30d46682016-03-08 01:21:51 +0000883 } else if (FunI == II_strdup || FunI == II_win_strdup ||
884 FunI == II_wcsdup || FunI == II_win_wcsdup) {
Anton Yartseve3377fb2013-04-04 23:46:29 +0000885 State = MallocUpdateRefState(C, CE, State);
886 } else if (FunI == II_strndup) {
887 State = MallocUpdateRefState(C, CE, State);
Anna Zaks30d46682016-03-08 01:21:51 +0000888 } else if (FunI == II_alloca || FunI == II_win_alloca) {
Devin Coughlin684d19d2016-10-16 22:19:03 +0000889 if (CE->getNumArgs() < 1)
890 return;
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000891 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
892 AF_Alloca);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000893 State = ProcessZeroAllocation(C, CE, 0, State);
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +0000894 } else if (isStandardNewDelete(FD, C.getASTContext())) {
Anton Yartseve3377fb2013-04-04 23:46:29 +0000895 // Process direct calls to operator new/new[]/delete/delete[] functions
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000896 // as distinct from new/new[]/delete/delete[] expressions that are
897 // processed by the checkPostStmt callbacks for CXXNewExpr and
Anton Yartseve3377fb2013-04-04 23:46:29 +0000898 // CXXDeleteExpr.
899 OverloadedOperatorKind K = FD->getOverloadedOperator();
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000900 if (K == OO_New) {
Anton Yartseve3377fb2013-04-04 23:46:29 +0000901 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
902 AF_CXXNew);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000903 State = ProcessZeroAllocation(C, CE, 0, State);
904 }
905 else if (K == OO_Array_New) {
Anton Yartseve3377fb2013-04-04 23:46:29 +0000906 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
907 AF_CXXNewArray);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000908 State = ProcessZeroAllocation(C, CE, 0, State);
909 }
Anton Yartseve3377fb2013-04-04 23:46:29 +0000910 else if (K == OO_Delete || K == OO_Array_Delete)
911 State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
912 else
913 llvm_unreachable("not a new/delete operator");
Anna Zaksd79b8402014-10-03 21:48:59 +0000914 } else if (FunI == II_if_nameindex) {
915 // Should we model this differently? We can allocate a fixed number of
916 // elements with zeros in the last one.
917 State = MallocMemAux(C, CE, UnknownVal(), UnknownVal(), State,
918 AF_IfNameIndex);
919 } else if (FunI == II_if_freenameindex) {
920 State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
Anna Zaksbbec97c2017-03-09 00:01:01 +0000921 } else if (FunI == II_g_malloc0 || FunI == II_g_try_malloc0) {
922 if (CE->getNumArgs() < 1)
923 return;
924 SValBuilder &svalBuilder = C.getSValBuilder();
925 SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
926 State = MallocMemAux(C, CE, CE->getArg(0), zeroVal, State);
927 State = ProcessZeroAllocation(C, CE, 0, State);
928 } else if (FunI == II_g_memdup) {
929 if (CE->getNumArgs() < 2)
930 return;
931 State = MallocMemAux(C, CE, CE->getArg(1), UndefinedVal(), State);
932 State = ProcessZeroAllocation(C, CE, 1, State);
Leslie Zhaie3986c52017-04-26 05:33:14 +0000933 } else if (FunI == II_g_malloc_n || FunI == II_g_try_malloc_n ||
934 FunI == II_g_malloc0_n || FunI == II_g_try_malloc0_n) {
935 if (CE->getNumArgs() < 2)
936 return;
937 SVal Init = UndefinedVal();
938 if (FunI == II_g_malloc0_n || FunI == II_g_try_malloc0_n) {
939 SValBuilder &SB = C.getSValBuilder();
940 Init = SB.makeZeroVal(SB.getContext().CharTy);
941 }
942 SVal TotalSize = evalMulForBufferSize(C, CE->getArg(0), CE->getArg(1));
943 State = MallocMemAux(C, CE, TotalSize, Init, State);
944 State = ProcessZeroAllocation(C, CE, 0, State);
945 State = ProcessZeroAllocation(C, CE, 1, State);
946 } else if (FunI == II_g_realloc_n || FunI == II_g_try_realloc_n) {
947 if (CE->getNumArgs() < 3)
948 return;
949 State = ReallocMemAux(C, CE, false, State, true);
950 State = ProcessZeroAllocation(C, CE, 1, State);
951 State = ProcessZeroAllocation(C, CE, 2, State);
Jordan Rose6cd16c52012-07-10 23:13:01 +0000952 }
953 }
954
Gabor Horvathe40c71c2015-03-04 17:59:34 +0000955 if (IsOptimistic || ChecksEnabled[CK_MismatchedDeallocatorChecker]) {
Anna Zaks40a7eb32012-02-22 19:24:52 +0000956 // Check all the attributes, if there are any.
957 // There can be multiple of these attributes.
958 if (FD->hasAttrs())
Aaron Ballmanbe22bcb2014-03-10 17:08:28 +0000959 for (const auto *I : FD->specific_attrs<OwnershipAttr>()) {
960 switch (I->getOwnKind()) {
Anna Zaks40a7eb32012-02-22 19:24:52 +0000961 case OwnershipAttr::Returns:
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000962 State = MallocMemReturnsAttr(C, CE, I, State);
Anna Zaks40a7eb32012-02-22 19:24:52 +0000963 break;
964 case OwnershipAttr::Takes:
965 case OwnershipAttr::Holds:
Anton Yartsevb3fa86d2015-02-10 20:13:08 +0000966 State = FreeMemAttr(C, CE, I, State);
Anna Zaks40a7eb32012-02-22 19:24:52 +0000967 break;
968 }
969 }
Zhongxing Xu527ff6d2010-06-01 03:01:33 +0000970 }
Anna Zaks199e8e52012-02-22 03:14:20 +0000971 C.addTransition(State);
Zhongxing Xuc0484fa2009-12-12 12:29:38 +0000972}
973
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000974// Performs a 0-sized allocations check.
Artem Dergachev13b20262018-01-17 23:46:13 +0000975ProgramStateRef MallocChecker::ProcessZeroAllocation(
976 CheckerContext &C, const Expr *E, const unsigned AllocationSizeArg,
977 ProgramStateRef State, Optional<SVal> RetVal) const {
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000978 if (!State)
979 return nullptr;
980
Artem Dergachev13b20262018-01-17 23:46:13 +0000981 if (!RetVal)
982 RetVal = C.getSVal(E);
983
Anton Yartsevb50f4ba2015-04-14 14:18:04 +0000984 const Expr *Arg = nullptr;
985
986 if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
987 Arg = CE->getArg(AllocationSizeArg);
988 }
989 else if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) {
990 if (NE->isArray())
991 Arg = NE->getArraySize();
992 else
993 return State;
994 }
995 else
996 llvm_unreachable("not a CallExpr or CXXNewExpr");
997
998 assert(Arg);
999
George Karpenkovd703ec92018-01-17 20:27:29 +00001000 Optional<DefinedSVal> DefArgVal = C.getSVal(Arg).getAs<DefinedSVal>();
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00001001
1002 if (!DefArgVal)
1003 return State;
1004
1005 // Check if the allocation size is 0.
1006 ProgramStateRef TrueState, FalseState;
1007 SValBuilder &SvalBuilder = C.getSValBuilder();
1008 DefinedSVal Zero =
1009 SvalBuilder.makeZeroVal(Arg->getType()).castAs<DefinedSVal>();
1010
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001011 std::tie(TrueState, FalseState) =
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00001012 State->assume(SvalBuilder.evalEQ(State, *DefArgVal, Zero));
1013
1014 if (TrueState && !FalseState) {
Artem Dergachev13b20262018-01-17 23:46:13 +00001015 SymbolRef Sym = RetVal->getAsLocSymbol();
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00001016 if (!Sym)
1017 return State;
1018
1019 const RefState *RS = State->get<RegionState>(Sym);
Devin Coughlin81771732015-09-22 22:47:14 +00001020 if (RS) {
1021 if (RS->isAllocated())
1022 return TrueState->set<RegionState>(Sym,
1023 RefState::getAllocatedOfSizeZero(RS));
1024 else
1025 return State;
1026 } else {
1027 // Case of zero-size realloc. Historically 'realloc(ptr, 0)' is treated as
1028 // 'free(ptr)' and the returned value from 'realloc(ptr, 0)' is not
1029 // tracked. Add zero-reallocated Sym to the state to catch references
1030 // to zero-allocated memory.
1031 return TrueState->add<ReallocSizeZeroSymbols>(Sym);
1032 }
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00001033 }
1034
1035 // Assume the value is non-zero going forward.
1036 assert(FalseState);
1037 return FalseState;
1038}
1039
Anton Yartsev4e4cb6b2014-08-05 18:26:05 +00001040static QualType getDeepPointeeType(QualType T) {
1041 QualType Result = T, PointeeType = T->getPointeeType();
1042 while (!PointeeType.isNull()) {
1043 Result = PointeeType;
1044 PointeeType = PointeeType->getPointeeType();
1045 }
1046 return Result;
1047}
1048
1049static bool treatUnusedNewEscaped(const CXXNewExpr *NE) {
1050
1051 const CXXConstructExpr *ConstructE = NE->getConstructExpr();
1052 if (!ConstructE)
1053 return false;
1054
1055 if (!NE->getAllocatedType()->getAsCXXRecordDecl())
1056 return false;
1057
1058 const CXXConstructorDecl *CtorD = ConstructE->getConstructor();
1059
1060 // Iterate over the constructor parameters.
David Majnemer59f77922016-06-24 04:05:48 +00001061 for (const auto *CtorParam : CtorD->parameters()) {
Anton Yartsev4e4cb6b2014-08-05 18:26:05 +00001062
1063 QualType CtorParamPointeeT = CtorParam->getType()->getPointeeType();
1064 if (CtorParamPointeeT.isNull())
1065 continue;
1066
1067 CtorParamPointeeT = getDeepPointeeType(CtorParamPointeeT);
1068
1069 if (CtorParamPointeeT->getAsCXXRecordDecl())
1070 return true;
1071 }
1072
1073 return false;
1074}
1075
Artem Dergachev13b20262018-01-17 23:46:13 +00001076void MallocChecker::processNewAllocation(const CXXNewExpr *NE,
1077 CheckerContext &C,
1078 SVal Target) const {
Anton Yartsev13df0362013-03-25 01:35:45 +00001079 if (NE->getNumPlacementArgs())
1080 for (CXXNewExpr::const_arg_iterator I = NE->placement_arg_begin(),
1081 E = NE->placement_arg_end(); I != E; ++I)
1082 if (SymbolRef Sym = C.getSVal(*I).getAsSymbol())
1083 checkUseAfterFree(Sym, C, *I);
1084
Anton Yartsev13df0362013-03-25 01:35:45 +00001085 if (!isStandardNewDelete(NE->getOperatorNew(), C.getASTContext()))
1086 return;
1087
Anton Yartsev4e4cb6b2014-08-05 18:26:05 +00001088 ParentMap &PM = C.getLocationContext()->getParentMap();
1089 if (!PM.isConsumedExpr(NE) && treatUnusedNewEscaped(NE))
1090 return;
1091
Anton Yartsev13df0362013-03-25 01:35:45 +00001092 ProgramStateRef State = C.getState();
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001093 // The return value from operator new is bound to a specified initialization
1094 // value (if any) and we don't want to loose this value. So we call
1095 // MallocUpdateRefState() instead of MallocMemAux() which breakes the
Anton Yartsev13df0362013-03-25 01:35:45 +00001096 // existing binding.
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001097 State = MallocUpdateRefState(C, NE, State, NE->isArray() ? AF_CXXNewArray
Artem Dergachev13b20262018-01-17 23:46:13 +00001098 : AF_CXXNew, Target);
1099 State = addExtentSize(C, NE, State, Target);
1100 State = ProcessZeroAllocation(C, NE, 0, State, Target);
Anton Yartsev13df0362013-03-25 01:35:45 +00001101 C.addTransition(State);
1102}
1103
Artem Dergachev13b20262018-01-17 23:46:13 +00001104void MallocChecker::checkPostStmt(const CXXNewExpr *NE,
1105 CheckerContext &C) const {
1106 if (!C.getAnalysisManager().getAnalyzerOptions().mayInlineCXXAllocator())
1107 processNewAllocation(NE, C, C.getSVal(NE));
1108}
1109
1110void MallocChecker::checkNewAllocator(const CXXNewExpr *NE, SVal Target,
1111 CheckerContext &C) const {
1112 if (!C.wasInlined)
1113 processNewAllocation(NE, C, Target);
1114}
1115
Gabor Horvath73040272016-09-19 20:39:52 +00001116// Sets the extent value of the MemRegion allocated by
1117// new expression NE to its size in Bytes.
1118//
1119ProgramStateRef MallocChecker::addExtentSize(CheckerContext &C,
1120 const CXXNewExpr *NE,
Artem Dergachev13b20262018-01-17 23:46:13 +00001121 ProgramStateRef State,
1122 SVal Target) {
Gabor Horvath73040272016-09-19 20:39:52 +00001123 if (!State)
1124 return nullptr;
1125 SValBuilder &svalBuilder = C.getSValBuilder();
1126 SVal ElementCount;
Gabor Horvath73040272016-09-19 20:39:52 +00001127 const SubRegion *Region;
1128 if (NE->isArray()) {
1129 const Expr *SizeExpr = NE->getArraySize();
George Karpenkovd703ec92018-01-17 20:27:29 +00001130 ElementCount = C.getSVal(SizeExpr);
Gabor Horvath73040272016-09-19 20:39:52 +00001131 // Store the extent size for the (symbolic)region
1132 // containing the elements.
Artem Dergachev13b20262018-01-17 23:46:13 +00001133 Region = Target.getAsRegion()
Gabor Horvath73040272016-09-19 20:39:52 +00001134 ->getAs<SubRegion>()
Artem Dergachev13b20262018-01-17 23:46:13 +00001135 ->StripCasts()
Gabor Horvath73040272016-09-19 20:39:52 +00001136 ->getAs<SubRegion>();
1137 } else {
1138 ElementCount = svalBuilder.makeIntVal(1, true);
Artem Dergachev13b20262018-01-17 23:46:13 +00001139 Region = Target.getAsRegion()->getAs<SubRegion>();
Gabor Horvath73040272016-09-19 20:39:52 +00001140 }
1141 assert(Region);
1142
1143 // Set the region's extent equal to the Size in Bytes.
1144 QualType ElementType = NE->getAllocatedType();
1145 ASTContext &AstContext = C.getASTContext();
1146 CharUnits TypeSize = AstContext.getTypeSizeInChars(ElementType);
1147
Devin Coughline3b75de2016-12-16 18:41:40 +00001148 if (ElementCount.getAs<NonLoc>()) {
Gabor Horvath73040272016-09-19 20:39:52 +00001149 DefinedOrUnknownSVal Extent = Region->getExtent(svalBuilder);
1150 // size in Bytes = ElementCount*TypeSize
1151 SVal SizeInBytes = svalBuilder.evalBinOpNN(
1152 State, BO_Mul, ElementCount.castAs<NonLoc>(),
1153 svalBuilder.makeArrayIndex(TypeSize.getQuantity()),
1154 svalBuilder.getArrayIndexType());
1155 DefinedOrUnknownSVal extentMatchesSize = svalBuilder.evalEQ(
1156 State, Extent, SizeInBytes.castAs<DefinedOrUnknownSVal>());
1157 State = State->assume(extentMatchesSize, true);
1158 }
1159 return State;
1160}
1161
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001162void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE,
Anton Yartsev13df0362013-03-25 01:35:45 +00001163 CheckerContext &C) const {
1164
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001165 if (!ChecksEnabled[CK_NewDeleteChecker])
Anton Yartsev13df0362013-03-25 01:35:45 +00001166 if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol())
1167 checkUseAfterFree(Sym, C, DE->getArgument());
1168
Anton Yartsev13df0362013-03-25 01:35:45 +00001169 if (!isStandardNewDelete(DE->getOperatorDelete(), C.getASTContext()))
1170 return;
1171
1172 ProgramStateRef State = C.getState();
1173 bool ReleasedAllocated;
1174 State = FreeMemAux(C, DE->getArgument(), DE, State,
1175 /*Hold*/false, ReleasedAllocated);
1176
1177 C.addTransition(State);
1178}
1179
Jordan Rose613f3c02013-03-09 00:59:10 +00001180static bool isKnownDeallocObjCMethodName(const ObjCMethodCall &Call) {
1181 // If the first selector piece is one of the names below, assume that the
1182 // object takes ownership of the memory, promising to eventually deallocate it
1183 // with free().
1184 // Ex: [NSData dataWithBytesNoCopy:bytes length:10];
1185 // (...unless a 'freeWhenDone' parameter is false, but that's checked later.)
1186 StringRef FirstSlot = Call.getSelector().getNameForSlot(0);
Alexander Kornienko9c104902015-12-28 13:06:58 +00001187 return FirstSlot == "dataWithBytesNoCopy" ||
1188 FirstSlot == "initWithBytesNoCopy" ||
1189 FirstSlot == "initWithCharactersNoCopy";
Anna Zaks0d6989b2012-06-22 02:04:31 +00001190}
1191
Jordan Rose613f3c02013-03-09 00:59:10 +00001192static Optional<bool> getFreeWhenDoneArg(const ObjCMethodCall &Call) {
1193 Selector S = Call.getSelector();
1194
1195 // FIXME: We should not rely on fully-constrained symbols being folded.
1196 for (unsigned i = 1; i < S.getNumArgs(); ++i)
1197 if (S.getNameForSlot(i).equals("freeWhenDone"))
1198 return !Call.getArgSVal(i).isZeroConstant();
1199
1200 return None;
1201}
1202
Anna Zaks67291b92012-11-13 03:18:01 +00001203void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call,
1204 CheckerContext &C) const {
Anna Zaksa7b1c472012-12-11 00:17:53 +00001205 if (C.wasInlined)
1206 return;
1207
Jordan Rose613f3c02013-03-09 00:59:10 +00001208 if (!isKnownDeallocObjCMethodName(Call))
1209 return;
Anna Zaks67291b92012-11-13 03:18:01 +00001210
Jordan Rose613f3c02013-03-09 00:59:10 +00001211 if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(Call))
1212 if (!*FreeWhenDone)
1213 return;
1214
1215 bool ReleasedAllocatedMemory;
1216 ProgramStateRef State = FreeMemAux(C, Call.getArgExpr(0),
1217 Call.getOriginExpr(), C.getState(),
1218 /*Hold=*/true, ReleasedAllocatedMemory,
1219 /*RetNullOnFailure=*/true);
1220
1221 C.addTransition(State);
Anna Zaks0d6989b2012-06-22 02:04:31 +00001222}
1223
Richard Smith852e9ce2013-11-27 01:46:48 +00001224ProgramStateRef
1225MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001226 const OwnershipAttr *Att,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001227 ProgramStateRef State) const {
1228 if (!State)
1229 return nullptr;
1230
Richard Smith852e9ce2013-11-27 01:46:48 +00001231 if (Att->getModule() != II_malloc)
Craig Topper0dbb7832014-05-27 02:45:47 +00001232 return nullptr;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001233
Joel E. Dennya6555112018-04-02 19:43:34 +00001234 OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
Ted Kremenekd21139a2010-07-31 01:52:11 +00001235 if (I != E) {
Joel E. Denny81508102018-03-13 14:51:22 +00001236 return MallocMemAux(C, CE, CE->getArg(I->getASTIndex()), UndefinedVal(),
1237 State);
Ted Kremenekd21139a2010-07-31 01:52:11 +00001238 }
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001239 return MallocMemAux(C, CE, UnknownVal(), UndefinedVal(), State);
1240}
1241
1242ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
1243 const CallExpr *CE,
1244 const Expr *SizeEx, SVal Init,
1245 ProgramStateRef State,
1246 AllocationFamily Family) {
1247 if (!State)
1248 return nullptr;
1249
George Karpenkovd703ec92018-01-17 20:27:29 +00001250 return MallocMemAux(C, CE, C.getSVal(SizeEx), Init, State, Family);
Ted Kremenekd21139a2010-07-31 01:52:11 +00001251}
1252
Anna Zaksc68bf4c2012-02-08 20:13:28 +00001253ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00001254 const CallExpr *CE,
Zhongxing Xu527ff6d2010-06-01 03:01:33 +00001255 SVal Size, SVal Init,
Anton Yartsev05789592013-03-28 17:05:19 +00001256 ProgramStateRef State,
1257 AllocationFamily Family) {
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001258 if (!State)
1259 return nullptr;
Anna Zaks3563fde2012-06-07 03:57:32 +00001260
Jordan Rosef69e65f2014-09-05 16:33:51 +00001261 // We expect the malloc functions to return a pointer.
1262 if (!Loc::isLocType(CE->getType()))
1263 return nullptr;
1264
Anna Zaks3563fde2012-06-07 03:57:32 +00001265 // Bind the return value to the symbolic value from the heap region.
1266 // TODO: We could rewrite post visit to eval call; 'malloc' does not have
1267 // side effects other than what we model here.
Ted Kremenekd94854a2012-08-22 06:26:15 +00001268 unsigned Count = C.blockCount();
Anna Zaks3563fde2012-06-07 03:57:32 +00001269 SValBuilder &svalBuilder = C.getSValBuilder();
1270 const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
David Blaikie2fdacbc2013-02-20 05:52:05 +00001271 DefinedSVal RetVal = svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count)
1272 .castAs<DefinedSVal>();
Anton Yartsev05789592013-03-28 17:05:19 +00001273 State = State->BindExpr(CE, C.getLocationContext(), RetVal);
Zhongxing Xu9cb53b82009-12-11 03:09:01 +00001274
Jordy Rose674bd552010-07-04 00:00:41 +00001275 // Fill the region with the initialization value.
Anna Zaksb5701952017-01-13 00:50:57 +00001276 State = State->bindDefault(RetVal, Init, LCtx);
Zhongxing Xu527ff6d2010-06-01 03:01:33 +00001277
Jordy Rose674bd552010-07-04 00:00:41 +00001278 // Set the region's extent equal to the Size parameter.
Anna Zaks31886862012-02-10 01:11:00 +00001279 const SymbolicRegion *R =
Anna Zaks3563fde2012-06-07 03:57:32 +00001280 dyn_cast_or_null<SymbolicRegion>(RetVal.getAsRegion());
Anna Zaks199e8e52012-02-22 03:14:20 +00001281 if (!R)
Craig Topper0dbb7832014-05-27 02:45:47 +00001282 return nullptr;
David Blaikie05785d12013-02-20 22:23:23 +00001283 if (Optional<DefinedOrUnknownSVal> DefinedSize =
David Blaikie2fdacbc2013-02-20 05:52:05 +00001284 Size.getAs<DefinedOrUnknownSVal>()) {
Anna Zaks40a7eb32012-02-22 19:24:52 +00001285 SValBuilder &svalBuilder = C.getSValBuilder();
Anna Zaks199e8e52012-02-22 03:14:20 +00001286 DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
Anna Zaks199e8e52012-02-22 03:14:20 +00001287 DefinedOrUnknownSVal extentMatchesSize =
Anton Yartsev05789592013-03-28 17:05:19 +00001288 svalBuilder.evalEQ(State, Extent, *DefinedSize);
Anna Zaks31886862012-02-10 01:11:00 +00001289
Anton Yartsev05789592013-03-28 17:05:19 +00001290 State = State->assume(extentMatchesSize, true);
1291 assert(State);
Anna Zaks199e8e52012-02-22 03:14:20 +00001292 }
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001293
Anton Yartsev05789592013-03-28 17:05:19 +00001294 return MallocUpdateRefState(C, CE, State, Family);
Anna Zaks40a7eb32012-02-22 19:24:52 +00001295}
1296
1297ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C,
Anton Yartsev13df0362013-03-25 01:35:45 +00001298 const Expr *E,
Anton Yartsev05789592013-03-28 17:05:19 +00001299 ProgramStateRef State,
Artem Dergachev13b20262018-01-17 23:46:13 +00001300 AllocationFamily Family,
1301 Optional<SVal> RetVal) {
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001302 if (!State)
1303 return nullptr;
1304
Anna Zaks40a7eb32012-02-22 19:24:52 +00001305 // Get the return value.
Artem Dergachev13b20262018-01-17 23:46:13 +00001306 if (!RetVal)
1307 RetVal = C.getSVal(E);
Anna Zaks40a7eb32012-02-22 19:24:52 +00001308
1309 // We expect the malloc functions to return a pointer.
Artem Dergachev13b20262018-01-17 23:46:13 +00001310 if (!RetVal->getAs<Loc>())
Craig Topper0dbb7832014-05-27 02:45:47 +00001311 return nullptr;
Anna Zaks40a7eb32012-02-22 19:24:52 +00001312
Artem Dergachev13b20262018-01-17 23:46:13 +00001313 SymbolRef Sym = RetVal->getAsLocSymbol();
1314 // This is a return value of a function that was not inlined, such as malloc()
1315 // or new(). We've checked that in the caller. Therefore, it must be a symbol.
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001316 assert(Sym);
Ted Kremenek90af9092010-12-02 07:49:45 +00001317
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001318 // Set the symbol's state to Allocated.
Anton Yartsev05789592013-03-28 17:05:19 +00001319 return State->set<RegionState>(Sym, RefState::getAllocated(Family, E));
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001320}
1321
Anna Zaks40a7eb32012-02-22 19:24:52 +00001322ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C,
1323 const CallExpr *CE,
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001324 const OwnershipAttr *Att,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001325 ProgramStateRef State) const {
1326 if (!State)
1327 return nullptr;
1328
Richard Smith852e9ce2013-11-27 01:46:48 +00001329 if (Att->getModule() != II_malloc)
Craig Topper0dbb7832014-05-27 02:45:47 +00001330 return nullptr;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001331
Anna Zaksfe6eb672012-08-24 02:28:20 +00001332 bool ReleasedAllocated = false;
Anna Zaks8dc53af2012-03-01 22:06:06 +00001333
Aaron Ballmana82eaa72014-05-02 13:35:42 +00001334 for (const auto &Arg : Att->args()) {
Joel E. Denny81508102018-03-13 14:51:22 +00001335 ProgramStateRef StateI = FreeMemAux(
1336 C, CE, State, Arg.getASTIndex(),
1337 Att->getOwnKind() == OwnershipAttr::Holds, ReleasedAllocated);
Anna Zaks8dc53af2012-03-01 22:06:06 +00001338 if (StateI)
1339 State = StateI;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001340 }
Anna Zaks8dc53af2012-03-01 22:06:06 +00001341 return State;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001342}
1343
Ted Kremenek49b1e382012-01-26 21:29:00 +00001344ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
Anna Zaks31886862012-02-10 01:11:00 +00001345 const CallExpr *CE,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001346 ProgramStateRef State,
Anna Zaks31886862012-02-10 01:11:00 +00001347 unsigned Num,
Anna Zaksfe6eb672012-08-24 02:28:20 +00001348 bool Hold,
Anna Zaks67291b92012-11-13 03:18:01 +00001349 bool &ReleasedAllocated,
1350 bool ReturnsNullOnFailure) const {
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001351 if (!State)
1352 return nullptr;
1353
Anna Zaksb508d292012-04-10 23:41:11 +00001354 if (CE->getNumArgs() < (Num + 1))
Craig Topper0dbb7832014-05-27 02:45:47 +00001355 return nullptr;
Anna Zaksb508d292012-04-10 23:41:11 +00001356
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001357 return FreeMemAux(C, CE->getArg(Num), CE, State, Hold,
Anna Zaks67291b92012-11-13 03:18:01 +00001358 ReleasedAllocated, ReturnsNullOnFailure);
1359}
1360
Anna Zaksa14c1d02012-11-13 19:47:40 +00001361/// Checks if the previous call to free on the given symbol failed - if free
1362/// failed, returns true. Also, returns the corresponding return value symbol.
Benjamin Kramerba4c85e2012-11-22 15:02:44 +00001363static bool didPreviousFreeFail(ProgramStateRef State,
1364 SymbolRef Sym, SymbolRef &RetStatusSymbol) {
Anna Zaksa14c1d02012-11-13 19:47:40 +00001365 const SymbolRef *Ret = State->get<FreeReturnValue>(Sym);
Anna Zaks67291b92012-11-13 03:18:01 +00001366 if (Ret) {
1367 assert(*Ret && "We should not store the null return symbol");
1368 ConstraintManager &CMgr = State->getConstraintManager();
1369 ConditionTruthVal FreeFailed = CMgr.isNull(State, *Ret);
Anna Zaksa14c1d02012-11-13 19:47:40 +00001370 RetStatusSymbol = *Ret;
1371 return FreeFailed.isConstrainedTrue();
Anna Zaks67291b92012-11-13 03:18:01 +00001372 }
Anna Zaksa14c1d02012-11-13 19:47:40 +00001373 return false;
Anna Zaks0d6989b2012-06-22 02:04:31 +00001374}
1375
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001376AllocationFamily MallocChecker::getAllocationFamily(CheckerContext &C,
Anton Yartseve3377fb2013-04-04 23:46:29 +00001377 const Stmt *S) const {
1378 if (!S)
Anton Yartsev05789592013-03-28 17:05:19 +00001379 return AF_None;
1380
Anton Yartseve3377fb2013-04-04 23:46:29 +00001381 if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
Anton Yartsev05789592013-03-28 17:05:19 +00001382 const FunctionDecl *FD = C.getCalleeDecl(CE);
Anton Yartseve3377fb2013-04-04 23:46:29 +00001383
1384 if (!FD)
1385 FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
1386
Anton Yartsev05789592013-03-28 17:05:19 +00001387 ASTContext &Ctx = C.getASTContext();
1388
Anna Zaksd79b8402014-10-03 21:48:59 +00001389 if (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Any))
Anton Yartsev05789592013-03-28 17:05:19 +00001390 return AF_Malloc;
1391
1392 if (isStandardNewDelete(FD, Ctx)) {
1393 OverloadedOperatorKind Kind = FD->getOverloadedOperator();
Anton Yartseve3377fb2013-04-04 23:46:29 +00001394 if (Kind == OO_New || Kind == OO_Delete)
Anton Yartsev05789592013-03-28 17:05:19 +00001395 return AF_CXXNew;
Anton Yartseve3377fb2013-04-04 23:46:29 +00001396 else if (Kind == OO_Array_New || Kind == OO_Array_Delete)
Anton Yartsev05789592013-03-28 17:05:19 +00001397 return AF_CXXNewArray;
1398 }
1399
Anna Zaksd79b8402014-10-03 21:48:59 +00001400 if (isCMemFunction(FD, Ctx, AF_IfNameIndex, MemoryOperationKind::MOK_Any))
1401 return AF_IfNameIndex;
1402
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001403 if (isCMemFunction(FD, Ctx, AF_Alloca, MemoryOperationKind::MOK_Any))
1404 return AF_Alloca;
1405
Anton Yartsev05789592013-03-28 17:05:19 +00001406 return AF_None;
1407 }
1408
Anton Yartseve3377fb2013-04-04 23:46:29 +00001409 if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(S))
1410 return NE->isArray() ? AF_CXXNewArray : AF_CXXNew;
1411
1412 if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(S))
Anton Yartsev05789592013-03-28 17:05:19 +00001413 return DE->isArrayForm() ? AF_CXXNewArray : AF_CXXNew;
1414
Anton Yartseve3377fb2013-04-04 23:46:29 +00001415 if (isa<ObjCMessageExpr>(S))
Anton Yartsev05789592013-03-28 17:05:19 +00001416 return AF_Malloc;
1417
1418 return AF_None;
1419}
1420
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001421bool MallocChecker::printAllocDeallocName(raw_ostream &os, CheckerContext &C,
Anton Yartsev05789592013-03-28 17:05:19 +00001422 const Expr *E) const {
1423 if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
1424 // FIXME: This doesn't handle indirect calls.
1425 const FunctionDecl *FD = CE->getDirectCallee();
1426 if (!FD)
1427 return false;
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001428
Anton Yartsev05789592013-03-28 17:05:19 +00001429 os << *FD;
1430 if (!FD->isOverloadedOperator())
1431 os << "()";
1432 return true;
1433 }
1434
1435 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) {
1436 if (Msg->isInstanceMessage())
1437 os << "-";
1438 else
1439 os << "+";
Aaron Ballmanb190f972014-01-03 17:59:55 +00001440 Msg->getSelector().print(os);
Anton Yartsev05789592013-03-28 17:05:19 +00001441 return true;
1442 }
1443
1444 if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) {
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001445 os << "'"
Anton Yartsev05789592013-03-28 17:05:19 +00001446 << getOperatorSpelling(NE->getOperatorNew()->getOverloadedOperator())
1447 << "'";
1448 return true;
1449 }
1450
1451 if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(E)) {
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001452 os << "'"
Anton Yartsev05789592013-03-28 17:05:19 +00001453 << getOperatorSpelling(DE->getOperatorDelete()->getOverloadedOperator())
1454 << "'";
1455 return true;
1456 }
1457
1458 return false;
1459}
1460
1461void MallocChecker::printExpectedAllocName(raw_ostream &os, CheckerContext &C,
1462 const Expr *E) const {
1463 AllocationFamily Family = getAllocationFamily(C, E);
1464
1465 switch(Family) {
1466 case AF_Malloc: os << "malloc()"; return;
1467 case AF_CXXNew: os << "'new'"; return;
1468 case AF_CXXNewArray: os << "'new[]'"; return;
Anna Zaksd79b8402014-10-03 21:48:59 +00001469 case AF_IfNameIndex: os << "'if_nameindex()'"; return;
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001470 case AF_Alloca:
Anton Yartsev05789592013-03-28 17:05:19 +00001471 case AF_None: llvm_unreachable("not a deallocation expression");
1472 }
1473}
1474
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001475void MallocChecker::printExpectedDeallocName(raw_ostream &os,
Anton Yartsev05789592013-03-28 17:05:19 +00001476 AllocationFamily Family) const {
1477 switch(Family) {
1478 case AF_Malloc: os << "free()"; return;
1479 case AF_CXXNew: os << "'delete'"; return;
1480 case AF_CXXNewArray: os << "'delete[]'"; return;
Anna Zaksd79b8402014-10-03 21:48:59 +00001481 case AF_IfNameIndex: os << "'if_freenameindex()'"; return;
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001482 case AF_Alloca:
1483 case AF_None: llvm_unreachable("suspicious argument");
Anton Yartsev05789592013-03-28 17:05:19 +00001484 }
1485}
1486
Anna Zaks0d6989b2012-06-22 02:04:31 +00001487ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
1488 const Expr *ArgExpr,
1489 const Expr *ParentExpr,
Anna Zaks67291b92012-11-13 03:18:01 +00001490 ProgramStateRef State,
Anna Zaksfe6eb672012-08-24 02:28:20 +00001491 bool Hold,
Anna Zaks67291b92012-11-13 03:18:01 +00001492 bool &ReleasedAllocated,
1493 bool ReturnsNullOnFailure) const {
Anna Zaks0d6989b2012-06-22 02:04:31 +00001494
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00001495 if (!State)
1496 return nullptr;
1497
George Karpenkovd703ec92018-01-17 20:27:29 +00001498 SVal ArgVal = C.getSVal(ArgExpr);
David Blaikie2fdacbc2013-02-20 05:52:05 +00001499 if (!ArgVal.getAs<DefinedOrUnknownSVal>())
Craig Topper0dbb7832014-05-27 02:45:47 +00001500 return nullptr;
David Blaikie2fdacbc2013-02-20 05:52:05 +00001501 DefinedOrUnknownSVal location = ArgVal.castAs<DefinedOrUnknownSVal>();
Ted Kremenekd21139a2010-07-31 01:52:11 +00001502
1503 // Check for null dereferences.
David Blaikie2fdacbc2013-02-20 05:52:05 +00001504 if (!location.getAs<Loc>())
Craig Topper0dbb7832014-05-27 02:45:47 +00001505 return nullptr;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001506
Anna Zaksad01ef52012-02-14 00:26:13 +00001507 // The explicit NULL case, no operation is performed.
Ted Kremenek49b1e382012-01-26 21:29:00 +00001508 ProgramStateRef notNullState, nullState;
Benjamin Kramer867ea1d2014-03-02 13:01:17 +00001509 std::tie(notNullState, nullState) = State->assume(location);
Ted Kremenekd21139a2010-07-31 01:52:11 +00001510 if (nullState && !notNullState)
Craig Topper0dbb7832014-05-27 02:45:47 +00001511 return nullptr;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001512
Jordy Rose3597b212010-06-07 19:32:37 +00001513 // Unknown values could easily be okay
1514 // Undefined values are handled elsewhere
1515 if (ArgVal.isUnknownOrUndef())
Craig Topper0dbb7832014-05-27 02:45:47 +00001516 return nullptr;
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001517
Jordy Rose3597b212010-06-07 19:32:37 +00001518 const MemRegion *R = ArgVal.getAsRegion();
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001519
Jordy Rose3597b212010-06-07 19:32:37 +00001520 // Nonlocs can't be freed, of course.
1521 // Non-region locations (labels and fixed addresses) also shouldn't be freed.
1522 if (!R) {
Anton Yartsev05789592013-03-28 17:05:19 +00001523 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
Craig Topper0dbb7832014-05-27 02:45:47 +00001524 return nullptr;
Jordy Rose3597b212010-06-07 19:32:37 +00001525 }
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001526
Jordy Rose3597b212010-06-07 19:32:37 +00001527 R = R->StripCasts();
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001528
Jordy Rose3597b212010-06-07 19:32:37 +00001529 // Blocks might show up as heap data, but should not be free()d
1530 if (isa<BlockDataRegion>(R)) {
Anton Yartsev05789592013-03-28 17:05:19 +00001531 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
Craig Topper0dbb7832014-05-27 02:45:47 +00001532 return nullptr;
Jordy Rose3597b212010-06-07 19:32:37 +00001533 }
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001534
Jordy Rose3597b212010-06-07 19:32:37 +00001535 const MemSpaceRegion *MS = R->getMemorySpace();
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001536
1537 // Parameters, locals, statics, globals, and memory returned by
Anton Yartsevc38d7952015-03-03 22:58:46 +00001538 // __builtin_alloca() shouldn't be freed.
Jordy Rose3597b212010-06-07 19:32:37 +00001539 if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
1540 // FIXME: at the time this code was written, malloc() regions were
1541 // represented by conjured symbols, which are all in UnknownSpaceRegion.
1542 // This means that there isn't actually anything from HeapSpaceRegion
1543 // that should be freed, even though we allow it here.
1544 // Of course, free() can work on memory allocated outside the current
1545 // function, so UnknownSpaceRegion is always a possibility.
1546 // False negatives are better than false positives.
Anton Yartsevc38d7952015-03-03 22:58:46 +00001547
1548 if (isa<AllocaRegion>(R))
1549 ReportFreeAlloca(C, ArgVal, ArgExpr->getSourceRange());
1550 else
1551 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
1552
Craig Topper0dbb7832014-05-27 02:45:47 +00001553 return nullptr;
Jordy Rose3597b212010-06-07 19:32:37 +00001554 }
Anna Zaksc89ad072013-02-07 23:05:47 +00001555
1556 const SymbolicRegion *SrBase = dyn_cast<SymbolicRegion>(R->getBaseRegion());
Jordy Rose3597b212010-06-07 19:32:37 +00001557 // Various cases could lead to non-symbol values here.
1558 // For now, ignore them.
Anna Zaksc89ad072013-02-07 23:05:47 +00001559 if (!SrBase)
Craig Topper0dbb7832014-05-27 02:45:47 +00001560 return nullptr;
Jordy Rose3597b212010-06-07 19:32:37 +00001561
Anna Zaksc89ad072013-02-07 23:05:47 +00001562 SymbolRef SymBase = SrBase->getSymbol();
1563 const RefState *RsBase = State->get<RegionState>(SymBase);
Craig Topper0dbb7832014-05-27 02:45:47 +00001564 SymbolRef PreviousRetStatusSymbol = nullptr;
Zhongxing Xue2bdb9a2010-01-18 03:27:34 +00001565
Anton Yartseve3377fb2013-04-04 23:46:29 +00001566 if (RsBase) {
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001567
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001568 // Memory returned by alloca() shouldn't be freed.
1569 if (RsBase->getAllocationFamily() == AF_Alloca) {
1570 ReportFreeAlloca(C, ArgVal, ArgExpr->getSourceRange());
1571 return nullptr;
1572 }
1573
Anna Zaks93a21a82013-04-09 00:30:28 +00001574 // Check for double free first.
1575 if ((RsBase->isReleased() || RsBase->isRelinquished()) &&
Anton Yartseve3377fb2013-04-04 23:46:29 +00001576 !didPreviousFreeFail(State, SymBase, PreviousRetStatusSymbol)) {
1577 ReportDoubleFree(C, ParentExpr->getSourceRange(), RsBase->isReleased(),
1578 SymBase, PreviousRetStatusSymbol);
Craig Topper0dbb7832014-05-27 02:45:47 +00001579 return nullptr;
Anton Yartseve3377fb2013-04-04 23:46:29 +00001580
Anna Zaks93a21a82013-04-09 00:30:28 +00001581 // If the pointer is allocated or escaped, but we are now trying to free it,
1582 // check that the call to free is proper.
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001583 } else if (RsBase->isAllocated() || RsBase->isAllocatedOfSizeZero() ||
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00001584 RsBase->isEscaped()) {
Anna Zaks93a21a82013-04-09 00:30:28 +00001585
1586 // Check if an expected deallocation function matches the real one.
1587 bool DeallocMatchesAlloc =
1588 RsBase->getAllocationFamily() == getAllocationFamily(C, ParentExpr);
1589 if (!DeallocMatchesAlloc) {
1590 ReportMismatchedDealloc(C, ArgExpr->getSourceRange(),
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001591 ParentExpr, RsBase, SymBase, Hold);
Craig Topper0dbb7832014-05-27 02:45:47 +00001592 return nullptr;
Anna Zaks93a21a82013-04-09 00:30:28 +00001593 }
1594
1595 // Check if the memory location being freed is the actual location
1596 // allocated, or an offset.
1597 RegionOffset Offset = R->getAsOffset();
1598 if (Offset.isValid() &&
1599 !Offset.hasSymbolicOffset() &&
1600 Offset.getOffset() != 0) {
1601 const Expr *AllocExpr = cast<Expr>(RsBase->getStmt());
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001602 ReportOffsetFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
Anna Zaks93a21a82013-04-09 00:30:28 +00001603 AllocExpr);
Craig Topper0dbb7832014-05-27 02:45:47 +00001604 return nullptr;
Anna Zaks93a21a82013-04-09 00:30:28 +00001605 }
Anton Yartseve3377fb2013-04-04 23:46:29 +00001606 }
Anna Zaksc89ad072013-02-07 23:05:47 +00001607 }
1608
Daniel Marjamakia43a8f52017-05-02 11:46:12 +00001609 if (SymBase->getType()->isFunctionPointerType()) {
1610 ReportFunctionPointerFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
1611 return nullptr;
1612 }
1613
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001614 ReleasedAllocated = (RsBase != nullptr) && (RsBase->isAllocated() ||
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00001615 RsBase->isAllocatedOfSizeZero());
Anna Zaksfe6eb672012-08-24 02:28:20 +00001616
Anna Zaksa14c1d02012-11-13 19:47:40 +00001617 // Clean out the info on previous call to free return info.
Anna Zaksc89ad072013-02-07 23:05:47 +00001618 State = State->remove<FreeReturnValue>(SymBase);
Anna Zaksa14c1d02012-11-13 19:47:40 +00001619
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001620 // Keep track of the return value. If it is NULL, we will know that free
Anna Zaks67291b92012-11-13 03:18:01 +00001621 // failed.
1622 if (ReturnsNullOnFailure) {
1623 SVal RetVal = C.getSVal(ParentExpr);
1624 SymbolRef RetStatusSymbol = RetVal.getAsSymbol();
1625 if (RetStatusSymbol) {
Anna Zaksc89ad072013-02-07 23:05:47 +00001626 C.getSymbolManager().addSymbolDependency(SymBase, RetStatusSymbol);
1627 State = State->set<FreeReturnValue>(SymBase, RetStatusSymbol);
Anna Zaks67291b92012-11-13 03:18:01 +00001628 }
1629 }
1630
Anton Yartsev030bcdd2013-04-05 19:08:04 +00001631 AllocationFamily Family = RsBase ? RsBase->getAllocationFamily()
1632 : getAllocationFamily(C, ParentExpr);
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00001633 // Normal free.
Anton Yartsev05789592013-03-28 17:05:19 +00001634 if (Hold)
Anna Zaksc89ad072013-02-07 23:05:47 +00001635 return State->set<RegionState>(SymBase,
Anton Yartsev05789592013-03-28 17:05:19 +00001636 RefState::getRelinquished(Family,
1637 ParentExpr));
1638
1639 return State->set<RegionState>(SymBase,
1640 RefState::getReleased(Family, ParentExpr));
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00001641}
1642
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001643Optional<MallocChecker::CheckKind>
Anton Yartsev2487dd62015-03-10 22:24:21 +00001644MallocChecker::getCheckIfTracked(AllocationFamily Family,
1645 bool IsALeakCheck) const {
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001646 switch (Family) {
Anna Zaksd79b8402014-10-03 21:48:59 +00001647 case AF_Malloc:
Anton Yartsev4eb394d2015-03-07 00:31:53 +00001648 case AF_Alloca:
1649 case AF_IfNameIndex: {
1650 if (ChecksEnabled[CK_MallocChecker])
1651 return CK_MallocChecker;
1652
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001653 return Optional<MallocChecker::CheckKind>();
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001654 }
1655 case AF_CXXNew:
1656 case AF_CXXNewArray: {
Anton Yartsev2487dd62015-03-10 22:24:21 +00001657 if (IsALeakCheck) {
1658 if (ChecksEnabled[CK_NewDeleteLeaksChecker])
1659 return CK_NewDeleteLeaksChecker;
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001660 }
Anton Yartsev2487dd62015-03-10 22:24:21 +00001661 else {
1662 if (ChecksEnabled[CK_NewDeleteChecker])
1663 return CK_NewDeleteChecker;
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001664 }
1665 return Optional<MallocChecker::CheckKind>();
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001666 }
1667 case AF_None: {
Anton Yartsev030bcdd2013-04-05 19:08:04 +00001668 llvm_unreachable("no family");
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001669 }
Anton Yartsev717aa0e2013-04-05 00:31:02 +00001670 }
Anton Yartsev2f910042013-04-05 02:12:04 +00001671 llvm_unreachable("unhandled family");
Anton Yartseve3377fb2013-04-04 23:46:29 +00001672}
1673
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001674Optional<MallocChecker::CheckKind>
Anton Yartsev4eb394d2015-03-07 00:31:53 +00001675MallocChecker::getCheckIfTracked(CheckerContext &C,
Anton Yartsev2487dd62015-03-10 22:24:21 +00001676 const Stmt *AllocDeallocStmt,
1677 bool IsALeakCheck) const {
1678 return getCheckIfTracked(getAllocationFamily(C, AllocDeallocStmt),
1679 IsALeakCheck);
Anton Yartseve5c0c142015-02-18 00:39:06 +00001680}
1681
1682Optional<MallocChecker::CheckKind>
Anton Yartsev2487dd62015-03-10 22:24:21 +00001683MallocChecker::getCheckIfTracked(CheckerContext &C, SymbolRef Sym,
1684 bool IsALeakCheck) const {
Devin Coughlin81771732015-09-22 22:47:14 +00001685 if (C.getState()->contains<ReallocSizeZeroSymbols>(Sym))
1686 return CK_MallocChecker;
1687
Anton Yartsev030bcdd2013-04-05 19:08:04 +00001688 const RefState *RS = C.getState()->get<RegionState>(Sym);
1689 assert(RS);
Anton Yartsev2487dd62015-03-10 22:24:21 +00001690 return getCheckIfTracked(RS->getAllocationFamily(), IsALeakCheck);
Anton Yartseve3377fb2013-04-04 23:46:29 +00001691}
1692
Ted Kremenek5ef32db2011-08-12 23:37:29 +00001693bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
David Blaikie05785d12013-02-20 22:23:23 +00001694 if (Optional<nonloc::ConcreteInt> IntVal = V.getAs<nonloc::ConcreteInt>())
Jordy Rose3597b212010-06-07 19:32:37 +00001695 os << "an integer (" << IntVal->getValue() << ")";
David Blaikie05785d12013-02-20 22:23:23 +00001696 else if (Optional<loc::ConcreteInt> ConstAddr = V.getAs<loc::ConcreteInt>())
Jordy Rose3597b212010-06-07 19:32:37 +00001697 os << "a constant address (" << ConstAddr->getValue() << ")";
David Blaikie05785d12013-02-20 22:23:23 +00001698 else if (Optional<loc::GotoLabel> Label = V.getAs<loc::GotoLabel>())
Chris Lattner5a9b1ec2011-02-17 05:38:27 +00001699 os << "the address of the label '" << Label->getLabel()->getName() << "'";
Jordy Rose3597b212010-06-07 19:32:37 +00001700 else
1701 return false;
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001702
Jordy Rose3597b212010-06-07 19:32:37 +00001703 return true;
1704}
1705
Ted Kremenek5ef32db2011-08-12 23:37:29 +00001706bool MallocChecker::SummarizeRegion(raw_ostream &os,
Jordy Rose3597b212010-06-07 19:32:37 +00001707 const MemRegion *MR) {
1708 switch (MR->getKind()) {
Artem Dergachev73f018e2016-01-13 13:49:29 +00001709 case MemRegion::FunctionCodeRegionKind: {
1710 const NamedDecl *FD = cast<FunctionCodeRegion>(MR)->getDecl();
Jordy Rose3597b212010-06-07 19:32:37 +00001711 if (FD)
Benjamin Kramerb89514a2011-10-14 18:45:37 +00001712 os << "the address of the function '" << *FD << '\'';
Jordy Rose3597b212010-06-07 19:32:37 +00001713 else
1714 os << "the address of a function";
1715 return true;
1716 }
Artem Dergachev73f018e2016-01-13 13:49:29 +00001717 case MemRegion::BlockCodeRegionKind:
Jordy Rose3597b212010-06-07 19:32:37 +00001718 os << "block text";
1719 return true;
1720 case MemRegion::BlockDataRegionKind:
1721 // FIXME: where the block came from?
1722 os << "a block";
1723 return true;
1724 default: {
1725 const MemSpaceRegion *MS = MR->getMemorySpace();
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001726
Anna Zaks8158ef02012-01-04 23:54:01 +00001727 if (isa<StackLocalsSpaceRegion>(MS)) {
Jordy Rose3597b212010-06-07 19:32:37 +00001728 const VarRegion *VR = dyn_cast<VarRegion>(MR);
1729 const VarDecl *VD;
1730 if (VR)
1731 VD = VR->getDecl();
1732 else
Craig Topper0dbb7832014-05-27 02:45:47 +00001733 VD = nullptr;
1734
Jordy Rose3597b212010-06-07 19:32:37 +00001735 if (VD)
1736 os << "the address of the local variable '" << VD->getName() << "'";
1737 else
1738 os << "the address of a local stack variable";
1739 return true;
1740 }
Anna Zaks8158ef02012-01-04 23:54:01 +00001741
1742 if (isa<StackArgumentsSpaceRegion>(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 parameter '" << VD->getName() << "'";
1752 else
1753 os << "the address of a parameter";
1754 return true;
1755 }
Anna Zaks8158ef02012-01-04 23:54:01 +00001756
1757 if (isa<GlobalsSpaceRegion>(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 if (VD->isStaticLocal())
1767 os << "the address of the static variable '" << VD->getName() << "'";
1768 else
1769 os << "the address of the global variable '" << VD->getName() << "'";
1770 } else
1771 os << "the address of a global variable";
1772 return true;
1773 }
Anna Zaks8158ef02012-01-04 23:54:01 +00001774
1775 return false;
Jordy Rose3597b212010-06-07 19:32:37 +00001776 }
1777 }
1778}
1779
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001780void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
1781 SourceRange Range,
Anton Yartsev05789592013-03-28 17:05:19 +00001782 const Expr *DeallocExpr) const {
1783
Anton Yartsev4eb394d2015-03-07 00:31:53 +00001784 if (!ChecksEnabled[CK_MallocChecker] &&
1785 !ChecksEnabled[CK_NewDeleteChecker])
1786 return;
1787
1788 Optional<MallocChecker::CheckKind> CheckKind =
1789 getCheckIfTracked(C, DeallocExpr);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001790 if (!CheckKind.hasValue())
Anton Yartseve3377fb2013-04-04 23:46:29 +00001791 return;
1792
Devin Coughline39bd402015-09-16 22:03:05 +00001793 if (ExplodedNode *N = C.generateErrorNode()) {
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001794 if (!BT_BadFree[*CheckKind])
Artem Dergachevb6a513d2017-05-03 11:47:13 +00001795 BT_BadFree[*CheckKind].reset(new BugType(
1796 CheckNames[*CheckKind], "Bad free", categories::MemoryError));
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001797
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001798 SmallString<100> buf;
Jordy Rose3597b212010-06-07 19:32:37 +00001799 llvm::raw_svector_ostream os(buf);
Anton Yartsev05789592013-03-28 17:05:19 +00001800
Jordy Rose3597b212010-06-07 19:32:37 +00001801 const MemRegion *MR = ArgVal.getAsRegion();
Anton Yartsev05789592013-03-28 17:05:19 +00001802 while (const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(MR))
1803 MR = ER->getSuperRegion();
1804
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001805 os << "Argument to ";
1806 if (!printAllocDeallocName(os, C, DeallocExpr))
1807 os << "deallocator";
Anton Yartsev05789592013-03-28 17:05:19 +00001808
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001809 os << " is ";
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001810 bool Summarized = MR ? SummarizeRegion(os, MR)
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001811 : SummarizeValue(os, ArgVal);
1812 if (Summarized)
1813 os << ", which is not memory allocated by ";
1814 else
1815 os << "not memory allocated by ";
Anton Yartsev05789592013-03-28 17:05:19 +00001816
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001817 printExpectedAllocName(os, C, DeallocExpr);
Anton Yartsev05789592013-03-28 17:05:19 +00001818
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001819 auto R = llvm::make_unique<BugReport>(*BT_BadFree[*CheckKind], os.str(), N);
Ted Kremenek1e809b42012-03-09 01:13:14 +00001820 R->markInteresting(MR);
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001821 R->addRange(Range);
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001822 C.emitReport(std::move(R));
Jordy Rose3597b212010-06-07 19:32:37 +00001823 }
1824}
1825
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001826void MallocChecker::ReportFreeAlloca(CheckerContext &C, SVal ArgVal,
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001827 SourceRange Range) const {
1828
Anton Yartsev4eb394d2015-03-07 00:31:53 +00001829 Optional<MallocChecker::CheckKind> CheckKind;
1830
1831 if (ChecksEnabled[CK_MallocChecker])
1832 CheckKind = CK_MallocChecker;
1833 else if (ChecksEnabled[CK_MismatchedDeallocatorChecker])
1834 CheckKind = CK_MismatchedDeallocatorChecker;
1835 else
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001836 return;
1837
Devin Coughline39bd402015-09-16 22:03:05 +00001838 if (ExplodedNode *N = C.generateErrorNode()) {
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001839 if (!BT_FreeAlloca[*CheckKind])
Artem Dergachevb6a513d2017-05-03 11:47:13 +00001840 BT_FreeAlloca[*CheckKind].reset(new BugType(
1841 CheckNames[*CheckKind], "Free alloca()", categories::MemoryError));
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001842
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001843 auto R = llvm::make_unique<BugReport>(
1844 *BT_FreeAlloca[*CheckKind],
1845 "Memory allocated by alloca() should not be deallocated", N);
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001846 R->markInteresting(ArgVal.getAsRegion());
1847 R->addRange(Range);
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001848 C.emitReport(std::move(R));
Anton Yartsev5b5c7ce2015-02-19 13:36:20 +00001849 }
1850}
1851
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001852void MallocChecker::ReportMismatchedDealloc(CheckerContext &C,
Anton Yartseve3377fb2013-04-04 23:46:29 +00001853 SourceRange Range,
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001854 const Expr *DeallocExpr,
Anton Yartsevf0593d62013-04-05 11:25:10 +00001855 const RefState *RS,
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001856 SymbolRef Sym,
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001857 bool OwnershipTransferred) const {
Anton Yartsev05789592013-03-28 17:05:19 +00001858
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001859 if (!ChecksEnabled[CK_MismatchedDeallocatorChecker])
Anton Yartsev05789592013-03-28 17:05:19 +00001860 return;
1861
Devin Coughline39bd402015-09-16 22:03:05 +00001862 if (ExplodedNode *N = C.generateErrorNode()) {
Anton Yartseve3377fb2013-04-04 23:46:29 +00001863 if (!BT_MismatchedDealloc)
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001864 BT_MismatchedDealloc.reset(
1865 new BugType(CheckNames[CK_MismatchedDeallocatorChecker],
Artem Dergachevb6a513d2017-05-03 11:47:13 +00001866 "Bad deallocator", categories::MemoryError));
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001867
Anton Yartsev05789592013-03-28 17:05:19 +00001868 SmallString<100> buf;
1869 llvm::raw_svector_ostream os(buf);
1870
1871 const Expr *AllocExpr = cast<Expr>(RS->getStmt());
1872 SmallString<20> AllocBuf;
1873 llvm::raw_svector_ostream AllocOs(AllocBuf);
1874 SmallString<20> DeallocBuf;
1875 llvm::raw_svector_ostream DeallocOs(DeallocBuf);
1876
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001877 if (OwnershipTransferred) {
1878 if (printAllocDeallocName(DeallocOs, C, DeallocExpr))
1879 os << DeallocOs.str() << " cannot";
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001880 else
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001881 os << "Cannot";
Anton Yartsev05789592013-03-28 17:05:19 +00001882
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001883 os << " take ownership of memory";
Anton Yartsev05789592013-03-28 17:05:19 +00001884
Anton Yartsevf5bccce2013-09-16 17:51:25 +00001885 if (printAllocDeallocName(AllocOs, C, AllocExpr))
1886 os << " allocated by " << AllocOs.str();
1887 } else {
1888 os << "Memory";
1889 if (printAllocDeallocName(AllocOs, C, AllocExpr))
1890 os << " allocated by " << AllocOs.str();
1891
1892 os << " should be deallocated by ";
1893 printExpectedDeallocName(os, RS->getAllocationFamily());
1894
1895 if (printAllocDeallocName(DeallocOs, C, DeallocExpr))
1896 os << ", not " << DeallocOs.str();
1897 }
Anton Yartsev05789592013-03-28 17:05:19 +00001898
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001899 auto R = llvm::make_unique<BugReport>(*BT_MismatchedDealloc, os.str(), N);
Anton Yartsevf0593d62013-04-05 11:25:10 +00001900 R->markInteresting(Sym);
Anton Yartsev05789592013-03-28 17:05:19 +00001901 R->addRange(Range);
David Blaikie91e79022014-09-04 23:54:33 +00001902 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001903 C.emitReport(std::move(R));
Anton Yartsev05789592013-03-28 17:05:19 +00001904 }
1905}
1906
Anna Zaksc89ad072013-02-07 23:05:47 +00001907void MallocChecker::ReportOffsetFree(CheckerContext &C, SVal ArgVal,
Anton Yartsev05789592013-03-28 17:05:19 +00001908 SourceRange Range, const Expr *DeallocExpr,
1909 const Expr *AllocExpr) const {
1910
Anton Yartsev05789592013-03-28 17:05:19 +00001911
Anton Yartsev4eb394d2015-03-07 00:31:53 +00001912 if (!ChecksEnabled[CK_MallocChecker] &&
1913 !ChecksEnabled[CK_NewDeleteChecker])
1914 return;
1915
1916 Optional<MallocChecker::CheckKind> CheckKind =
1917 getCheckIfTracked(C, AllocExpr);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001918 if (!CheckKind.hasValue())
Anton Yartseve3377fb2013-04-04 23:46:29 +00001919 return;
1920
Devin Coughline39bd402015-09-16 22:03:05 +00001921 ExplodedNode *N = C.generateErrorNode();
Craig Topper0dbb7832014-05-27 02:45:47 +00001922 if (!N)
Anna Zaksc89ad072013-02-07 23:05:47 +00001923 return;
1924
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001925 if (!BT_OffsetFree[*CheckKind])
Artem Dergachevb6a513d2017-05-03 11:47:13 +00001926 BT_OffsetFree[*CheckKind].reset(new BugType(
1927 CheckNames[*CheckKind], "Offset free", categories::MemoryError));
Anna Zaksc89ad072013-02-07 23:05:47 +00001928
1929 SmallString<100> buf;
1930 llvm::raw_svector_ostream os(buf);
Anton Yartsev05789592013-03-28 17:05:19 +00001931 SmallString<20> AllocNameBuf;
1932 llvm::raw_svector_ostream AllocNameOs(AllocNameBuf);
Anna Zaksc89ad072013-02-07 23:05:47 +00001933
1934 const MemRegion *MR = ArgVal.getAsRegion();
1935 assert(MR && "Only MemRegion based symbols can have offset free errors");
1936
1937 RegionOffset Offset = MR->getAsOffset();
1938 assert((Offset.isValid() &&
1939 !Offset.hasSymbolicOffset() &&
1940 Offset.getOffset() != 0) &&
1941 "Only symbols with a valid offset can have offset free errors");
1942
1943 int offsetBytes = Offset.getOffset() / C.getASTContext().getCharWidth();
1944
Anton Yartsev05789592013-03-28 17:05:19 +00001945 os << "Argument to ";
1946 if (!printAllocDeallocName(os, C, DeallocExpr))
1947 os << "deallocator";
1948 os << " is offset by "
Anna Zaksc89ad072013-02-07 23:05:47 +00001949 << offsetBytes
1950 << " "
1951 << ((abs(offsetBytes) > 1) ? "bytes" : "byte")
Anton Yartsev05789592013-03-28 17:05:19 +00001952 << " from the start of ";
1953 if (AllocExpr && printAllocDeallocName(AllocNameOs, C, AllocExpr))
1954 os << "memory allocated by " << AllocNameOs.str();
1955 else
1956 os << "allocated memory";
Anna Zaksc89ad072013-02-07 23:05:47 +00001957
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001958 auto R = llvm::make_unique<BugReport>(*BT_OffsetFree[*CheckKind], os.str(), N);
Anna Zaksc89ad072013-02-07 23:05:47 +00001959 R->markInteresting(MR->getBaseRegion());
1960 R->addRange(Range);
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001961 C.emitReport(std::move(R));
Anna Zaksc89ad072013-02-07 23:05:47 +00001962}
1963
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001964void MallocChecker::ReportUseAfterFree(CheckerContext &C, SourceRange Range,
1965 SymbolRef Sym) const {
1966
Anton Yartsev4eb394d2015-03-07 00:31:53 +00001967 if (!ChecksEnabled[CK_MallocChecker] &&
1968 !ChecksEnabled[CK_NewDeleteChecker])
1969 return;
1970
1971 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001972 if (!CheckKind.hasValue())
Anton Yartseve3377fb2013-04-04 23:46:29 +00001973 return;
1974
Devin Coughline39bd402015-09-16 22:03:05 +00001975 if (ExplodedNode *N = C.generateErrorNode()) {
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001976 if (!BT_UseFree[*CheckKind])
1977 BT_UseFree[*CheckKind].reset(new BugType(
Artem Dergachevb6a513d2017-05-03 11:47:13 +00001978 CheckNames[*CheckKind], "Use-after-free", categories::MemoryError));
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001979
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001980 auto R = llvm::make_unique<BugReport>(*BT_UseFree[*CheckKind],
1981 "Use of memory after it is freed", N);
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001982
1983 R->markInteresting(Sym);
1984 R->addRange(Range);
David Blaikie91e79022014-09-04 23:54:33 +00001985 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00001986 C.emitReport(std::move(R));
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001987 }
1988}
1989
1990void MallocChecker::ReportDoubleFree(CheckerContext &C, SourceRange Range,
Ted Kremenek3a0678e2015-09-08 03:50:52 +00001991 bool Released, SymbolRef Sym,
Anton Yartsev6c2af432013-03-13 17:07:32 +00001992 SymbolRef PrevSym) const {
Anton Yartsev59ed15b2013-03-13 14:39:10 +00001993
Anton Yartsev4eb394d2015-03-07 00:31:53 +00001994 if (!ChecksEnabled[CK_MallocChecker] &&
1995 !ChecksEnabled[CK_NewDeleteChecker])
1996 return;
1997
1998 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00001999 if (!CheckKind.hasValue())
Anton Yartseve3377fb2013-04-04 23:46:29 +00002000 return;
2001
Devin Coughline39bd402015-09-16 22:03:05 +00002002 if (ExplodedNode *N = C.generateErrorNode()) {
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002003 if (!BT_DoubleFree[*CheckKind])
Artem Dergachevb6a513d2017-05-03 11:47:13 +00002004 BT_DoubleFree[*CheckKind].reset(new BugType(
2005 CheckNames[*CheckKind], "Double free", categories::MemoryError));
Anton Yartsev59ed15b2013-03-13 14:39:10 +00002006
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002007 auto R = llvm::make_unique<BugReport>(
2008 *BT_DoubleFree[*CheckKind],
2009 (Released ? "Attempt to free released memory"
2010 : "Attempt to free non-owned memory"),
2011 N);
Anton Yartsev59ed15b2013-03-13 14:39:10 +00002012 R->addRange(Range);
Anton Yartsev6c2af432013-03-13 17:07:32 +00002013 R->markInteresting(Sym);
2014 if (PrevSym)
2015 R->markInteresting(PrevSym);
David Blaikie91e79022014-09-04 23:54:33 +00002016 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002017 C.emitReport(std::move(R));
Anton Yartsev59ed15b2013-03-13 14:39:10 +00002018 }
2019}
2020
Jordan Rose656fdd52014-01-08 18:46:55 +00002021void MallocChecker::ReportDoubleDelete(CheckerContext &C, SymbolRef Sym) const {
2022
Anton Yartsev4eb394d2015-03-07 00:31:53 +00002023 if (!ChecksEnabled[CK_NewDeleteChecker])
2024 return;
2025
2026 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002027 if (!CheckKind.hasValue())
Jordan Rose656fdd52014-01-08 18:46:55 +00002028 return;
2029
Devin Coughline39bd402015-09-16 22:03:05 +00002030 if (ExplodedNode *N = C.generateErrorNode()) {
Jordan Rose656fdd52014-01-08 18:46:55 +00002031 if (!BT_DoubleDelete)
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002032 BT_DoubleDelete.reset(new BugType(CheckNames[CK_NewDeleteChecker],
Artem Dergachevb6a513d2017-05-03 11:47:13 +00002033 "Double delete",
2034 categories::MemoryError));
Jordan Rose656fdd52014-01-08 18:46:55 +00002035
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002036 auto R = llvm::make_unique<BugReport>(
2037 *BT_DoubleDelete, "Attempt to delete released memory", N);
Jordan Rose656fdd52014-01-08 18:46:55 +00002038
2039 R->markInteresting(Sym);
David Blaikie91e79022014-09-04 23:54:33 +00002040 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002041 C.emitReport(std::move(R));
Jordan Rose656fdd52014-01-08 18:46:55 +00002042 }
2043}
2044
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002045void MallocChecker::ReportUseZeroAllocated(CheckerContext &C,
2046 SourceRange Range,
2047 SymbolRef Sym) const {
2048
2049 if (!ChecksEnabled[CK_MallocChecker] &&
2050 !ChecksEnabled[CK_NewDeleteChecker])
2051 return;
2052
2053 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
2054
2055 if (!CheckKind.hasValue())
2056 return;
2057
Devin Coughline39bd402015-09-16 22:03:05 +00002058 if (ExplodedNode *N = C.generateErrorNode()) {
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002059 if (!BT_UseZerroAllocated[*CheckKind])
Artem Dergachevb6a513d2017-05-03 11:47:13 +00002060 BT_UseZerroAllocated[*CheckKind].reset(
2061 new BugType(CheckNames[*CheckKind], "Use of zero allocated",
2062 categories::MemoryError));
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002063
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002064 auto R = llvm::make_unique<BugReport>(*BT_UseZerroAllocated[*CheckKind],
2065 "Use of zero-allocated memory", N);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002066
2067 R->addRange(Range);
2068 if (Sym) {
2069 R->markInteresting(Sym);
2070 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
2071 }
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002072 C.emitReport(std::move(R));
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002073 }
2074}
2075
Daniel Marjamakia43a8f52017-05-02 11:46:12 +00002076void MallocChecker::ReportFunctionPointerFree(CheckerContext &C, SVal ArgVal,
2077 SourceRange Range,
2078 const Expr *FreeExpr) const {
2079 if (!ChecksEnabled[CK_MallocChecker])
2080 return;
2081
2082 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, FreeExpr);
2083 if (!CheckKind.hasValue())
2084 return;
2085
2086 if (ExplodedNode *N = C.generateErrorNode()) {
2087 if (!BT_BadFree[*CheckKind])
Artem Dergachev9849f592018-02-08 23:28:29 +00002088 BT_BadFree[*CheckKind].reset(new BugType(
2089 CheckNames[*CheckKind], "Bad free", categories::MemoryError));
Daniel Marjamakia43a8f52017-05-02 11:46:12 +00002090
2091 SmallString<100> Buf;
2092 llvm::raw_svector_ostream Os(Buf);
2093
2094 const MemRegion *MR = ArgVal.getAsRegion();
2095 while (const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(MR))
2096 MR = ER->getSuperRegion();
2097
2098 Os << "Argument to ";
2099 if (!printAllocDeallocName(Os, C, FreeExpr))
2100 Os << "deallocator";
2101
2102 Os << " is a function pointer";
2103
2104 auto R = llvm::make_unique<BugReport>(*BT_BadFree[*CheckKind], Os.str(), N);
2105 R->markInteresting(MR);
2106 R->addRange(Range);
2107 C.emitReport(std::move(R));
2108 }
2109}
2110
Leslie Zhaie3986c52017-04-26 05:33:14 +00002111ProgramStateRef MallocChecker::ReallocMemAux(CheckerContext &C,
2112 const CallExpr *CE,
2113 bool FreesOnFail,
Daniel Marjamakia43a8f52017-05-02 11:46:12 +00002114 ProgramStateRef State,
Leslie Zhaie3986c52017-04-26 05:33:14 +00002115 bool SuffixWithN) const {
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00002116 if (!State)
2117 return nullptr;
2118
Leslie Zhaie3986c52017-04-26 05:33:14 +00002119 if (SuffixWithN && CE->getNumArgs() < 3)
2120 return nullptr;
2121 else if (CE->getNumArgs() < 2)
Craig Topper0dbb7832014-05-27 02:45:47 +00002122 return nullptr;
Anna Zaksb508d292012-04-10 23:41:11 +00002123
Ted Kremenek90af9092010-12-02 07:49:45 +00002124 const Expr *arg0Expr = CE->getArg(0);
George Karpenkovd703ec92018-01-17 20:27:29 +00002125 SVal Arg0Val = C.getSVal(arg0Expr);
David Blaikie2fdacbc2013-02-20 05:52:05 +00002126 if (!Arg0Val.getAs<DefinedOrUnknownSVal>())
Craig Topper0dbb7832014-05-27 02:45:47 +00002127 return nullptr;
David Blaikie2fdacbc2013-02-20 05:52:05 +00002128 DefinedOrUnknownSVal arg0Val = Arg0Val.castAs<DefinedOrUnknownSVal>();
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00002129
Ted Kremenek9d0bb1e2010-12-01 21:28:31 +00002130 SValBuilder &svalBuilder = C.getSValBuilder();
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00002131
Ted Kremenek90af9092010-12-02 07:49:45 +00002132 DefinedOrUnknownSVal PtrEQ =
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00002133 svalBuilder.evalEQ(State, arg0Val, svalBuilder.makeNull());
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00002134
Leslie Zhaie3986c52017-04-26 05:33:14 +00002135 // Get the size argument.
Lenny Maiorani005b5c12011-04-27 14:49:29 +00002136 const Expr *Arg1 = CE->getArg(1);
Lenny Maiorani005b5c12011-04-27 14:49:29 +00002137
2138 // Get the value of the size argument.
George Karpenkovd703ec92018-01-17 20:27:29 +00002139 SVal TotalSize = C.getSVal(Arg1);
Leslie Zhaie3986c52017-04-26 05:33:14 +00002140 if (SuffixWithN)
2141 TotalSize = evalMulForBufferSize(C, Arg1, CE->getArg(2));
2142 if (!TotalSize.getAs<DefinedOrUnknownSVal>())
Craig Topper0dbb7832014-05-27 02:45:47 +00002143 return nullptr;
Lenny Maiorani005b5c12011-04-27 14:49:29 +00002144
2145 // Compare the size argument to 0.
2146 DefinedOrUnknownSVal SizeZero =
Leslie Zhaie3986c52017-04-26 05:33:14 +00002147 svalBuilder.evalEQ(State, TotalSize.castAs<DefinedOrUnknownSVal>(),
Lenny Maiorani005b5c12011-04-27 14:49:29 +00002148 svalBuilder.makeIntValWithPtrWidth(0, false));
2149
Anna Zaksd56c8792012-02-13 18:05:39 +00002150 ProgramStateRef StatePtrIsNull, StatePtrNotNull;
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00002151 std::tie(StatePtrIsNull, StatePtrNotNull) = State->assume(PtrEQ);
Anna Zaksd56c8792012-02-13 18:05:39 +00002152 ProgramStateRef StateSizeIsZero, StateSizeNotZero;
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00002153 std::tie(StateSizeIsZero, StateSizeNotZero) = State->assume(SizeZero);
Anna Zaksd56c8792012-02-13 18:05:39 +00002154 // We only assume exceptional states if they are definitely true; if the
2155 // state is under-constrained, assume regular realloc behavior.
2156 bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull;
2157 bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero;
2158
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002159 // If the ptr is NULL and the size is not 0, the call is equivalent to
Lenny Maiorani005b5c12011-04-27 14:49:29 +00002160 // malloc(size).
Leslie Zhaie3986c52017-04-26 05:33:14 +00002161 if (PrtIsNull && !SizeIsZero) {
2162 ProgramStateRef stateMalloc = MallocMemAux(C, CE, TotalSize,
Anna Zaksd56c8792012-02-13 18:05:39 +00002163 UndefinedVal(), StatePtrIsNull);
Anna Zaks40a7eb32012-02-22 19:24:52 +00002164 return stateMalloc;
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00002165 }
2166
Anna Zaksd56c8792012-02-13 18:05:39 +00002167 if (PrtIsNull && SizeIsZero)
Devin Coughlin81771732015-09-22 22:47:14 +00002168 return State;
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00002169
Anna Zaks8fd0f2a2012-02-13 20:57:07 +00002170 // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size).
Anna Zaksd56c8792012-02-13 18:05:39 +00002171 assert(!PrtIsNull);
Anna Zaks8fd0f2a2012-02-13 20:57:07 +00002172 SymbolRef FromPtr = arg0Val.getAsSymbol();
George Karpenkovd703ec92018-01-17 20:27:29 +00002173 SVal RetVal = C.getSVal(CE);
Anna Zaks8fd0f2a2012-02-13 20:57:07 +00002174 SymbolRef ToPtr = RetVal.getAsSymbol();
2175 if (!FromPtr || !ToPtr)
Craig Topper0dbb7832014-05-27 02:45:47 +00002176 return nullptr;
Anna Zaksd56c8792012-02-13 18:05:39 +00002177
Anna Zaksfe6eb672012-08-24 02:28:20 +00002178 bool ReleasedAllocated = false;
2179
Anna Zaksd56c8792012-02-13 18:05:39 +00002180 // If the size is 0, free the memory.
2181 if (SizeIsZero)
Anna Zaksfe6eb672012-08-24 02:28:20 +00002182 if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero, 0,
2183 false, ReleasedAllocated)){
Anna Zaksd56c8792012-02-13 18:05:39 +00002184 // The semantics of the return value are:
2185 // If size was equal to 0, either NULL or a pointer suitable to be passed
Anna Zaks52242a62012-08-03 18:30:18 +00002186 // to free() is returned. We just free the input pointer and do not add
2187 // any constrains on the output pointer.
Anna Zaks40a7eb32012-02-22 19:24:52 +00002188 return stateFree;
Anna Zaksd56c8792012-02-13 18:05:39 +00002189 }
2190
2191 // Default behavior.
Anna Zaksfe6eb672012-08-24 02:28:20 +00002192 if (ProgramStateRef stateFree =
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00002193 FreeMemAux(C, CE, State, 0, false, ReleasedAllocated)) {
Anna Zaksfe6eb672012-08-24 02:28:20 +00002194
Leslie Zhaie3986c52017-04-26 05:33:14 +00002195 ProgramStateRef stateRealloc = MallocMemAux(C, CE, TotalSize,
Anna Zaksd56c8792012-02-13 18:05:39 +00002196 UnknownVal(), stateFree);
Anna Zaks8fd0f2a2012-02-13 20:57:07 +00002197 if (!stateRealloc)
Craig Topper0dbb7832014-05-27 02:45:47 +00002198 return nullptr;
Anna Zaksfe6eb672012-08-24 02:28:20 +00002199
Anna Zaks75cfbb62012-09-12 22:57:34 +00002200 ReallocPairKind Kind = RPToBeFreedAfterFailure;
2201 if (FreesOnFail)
2202 Kind = RPIsFreeOnFailure;
2203 else if (!ReleasedAllocated)
2204 Kind = RPDoNotTrackAfterFailure;
2205
Anna Zaksfe6eb672012-08-24 02:28:20 +00002206 // Record the info about the reallocated symbol so that we could properly
2207 // process failed reallocation.
Anna Zaksac068142012-02-15 00:11:25 +00002208 stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr,
Anna Zaks75cfbb62012-09-12 22:57:34 +00002209 ReallocPair(FromPtr, Kind));
Anna Zaksfe6eb672012-08-24 02:28:20 +00002210 // The reallocated symbol should stay alive for as long as the new symbol.
Anna Zaksad01ef52012-02-14 00:26:13 +00002211 C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
Anna Zaks40a7eb32012-02-22 19:24:52 +00002212 return stateRealloc;
Zhongxing Xuc0484fa2009-12-12 12:29:38 +00002213 }
Craig Topper0dbb7832014-05-27 02:45:47 +00002214 return nullptr;
Zhongxing Xu88cca6b2009-11-12 08:38:56 +00002215}
Zhongxing Xuc4902a52009-11-13 07:25:27 +00002216
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002217ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE,
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00002218 ProgramStateRef State) {
2219 if (!State)
2220 return nullptr;
2221
Anna Zaksb508d292012-04-10 23:41:11 +00002222 if (CE->getNumArgs() < 2)
Craig Topper0dbb7832014-05-27 02:45:47 +00002223 return nullptr;
Anna Zaksb508d292012-04-10 23:41:11 +00002224
Ted Kremenek9d0bb1e2010-12-01 21:28:31 +00002225 SValBuilder &svalBuilder = C.getSValBuilder();
Ted Kremenek90af9092010-12-02 07:49:45 +00002226 SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
Leslie Zhaie3986c52017-04-26 05:33:14 +00002227 SVal TotalSize = evalMulForBufferSize(C, CE->getArg(0), CE->getArg(1));
Zhongxing Xu527ff6d2010-06-01 03:01:33 +00002228
Anton Yartsevb3fa86d2015-02-10 20:13:08 +00002229 return MallocMemAux(C, CE, TotalSize, zeroVal, State);
Zhongxing Xu527ff6d2010-06-01 03:01:33 +00002230}
2231
Anna Zaksfc2e1532012-03-21 19:45:08 +00002232LeakInfo
Anna Zaksdf901a42012-02-23 21:38:21 +00002233MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
2234 CheckerContext &C) const {
Anna Zaks43ffba22012-02-27 23:40:55 +00002235 const LocationContext *LeakContext = N->getLocationContext();
Anna Zaksdf901a42012-02-23 21:38:21 +00002236 // Walk the ExplodedGraph backwards and find the first node that referred to
2237 // the tracked symbol.
2238 const ExplodedNode *AllocNode = N;
Craig Topper0dbb7832014-05-27 02:45:47 +00002239 const MemRegion *ReferenceRegion = nullptr;
Anna Zaksdf901a42012-02-23 21:38:21 +00002240
2241 while (N) {
Anna Zaksfc2e1532012-03-21 19:45:08 +00002242 ProgramStateRef State = N->getState();
2243 if (!State->get<RegionState>(Sym))
Anna Zaksdf901a42012-02-23 21:38:21 +00002244 break;
Anna Zaksfc2e1532012-03-21 19:45:08 +00002245
2246 // Find the most recent expression bound to the symbol in the current
2247 // context.
Anna Zaks7c19abe2013-04-10 21:42:02 +00002248 if (!ReferenceRegion) {
2249 if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) {
2250 SVal Val = State->getSVal(MR);
2251 if (Val.getAsLocSymbol() == Sym) {
Anna Zaks07804ef2013-04-10 22:56:33 +00002252 const VarRegion* VR = MR->getBaseRegion()->getAs<VarRegion>();
Anna Zaks7c19abe2013-04-10 21:42:02 +00002253 // Do not show local variables belonging to a function other than
2254 // where the error is reported.
2255 if (!VR ||
2256 (VR->getStackFrame() == LeakContext->getCurrentStackFrame()))
2257 ReferenceRegion = MR;
2258 }
2259 }
Benjamin Kramerc25c5e02012-03-21 21:03:48 +00002260 }
Anna Zaksfc2e1532012-03-21 19:45:08 +00002261
Anna Zaks486a0ff2015-02-05 01:02:53 +00002262 // Allocation node, is the last node in the current or parent context in
2263 // which the symbol was tracked.
2264 const LocationContext *NContext = N->getLocationContext();
2265 if (NContext == LeakContext ||
2266 NContext->isParentOf(LeakContext))
Anna Zaks43ffba22012-02-27 23:40:55 +00002267 AllocNode = N;
Craig Topper0dbb7832014-05-27 02:45:47 +00002268 N = N->pred_empty() ? nullptr : *(N->pred_begin());
Anna Zaksdf901a42012-02-23 21:38:21 +00002269 }
2270
Anna Zaksa043d0c2013-01-08 00:25:29 +00002271 return LeakInfo(AllocNode, ReferenceRegion);
Anna Zaksdf901a42012-02-23 21:38:21 +00002272}
2273
Anna Zaksd3571e5a2012-02-11 21:02:40 +00002274void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
2275 CheckerContext &C) const {
Anton Yartsev05789592013-03-28 17:05:19 +00002276
Anton Yartsev4eb394d2015-03-07 00:31:53 +00002277 if (!ChecksEnabled[CK_MallocChecker] &&
2278 !ChecksEnabled[CK_NewDeleteLeaksChecker])
Anton Yartsev6e499252013-04-05 02:25:02 +00002279 return;
2280
Anton Yartsev9907fc92015-03-04 23:18:21 +00002281 const RefState *RS = C.getState()->get<RegionState>(Sym);
Anton Yartsev4eb394d2015-03-07 00:31:53 +00002282 assert(RS && "cannot leak an untracked symbol");
2283 AllocationFamily Family = RS->getAllocationFamily();
Anton Yartsev2487dd62015-03-10 22:24:21 +00002284
2285 if (Family == AF_Alloca)
Anton Yartsev4eb394d2015-03-07 00:31:53 +00002286 return;
2287
Anton Yartsev2487dd62015-03-10 22:24:21 +00002288 Optional<MallocChecker::CheckKind>
2289 CheckKind = getCheckIfTracked(Family, true);
Anton Yartsev4eb394d2015-03-07 00:31:53 +00002290
Anton Yartsev2487dd62015-03-10 22:24:21 +00002291 if (!CheckKind.hasValue())
Anton Yartsev9907fc92015-03-04 23:18:21 +00002292 return;
2293
Anna Zaksd3571e5a2012-02-11 21:02:40 +00002294 assert(N);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002295 if (!BT_Leak[*CheckKind]) {
Artem Dergachevb6a513d2017-05-03 11:47:13 +00002296 BT_Leak[*CheckKind].reset(new BugType(CheckNames[*CheckKind], "Memory leak",
2297 categories::MemoryError));
Anna Zaksd3571e5a2012-02-11 21:02:40 +00002298 // Leaks should not be reported if they are post-dominated by a sink:
2299 // (1) Sinks are higher importance bugs.
2300 // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
2301 // with __noreturn functions such as assert() or exit(). We choose not
2302 // to report leaks on such paths.
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002303 BT_Leak[*CheckKind]->setSuppressOnSink(true);
Anna Zaksd3571e5a2012-02-11 21:02:40 +00002304 }
2305
Anna Zaksdf901a42012-02-23 21:38:21 +00002306 // Most bug reports are cached at the location where they occurred.
2307 // With leaks, we want to unique them by the location where they were
2308 // allocated, and only report a single path.
Anna Zaks43ffba22012-02-27 23:40:55 +00002309 PathDiagnosticLocation LocUsedForUniqueing;
Craig Topper0dbb7832014-05-27 02:45:47 +00002310 const ExplodedNode *AllocNode = nullptr;
2311 const MemRegion *Region = nullptr;
Benjamin Kramer867ea1d2014-03-02 13:01:17 +00002312 std::tie(AllocNode, Region) = getAllocationSite(N, Sym, C);
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002313
Gabor Horvath6ee4f902016-08-18 07:54:50 +00002314 const Stmt *AllocationStmt = PathDiagnosticLocation::getStmt(AllocNode);
Anton Yartsev6e499252013-04-05 02:25:02 +00002315 if (AllocationStmt)
Anna Zaksa043d0c2013-01-08 00:25:29 +00002316 LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocationStmt,
2317 C.getSourceManager(),
2318 AllocNode->getLocationContext());
Anna Zaksdf901a42012-02-23 21:38:21 +00002319
Anna Zaksfc2e1532012-03-21 19:45:08 +00002320 SmallString<200> buf;
2321 llvm::raw_svector_ostream os(buf);
Jordan Rosed86b3bd2012-08-08 18:23:36 +00002322 if (Region && Region->canPrintPretty()) {
Anna Zaks6cea7d92013-04-12 18:40:21 +00002323 os << "Potential leak of memory pointed to by ";
Jordan Rosed86b3bd2012-08-08 18:23:36 +00002324 Region->printPretty(os);
Anna Zaksa1de8562013-04-06 00:41:36 +00002325 } else {
2326 os << "Potential memory leak";
Anna Zaksfc2e1532012-03-21 19:45:08 +00002327 }
2328
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002329 auto R = llvm::make_unique<BugReport>(
2330 *BT_Leak[*CheckKind], os.str(), N, LocUsedForUniqueing,
2331 AllocNode->getLocationContext()->getDecl());
Ted Kremenek1e809b42012-03-09 01:13:14 +00002332 R->markInteresting(Sym);
David Blaikie91e79022014-09-04 23:54:33 +00002333 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym, true));
Aaron Ballman8d3a7a52015-06-23 13:15:32 +00002334 C.emitReport(std::move(R));
Anna Zaksd3571e5a2012-02-11 21:02:40 +00002335}
2336
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +00002337void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
2338 CheckerContext &C) const
Ted Kremenek90af9092010-12-02 07:49:45 +00002339{
Zhongxing Xubce831f2010-08-15 08:19:57 +00002340 if (!SymReaper.hasDeadSymbols())
2341 return;
Zhongxing Xuc7460962009-11-13 07:48:11 +00002342
Ted Kremenek49b1e382012-01-26 21:29:00 +00002343 ProgramStateRef state = C.getState();
Zhongxing Xubce831f2010-08-15 08:19:57 +00002344 RegionStateTy RS = state->get<RegionState>();
Jordy Rose82584992010-08-18 04:33:47 +00002345 RegionStateTy::Factory &F = state->get_context<RegionState>();
Zhongxing Xubce831f2010-08-15 08:19:57 +00002346
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002347 SmallVector<SymbolRef, 2> Errors;
Zhongxing Xubce831f2010-08-15 08:19:57 +00002348 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
2349 if (SymReaper.isDead(I->first)) {
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002350 if (I->second.isAllocated() || I->second.isAllocatedOfSizeZero())
Anna Zaks78edc2f2012-02-09 06:48:19 +00002351 Errors.push_back(I->first);
Jordy Rose82584992010-08-18 04:33:47 +00002352 // Remove the dead symbol from the map.
Ted Kremenekb3b56c62010-11-24 00:54:37 +00002353 RS = F.remove(RS, I->first);
Ted Kremeneke227f492011-07-28 23:07:51 +00002354
Zhongxing Xuc7460962009-11-13 07:48:11 +00002355 }
2356 }
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002357
Anna Zaksd56c8792012-02-13 18:05:39 +00002358 // Cleanup the Realloc Pairs Map.
Jordan Rose0c153cb2012-11-02 01:54:06 +00002359 ReallocPairsTy RP = state->get<ReallocPairs>();
2360 for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
Anna Zaksac068142012-02-15 00:11:25 +00002361 if (SymReaper.isDead(I->first) ||
2362 SymReaper.isDead(I->second.ReallocatedSym)) {
Anna Zaksd56c8792012-02-13 18:05:39 +00002363 state = state->remove<ReallocPairs>(I->first);
2364 }
2365 }
2366
Anna Zaks67291b92012-11-13 03:18:01 +00002367 // Cleanup the FreeReturnValue Map.
2368 FreeReturnValueTy FR = state->get<FreeReturnValue>();
2369 for (FreeReturnValueTy::iterator I = FR.begin(), E = FR.end(); I != E; ++I) {
2370 if (SymReaper.isDead(I->first) ||
2371 SymReaper.isDead(I->second)) {
2372 state = state->remove<FreeReturnValue>(I->first);
2373 }
2374 }
2375
Anna Zaksdf901a42012-02-23 21:38:21 +00002376 // Generate leak node.
Anna Zaks58a2c4e2012-10-29 22:51:54 +00002377 ExplodedNode *N = C.getPredecessor();
2378 if (!Errors.empty()) {
Anton Yartsev6a619222014-02-17 18:25:34 +00002379 static CheckerProgramPointTag Tag("MallocChecker", "DeadSymbolsLeak");
Devin Coughline39bd402015-09-16 22:03:05 +00002380 N = C.generateNonFatalErrorNode(C.getState(), &Tag);
2381 if (N) {
2382 for (SmallVectorImpl<SymbolRef>::iterator
Craig Topper2341c0d2013-07-04 03:08:24 +00002383 I = Errors.begin(), E = Errors.end(); I != E; ++I) {
Devin Coughline39bd402015-09-16 22:03:05 +00002384 reportLeak(*I, N, C);
2385 }
Anna Zaks78edc2f2012-02-09 06:48:19 +00002386 }
Ted Kremeneke227f492011-07-28 23:07:51 +00002387 }
Anna Zaks58a2c4e2012-10-29 22:51:54 +00002388
Anna Zaksdf901a42012-02-23 21:38:21 +00002389 C.addTransition(state->set<RegionState>(RS), N);
Zhongxing Xuc4902a52009-11-13 07:25:27 +00002390}
Zhongxing Xu4668c7e2009-11-17 07:54:15 +00002391
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00002392void MallocChecker::checkPreCall(const CallEvent &Call,
2393 CheckerContext &C) const {
2394
Jordan Rose656fdd52014-01-08 18:46:55 +00002395 if (const CXXDestructorCall *DC = dyn_cast<CXXDestructorCall>(&Call)) {
2396 SymbolRef Sym = DC->getCXXThisVal().getAsSymbol();
2397 if (!Sym || checkDoubleDelete(Sym, C))
2398 return;
2399 }
2400
Anna Zaks46d01602012-05-18 01:16:10 +00002401 // We will check for double free in the post visit.
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00002402 if (const AnyFunctionCall *FC = dyn_cast<AnyFunctionCall>(&Call)) {
2403 const FunctionDecl *FD = FC->getDecl();
2404 if (!FD)
2405 return;
Anton Yartsev13df0362013-03-25 01:35:45 +00002406
Anna Zaksd79b8402014-10-03 21:48:59 +00002407 ASTContext &Ctx = C.getASTContext();
Gabor Horvathe40c71c2015-03-04 17:59:34 +00002408 if (ChecksEnabled[CK_MallocChecker] &&
Anna Zaksd79b8402014-10-03 21:48:59 +00002409 (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Free) ||
2410 isCMemFunction(FD, Ctx, AF_IfNameIndex,
2411 MemoryOperationKind::MOK_Free)))
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00002412 return;
Anna Zaks3d348342012-02-14 21:55:24 +00002413
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002414 if (ChecksEnabled[CK_NewDeleteChecker] &&
Anna Zaksd79b8402014-10-03 21:48:59 +00002415 isStandardNewDelete(FD, Ctx))
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00002416 return;
2417 }
2418
2419 // Check if the callee of a method is deleted.
2420 if (const CXXInstanceCall *CC = dyn_cast<CXXInstanceCall>(&Call)) {
2421 SymbolRef Sym = CC->getCXXThisVal().getAsSymbol();
2422 if (!Sym || checkUseAfterFree(Sym, C, CC->getCXXThisExpr()))
2423 return;
2424 }
2425
2426 // Check arguments for being used after free.
2427 for (unsigned I = 0, E = Call.getNumArgs(); I != E; ++I) {
2428 SVal ArgSVal = Call.getArgSVal(I);
2429 if (ArgSVal.getAs<Loc>()) {
2430 SymbolRef Sym = ArgSVal.getAsSymbol();
Anna Zaks3d348342012-02-14 21:55:24 +00002431 if (!Sym)
2432 continue;
Anton Yartsevcb2ccd62013-04-10 22:21:41 +00002433 if (checkUseAfterFree(Sym, C, Call.getArgExpr(I)))
Anna Zaks3d348342012-02-14 21:55:24 +00002434 return;
2435 }
2436 }
2437}
2438
Anna Zaksa1b227b2012-02-08 23:16:56 +00002439void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
2440 const Expr *E = S->getRetValue();
2441 if (!E)
2442 return;
Anna Zaks3aa52252012-02-11 21:44:39 +00002443
2444 // Check if we are returning a symbol.
Jordan Rose356279c2012-08-08 18:23:31 +00002445 ProgramStateRef State = C.getState();
George Karpenkovd703ec92018-01-17 20:27:29 +00002446 SVal RetVal = C.getSVal(E);
Anna Zaks4ca45b12012-02-22 02:36:01 +00002447 SymbolRef Sym = RetVal.getAsSymbol();
2448 if (!Sym)
2449 // If we are returning a field of the allocated struct or an array element,
2450 // the callee could still free the memory.
2451 // TODO: This logic should be a part of generic symbol escape callback.
2452 if (const MemRegion *MR = RetVal.getAsRegion())
2453 if (isa<FieldRegion>(MR) || isa<ElementRegion>(MR))
2454 if (const SymbolicRegion *BMR =
2455 dyn_cast<SymbolicRegion>(MR->getBaseRegion()))
2456 Sym = BMR->getSymbol();
Zhongxing Xu23baa012009-11-17 08:58:18 +00002457
Anna Zaks3aa52252012-02-11 21:44:39 +00002458 // Check if we are returning freed memory.
Jordan Rose356279c2012-08-08 18:23:31 +00002459 if (Sym)
Jordan Rosef1f26142012-11-15 19:11:33 +00002460 checkUseAfterFree(Sym, C, E);
Zhongxing Xu23baa012009-11-17 08:58:18 +00002461}
Zhongxing Xub0e15df2009-12-31 06:13:07 +00002462
Anna Zaks9fe80982012-03-22 00:57:20 +00002463// TODO: Blocks should be either inlined or should call invalidate regions
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002464// upon invocation. After that's in place, special casing here will not be
Anna Zaks9fe80982012-03-22 00:57:20 +00002465// needed.
2466void MallocChecker::checkPostStmt(const BlockExpr *BE,
2467 CheckerContext &C) const {
2468
2469 // Scan the BlockDecRefExprs for any object the retain count checker
2470 // may be tracking.
2471 if (!BE->getBlockDecl()->hasCaptures())
2472 return;
2473
2474 ProgramStateRef state = C.getState();
2475 const BlockDataRegion *R =
George Karpenkovd703ec92018-01-17 20:27:29 +00002476 cast<BlockDataRegion>(C.getSVal(BE).getAsRegion());
Anna Zaks9fe80982012-03-22 00:57:20 +00002477
2478 BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
2479 E = R->referenced_vars_end();
2480
2481 if (I == E)
2482 return;
2483
2484 SmallVector<const MemRegion*, 10> Regions;
2485 const LocationContext *LC = C.getLocationContext();
2486 MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager();
2487
2488 for ( ; I != E; ++I) {
Ted Kremenekbcf90532012-12-06 07:17:20 +00002489 const VarRegion *VR = I.getCapturedRegion();
Anna Zaks9fe80982012-03-22 00:57:20 +00002490 if (VR->getSuperRegion() == R) {
2491 VR = MemMgr.getVarRegion(VR->getDecl(), LC);
2492 }
2493 Regions.push_back(VR);
2494 }
2495
2496 state =
2497 state->scanReachableSymbols<StopTrackingCallback>(Regions.data(),
2498 Regions.data() + Regions.size()).getState();
2499 C.addTransition(state);
2500}
2501
Anna Zaks46d01602012-05-18 01:16:10 +00002502bool MallocChecker::isReleased(SymbolRef Sym, CheckerContext &C) const {
Anna Zaksa1b227b2012-02-08 23:16:56 +00002503 assert(Sym);
2504 const RefState *RS = C.getState()->get<RegionState>(Sym);
Anna Zaks46d01602012-05-18 01:16:10 +00002505 return (RS && RS->isReleased());
2506}
2507
2508bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
2509 const Stmt *S) const {
Anna Zaksa1b227b2012-02-08 23:16:56 +00002510
Jordan Rose656fdd52014-01-08 18:46:55 +00002511 if (isReleased(Sym, C)) {
Anton Yartsev59ed15b2013-03-13 14:39:10 +00002512 ReportUseAfterFree(C, S->getSourceRange(), Sym);
2513 return true;
Anna Zaksa1b227b2012-02-08 23:16:56 +00002514 }
Anton Yartsev59ed15b2013-03-13 14:39:10 +00002515
Anna Zaksa1b227b2012-02-08 23:16:56 +00002516 return false;
2517}
2518
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002519void MallocChecker::checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C,
2520 const Stmt *S) const {
2521 assert(Sym);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002522
Devin Coughlin81771732015-09-22 22:47:14 +00002523 if (const RefState *RS = C.getState()->get<RegionState>(Sym)) {
2524 if (RS->isAllocatedOfSizeZero())
2525 ReportUseZeroAllocated(C, RS->getStmt()->getSourceRange(), Sym);
2526 }
2527 else if (C.getState()->contains<ReallocSizeZeroSymbols>(Sym)) {
2528 ReportUseZeroAllocated(C, S->getSourceRange(), Sym);
2529 }
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002530}
2531
Jordan Rose656fdd52014-01-08 18:46:55 +00002532bool MallocChecker::checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const {
2533
2534 if (isReleased(Sym, C)) {
2535 ReportDoubleDelete(C, Sym);
2536 return true;
2537 }
2538 return false;
2539}
2540
Zhongxing Xu1bb6a1a2010-03-10 04:58:55 +00002541// Check if the location is a freed symbolic region.
Anna Zaks3e0f4152011-10-06 00:43:15 +00002542void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
2543 CheckerContext &C) const {
Zhongxing Xu1bb6a1a2010-03-10 04:58:55 +00002544 SymbolRef Sym = l.getLocSymbolInBase();
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002545 if (Sym) {
Anna Zaks46d01602012-05-18 01:16:10 +00002546 checkUseAfterFree(Sym, C, S);
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002547 checkUseZeroAllocated(Sym, C, S);
2548 }
Zhongxing Xu1bb6a1a2010-03-10 04:58:55 +00002549}
Ted Kremenekd21139a2010-07-31 01:52:11 +00002550
Anna Zaksbb1ef902012-02-11 21:02:35 +00002551// If a symbolic region is assumed to NULL (or another constant), stop tracking
2552// it - assuming that allocation failed on this path.
2553ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state,
2554 SVal Cond,
2555 bool Assumption) const {
2556 RegionStateTy RS = state->get<RegionState>();
Anna Zaksbb1ef902012-02-11 21:02:35 +00002557 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
Ted Kremenek244e1d72012-09-07 22:31:01 +00002558 // If the symbol is assumed to be NULL, remove it from consideration.
Jordan Rose14fe9f32012-11-01 00:18:27 +00002559 ConstraintManager &CMgr = state->getConstraintManager();
2560 ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
2561 if (AllocFailed.isConstrainedTrue())
Anna Zaksbb1ef902012-02-11 21:02:35 +00002562 state = state->remove<RegionState>(I.getKey());
2563 }
2564
Anna Zaksd56c8792012-02-13 18:05:39 +00002565 // Realloc returns 0 when reallocation fails, which means that we should
2566 // restore the state of the pointer being reallocated.
Jordan Rose0c153cb2012-11-02 01:54:06 +00002567 ReallocPairsTy RP = state->get<ReallocPairs>();
2568 for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
Ted Kremenek244e1d72012-09-07 22:31:01 +00002569 // If the symbol is assumed to be NULL, remove it from consideration.
Jordan Rose14fe9f32012-11-01 00:18:27 +00002570 ConstraintManager &CMgr = state->getConstraintManager();
2571 ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
Jordan Rose40bb12492012-11-01 00:25:15 +00002572 if (!AllocFailed.isConstrainedTrue())
Anna Zaks75cfbb62012-09-12 22:57:34 +00002573 continue;
Jordan Rose14fe9f32012-11-01 00:18:27 +00002574
Anna Zaks75cfbb62012-09-12 22:57:34 +00002575 SymbolRef ReallocSym = I.getData().ReallocatedSym;
2576 if (const RefState *RS = state->get<RegionState>(ReallocSym)) {
2577 if (RS->isReleased()) {
2578 if (I.getData().Kind == RPToBeFreedAfterFailure)
Anna Zaksac068142012-02-15 00:11:25 +00002579 state = state->set<RegionState>(ReallocSym,
Anton Yartsev05789592013-03-28 17:05:19 +00002580 RefState::getAllocated(RS->getAllocationFamily(), RS->getStmt()));
Anna Zaks75cfbb62012-09-12 22:57:34 +00002581 else if (I.getData().Kind == RPDoNotTrackAfterFailure)
2582 state = state->remove<RegionState>(ReallocSym);
2583 else
2584 assert(I.getData().Kind == RPIsFreeOnFailure);
Anna Zaksd56c8792012-02-13 18:05:39 +00002585 }
Anna Zaksd56c8792012-02-13 18:05:39 +00002586 }
Anna Zaks75cfbb62012-09-12 22:57:34 +00002587 state = state->remove<ReallocPairs>(I.getKey());
Anna Zaksd56c8792012-02-13 18:05:39 +00002588 }
2589
Anna Zaksbb1ef902012-02-11 21:02:35 +00002590 return state;
2591}
2592
Anna Zaks8ebeb642013-06-08 00:29:29 +00002593bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002594 const CallEvent *Call,
2595 ProgramStateRef State,
2596 SymbolRef &EscapingSymbol) const {
Jordan Rose7ab01822012-07-02 19:27:51 +00002597 assert(Call);
Craig Topper0dbb7832014-05-27 02:45:47 +00002598 EscapingSymbol = nullptr;
2599
Jordan Rose2a833ca2014-01-15 17:25:15 +00002600 // For now, assume that any C++ or block call can free memory.
Anna Zaks7ac344a2012-02-24 23:56:53 +00002601 // TODO: If we want to be more optimistic here, we'll need to make sure that
2602 // regions escape to C++ containers. They seem to do that even now, but for
2603 // mysterious reasons.
Jordan Rose2a833ca2014-01-15 17:25:15 +00002604 if (!(isa<SimpleFunctionCall>(Call) || isa<ObjCMethodCall>(Call)))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002605 return true;
Anna Zaks7ac344a2012-02-24 23:56:53 +00002606
Jordan Rose742920c2012-07-02 19:27:35 +00002607 // Check Objective-C messages by selector name.
Jordan Rose6bad4902012-07-02 19:27:56 +00002608 if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) {
Jordan Rose7ab01822012-07-02 19:27:51 +00002609 // If it's not a framework call, or if it takes a callback, assume it
2610 // can free memory.
Anna Zaksfe1eca52015-10-27 20:19:45 +00002611 if (!Call->isInSystemHeader() || Call->argumentsMayEscape())
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002612 return true;
Anna Zaks06a77fc2012-02-28 01:54:22 +00002613
Jordan Rose613f3c02013-03-09 00:59:10 +00002614 // If it's a method we know about, handle it explicitly post-call.
2615 // This should happen before the "freeWhenDone" check below.
2616 if (isKnownDeallocObjCMethodName(*Msg))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002617 return false;
Anna Zaks886dfb82012-06-20 23:35:57 +00002618
Jordan Rose613f3c02013-03-09 00:59:10 +00002619 // If there's a "freeWhenDone" parameter, but the method isn't one we know
2620 // about, we can't be sure that the object will use free() to deallocate the
2621 // memory, so we can't model it explicitly. The best we can do is use it to
2622 // decide whether the pointer escapes.
2623 if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(*Msg))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002624 return *FreeWhenDone;
Anna Zaks7ac344a2012-02-24 23:56:53 +00002625
Jordan Rose613f3c02013-03-09 00:59:10 +00002626 // If the first selector piece ends with "NoCopy", and there is no
2627 // "freeWhenDone" parameter set to zero, we know ownership is being
2628 // transferred. Again, though, we can't be sure that the object will use
2629 // free() to deallocate the memory, so we can't model it explicitly.
2630 StringRef FirstSlot = Msg->getSelector().getNameForSlot(0);
Jordan Rose742920c2012-07-02 19:27:35 +00002631 if (FirstSlot.endswith("NoCopy"))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002632 return true;
Anna Zaks12a8b902012-03-05 17:42:10 +00002633
Anna Zaks42908c72012-06-19 05:10:32 +00002634 // If the first selector starts with addPointer, insertPointer,
2635 // or replacePointer, assume we are dealing with NSPointerArray or similar.
2636 // This is similar to C++ containers (vector); we still might want to check
Jordan Rose742920c2012-07-02 19:27:35 +00002637 // that the pointers get freed by following the container itself.
2638 if (FirstSlot.startswith("addPointer") ||
2639 FirstSlot.startswith("insertPointer") ||
Jordan Rose514f9352014-01-07 21:39:48 +00002640 FirstSlot.startswith("replacePointer") ||
2641 FirstSlot.equals("valueWithPointer")) {
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002642 return true;
Anna Zaks42908c72012-06-19 05:10:32 +00002643 }
2644
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002645 // We should escape receiver on call to 'init'. This is especially relevant
2646 // to the receiver, as the corresponding symbol is usually not referenced
2647 // after the call.
2648 if (Msg->getMethodFamily() == OMF_init) {
2649 EscapingSymbol = Msg->getReceiverSVal().getAsSymbol();
2650 return true;
2651 }
Anna Zaks737926b2013-05-31 22:39:13 +00002652
Jordan Rose742920c2012-07-02 19:27:35 +00002653 // Otherwise, assume that the method does not free memory.
2654 // Most framework methods do not free memory.
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002655 return false;
Anna Zaks3d348342012-02-14 21:55:24 +00002656 }
2657
Jordan Rose742920c2012-07-02 19:27:35 +00002658 // At this point the only thing left to handle is straight function calls.
Jordan Rose2a833ca2014-01-15 17:25:15 +00002659 const FunctionDecl *FD = cast<SimpleFunctionCall>(Call)->getDecl();
Jordan Rose742920c2012-07-02 19:27:35 +00002660 if (!FD)
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002661 return true;
Anna Zaks7ac344a2012-02-24 23:56:53 +00002662
Jordan Rose742920c2012-07-02 19:27:35 +00002663 ASTContext &ASTC = State->getStateManager().getContext();
2664
2665 // If it's one of the allocation functions we can reason about, we model
2666 // its behavior explicitly.
2667 if (isMemFunction(FD, ASTC))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002668 return false;
Jordan Rose742920c2012-07-02 19:27:35 +00002669
2670 // If it's not a system call, assume it frees memory.
2671 if (!Call->isInSystemHeader())
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002672 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00002673
2674 // White list the system functions whose arguments escape.
2675 const IdentifierInfo *II = FD->getIdentifier();
2676 if (!II)
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002677 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00002678 StringRef FName = II->getName();
2679
Jordan Rose742920c2012-07-02 19:27:35 +00002680 // White list the 'XXXNoCopy' CoreFoundation functions.
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002681 // We specifically check these before
Jordan Rose742920c2012-07-02 19:27:35 +00002682 if (FName.endswith("NoCopy")) {
2683 // Look for the deallocator argument. We know that the memory ownership
2684 // is not transferred only if the deallocator argument is
2685 // 'kCFAllocatorNull'.
2686 for (unsigned i = 1; i < Call->getNumArgs(); ++i) {
2687 const Expr *ArgE = Call->getArgExpr(i)->IgnoreParenCasts();
2688 if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) {
2689 StringRef DeallocatorName = DE->getFoundDecl()->getName();
2690 if (DeallocatorName == "kCFAllocatorNull")
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002691 return false;
Jordan Rose742920c2012-07-02 19:27:35 +00002692 }
2693 }
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002694 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00002695 }
2696
Jordan Rose742920c2012-07-02 19:27:35 +00002697 // Associating streams with malloced buffers. The pointer can escape if
Jordan Rose7ab01822012-07-02 19:27:51 +00002698 // 'closefn' is specified (and if that function does free memory),
2699 // but it will not if closefn is not specified.
Jordan Rose742920c2012-07-02 19:27:35 +00002700 // Currently, we do not inspect the 'closefn' function (PR12101).
2701 if (FName == "funopen")
Jordan Rose7ab01822012-07-02 19:27:51 +00002702 if (Call->getNumArgs() >= 4 && Call->getArgSVal(4).isConstant(0))
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002703 return false;
Jordan Rose742920c2012-07-02 19:27:35 +00002704
2705 // Do not warn on pointers passed to 'setbuf' when used with std streams,
2706 // these leaks might be intentional when setting the buffer for stdio.
2707 // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer
2708 if (FName == "setbuf" || FName =="setbuffer" ||
2709 FName == "setlinebuf" || FName == "setvbuf") {
2710 if (Call->getNumArgs() >= 1) {
2711 const Expr *ArgE = Call->getArgExpr(0)->IgnoreParenCasts();
2712 if (const DeclRefExpr *ArgDRE = dyn_cast<DeclRefExpr>(ArgE))
2713 if (const VarDecl *D = dyn_cast<VarDecl>(ArgDRE->getDecl()))
2714 if (D->getCanonicalDecl()->getName().find("std") != StringRef::npos)
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002715 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00002716 }
2717 }
2718
2719 // A bunch of other functions which either take ownership of a pointer or
2720 // wrap the result up in a struct or object, meaning it can be freed later.
2721 // (See RetainCountChecker.) Not all the parameters here are invalidated,
2722 // but the Malloc checker cannot differentiate between them. The right way
2723 // of doing this would be to implement a pointer escapes callback.
2724 if (FName == "CGBitmapContextCreate" ||
2725 FName == "CGBitmapContextCreateWithData" ||
2726 FName == "CVPixelBufferCreateWithBytes" ||
2727 FName == "CVPixelBufferCreateWithPlanarBytes" ||
2728 FName == "OSAtomicEnqueue") {
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002729 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00002730 }
2731
Anna Zaks03f48332016-01-06 00:32:56 +00002732 if (FName == "postEvent" &&
2733 FD->getQualifiedNameAsString() == "QCoreApplication::postEvent") {
2734 return true;
2735 }
2736
2737 if (FName == "postEvent" &&
2738 FD->getQualifiedNameAsString() == "QCoreApplication::postEvent") {
2739 return true;
2740 }
2741
Artem Dergachev85c92112016-12-16 12:21:55 +00002742 if (FName == "connectImpl" &&
2743 FD->getQualifiedNameAsString() == "QObject::connectImpl") {
2744 return true;
2745 }
2746
Jordan Rose7ab01822012-07-02 19:27:51 +00002747 // Handle cases where we know a buffer's /address/ can escape.
2748 // Note that the above checks handle some special cases where we know that
2749 // even though the address escapes, it's still our responsibility to free the
2750 // buffer.
2751 if (Call->argumentsMayEscape())
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002752 return true;
Jordan Rose742920c2012-07-02 19:27:35 +00002753
2754 // Otherwise, assume that the function does not free memory.
2755 // Most system calls do not free the memory.
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002756 return false;
Anna Zaks3d348342012-02-14 21:55:24 +00002757}
2758
Anna Zaks333481b2013-03-28 23:15:29 +00002759static bool retTrue(const RefState *RS) {
2760 return true;
2761}
2762
2763static bool checkIfNewOrNewArrayFamily(const RefState *RS) {
2764 return (RS->getAllocationFamily() == AF_CXXNewArray ||
2765 RS->getAllocationFamily() == AF_CXXNew);
2766}
2767
Anna Zaksdc154152012-12-20 00:38:25 +00002768ProgramStateRef MallocChecker::checkPointerEscape(ProgramStateRef State,
2769 const InvalidatedSymbols &Escaped,
Anna Zaksacdc13c2013-02-07 23:05:43 +00002770 const CallEvent *Call,
2771 PointerEscapeKind Kind) const {
Anna Zaks333481b2013-03-28 23:15:29 +00002772 return checkPointerEscapeAux(State, Escaped, Call, Kind, &retTrue);
2773}
2774
2775ProgramStateRef MallocChecker::checkConstPointerEscape(ProgramStateRef State,
2776 const InvalidatedSymbols &Escaped,
2777 const CallEvent *Call,
2778 PointerEscapeKind Kind) const {
2779 return checkPointerEscapeAux(State, Escaped, Call, Kind,
2780 &checkIfNewOrNewArrayFamily);
2781}
2782
2783ProgramStateRef MallocChecker::checkPointerEscapeAux(ProgramStateRef State,
2784 const InvalidatedSymbols &Escaped,
2785 const CallEvent *Call,
2786 PointerEscapeKind Kind,
2787 bool(*CheckRefState)(const RefState*)) const {
Jordan Rose613f3c02013-03-09 00:59:10 +00002788 // If we know that the call does not free memory, or we want to process the
2789 // call later, keep tracking the top level arguments.
Craig Topper0dbb7832014-05-27 02:45:47 +00002790 SymbolRef EscapingSymbol = nullptr;
Jordan Rose757fbb02013-05-10 17:07:16 +00002791 if (Kind == PSK_DirectEscapeOnCall &&
Anna Zaks8ebeb642013-06-08 00:29:29 +00002792 !mayFreeAnyEscapedMemoryOrIsModeledExplicitly(Call, State,
2793 EscapingSymbol) &&
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002794 !EscapingSymbol) {
Anna Zaks3d348342012-02-14 21:55:24 +00002795 return State;
Anna Zaksacdc13c2013-02-07 23:05:43 +00002796 }
Anna Zaks3d348342012-02-14 21:55:24 +00002797
Anna Zaksdc154152012-12-20 00:38:25 +00002798 for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
Anna Zaks333481b2013-03-28 23:15:29 +00002799 E = Escaped.end();
2800 I != E; ++I) {
Anna Zaksbb1ef902012-02-11 21:02:35 +00002801 SymbolRef sym = *I;
Anna Zaksdc154152012-12-20 00:38:25 +00002802
Anna Zaksa4bc5e12013-05-31 23:47:32 +00002803 if (EscapingSymbol && EscapingSymbol != sym)
2804 continue;
Ted Kremenek3a0678e2015-09-08 03:50:52 +00002805
Anna Zaks0d6989b2012-06-22 02:04:31 +00002806 if (const RefState *RS = State->get<RegionState>(sym)) {
Anton Yartsevb50f4ba2015-04-14 14:18:04 +00002807 if ((RS->isAllocated() || RS->isAllocatedOfSizeZero()) &&
2808 CheckRefState(RS)) {
Anna Zaks23a62012012-08-09 00:42:24 +00002809 State = State->remove<RegionState>(sym);
Anna Zaks93a21a82013-04-09 00:30:28 +00002810 State = State->set<RegionState>(sym, RefState::getEscaped(RS));
2811 }
Anna Zaks0d6989b2012-06-22 02:04:31 +00002812 }
Anna Zaksbb1ef902012-02-11 21:02:35 +00002813 }
Anna Zaks3d348342012-02-14 21:55:24 +00002814 return State;
Ted Kremenekd21139a2010-07-31 01:52:11 +00002815}
Argyrios Kyrtzidis183f0fb2011-02-28 01:26:35 +00002816
Jordy Rosebf38f202012-03-18 07:43:35 +00002817static SymbolRef findFailedReallocSymbol(ProgramStateRef currState,
2818 ProgramStateRef prevState) {
Jordan Rose0c153cb2012-11-02 01:54:06 +00002819 ReallocPairsTy currMap = currState->get<ReallocPairs>();
2820 ReallocPairsTy prevMap = prevState->get<ReallocPairs>();
Jordy Rosebf38f202012-03-18 07:43:35 +00002821
Jordan Rose0c153cb2012-11-02 01:54:06 +00002822 for (ReallocPairsTy::iterator I = prevMap.begin(), E = prevMap.end();
Jordy Rosebf38f202012-03-18 07:43:35 +00002823 I != E; ++I) {
2824 SymbolRef sym = I.getKey();
2825 if (!currMap.lookup(sym))
2826 return sym;
2827 }
2828
Craig Topper0dbb7832014-05-27 02:45:47 +00002829 return nullptr;
Jordy Rosebf38f202012-03-18 07:43:35 +00002830}
2831
Artem Dergachevff1fc212018-03-21 00:49:47 +00002832static bool isReferenceCountingPointerDestructor(const CXXDestructorDecl *DD) {
2833 if (const IdentifierInfo *II = DD->getParent()->getIdentifier()) {
2834 StringRef N = II->getName();
2835 if (N.contains_lower("ptr") || N.contains_lower("pointer")) {
2836 if (N.contains_lower("ref") || N.contains_lower("cnt") ||
2837 N.contains_lower("intrusive") || N.contains_lower("shared")) {
2838 return true;
2839 }
2840 }
2841 }
2842 return false;
2843}
2844
David Blaikie0a0c2752017-01-05 17:26:53 +00002845std::shared_ptr<PathDiagnosticPiece> MallocChecker::MallocBugVisitor::VisitNode(
2846 const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
2847 BugReport &BR) {
Artem Dergachev5337efc2018-02-27 21:19:33 +00002848 const Stmt *S = PathDiagnosticLocation::getStmt(N);
2849 if (!S)
2850 return nullptr;
2851
2852 const LocationContext *CurrentLC = N->getLocationContext();
2853
2854 // If we find an atomic fetch_add or fetch_sub within the destructor in which
2855 // the pointer was released (before the release), this is likely a destructor
2856 // of a shared pointer.
2857 // Because we don't model atomics, and also because we don't know that the
2858 // original reference count is positive, we should not report use-after-frees
2859 // on objects deleted in such destructors. This can probably be improved
2860 // through better shared pointer modeling.
2861 if (ReleaseDestructorLC) {
2862 if (const auto *AE = dyn_cast<AtomicExpr>(S)) {
2863 AtomicExpr::AtomicOp Op = AE->getOp();
2864 if (Op == AtomicExpr::AO__c11_atomic_fetch_add ||
2865 Op == AtomicExpr::AO__c11_atomic_fetch_sub) {
2866 if (ReleaseDestructorLC == CurrentLC ||
2867 ReleaseDestructorLC->isParentOf(CurrentLC)) {
2868 BR.markInvalid(getTag(), S);
2869 }
2870 }
2871 }
2872 }
2873
Jordy Rosebf38f202012-03-18 07:43:35 +00002874 ProgramStateRef state = N->getState();
2875 ProgramStateRef statePrev = PrevN->getState();
2876
2877 const RefState *RS = state->get<RegionState>(Sym);
2878 const RefState *RSPrev = statePrev->get<RegionState>(Sym);
Anna Zaks52242a62012-08-03 18:30:18 +00002879 if (!RS)
Craig Topper0dbb7832014-05-27 02:45:47 +00002880 return nullptr;
Anna Zaks2b5bb972012-02-09 06:25:51 +00002881
Jordan Rose681cce92012-07-10 22:07:42 +00002882 // FIXME: We will eventually need to handle non-statement-based events
2883 // (__attribute__((cleanup))).
2884
Anna Zaks2b5bb972012-02-09 06:25:51 +00002885 // Find out if this is an interesting point and what is the kind.
Gabor Horvath6ee4f902016-08-18 07:54:50 +00002886 const char *Msg = nullptr;
2887 StackHintGeneratorForSymbol *StackHint = nullptr;
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002888 if (Mode == Normal) {
Anna Zaks1ff57d52012-03-15 21:13:02 +00002889 if (isAllocated(RS, RSPrev, S)) {
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002890 Msg = "Memory is allocated";
Anna Zaksa7f457a2012-03-16 23:44:28 +00002891 StackHint = new StackHintGeneratorForSymbol(Sym,
2892 "Returned allocated memory");
Anna Zaks1ff57d52012-03-15 21:13:02 +00002893 } else if (isReleased(RS, RSPrev, S)) {
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002894 Msg = "Memory is released";
Anna Zaksa7f457a2012-03-16 23:44:28 +00002895 StackHint = new StackHintGeneratorForSymbol(Sym,
Anna Zakse4cfcd42013-04-16 00:22:55 +00002896 "Returning; memory was released");
Artem Dergachev5337efc2018-02-27 21:19:33 +00002897
Artem Dergachevff1fc212018-03-21 00:49:47 +00002898 // See if we're releasing memory while inlining a destructor
2899 // (or one of its callees). This turns on various common
2900 // false positive suppressions.
2901 bool FoundAnyDestructor = false;
Artem Dergachev5337efc2018-02-27 21:19:33 +00002902 for (const LocationContext *LC = CurrentLC; LC; LC = LC->getParent()) {
Artem Dergachevff1fc212018-03-21 00:49:47 +00002903 if (const auto *DD = dyn_cast<CXXDestructorDecl>(LC->getDecl())) {
2904 if (isReferenceCountingPointerDestructor(DD)) {
2905 // This immediately looks like a reference-counting destructor.
2906 // We're bad at guessing the original reference count of the object,
2907 // so suppress the report for now.
2908 BR.markInvalid(getTag(), DD);
2909 } else if (!FoundAnyDestructor) {
2910 assert(!ReleaseDestructorLC &&
2911 "There can be only one release point!");
2912 // Suspect that it's a reference counting pointer destructor.
2913 // On one of the next nodes might find out that it has atomic
2914 // reference counting operations within it (see the code above),
2915 // and if so, we'd conclude that it likely is a reference counting
2916 // pointer destructor.
2917 ReleaseDestructorLC = LC->getCurrentStackFrame();
2918 // It is unlikely that releasing memory is delegated to a destructor
2919 // inside a destructor of a shared pointer, because it's fairly hard
2920 // to pass the information that the pointer indeed needs to be
2921 // released into it. So we're only interested in the innermost
2922 // destructor.
2923 FoundAnyDestructor = true;
2924 }
Artem Dergachev5337efc2018-02-27 21:19:33 +00002925 }
2926 }
Anna Zaks0d6989b2012-06-22 02:04:31 +00002927 } else if (isRelinquished(RS, RSPrev, S)) {
Alp Toker5faf0c02013-12-02 03:50:25 +00002928 Msg = "Memory ownership is transferred";
Anna Zaks0d6989b2012-06-22 02:04:31 +00002929 StackHint = new StackHintGeneratorForSymbol(Sym, "");
Anna Zaks1ff57d52012-03-15 21:13:02 +00002930 } else if (isReallocFailedCheck(RS, RSPrev, S)) {
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002931 Mode = ReallocationFailed;
2932 Msg = "Reallocation failed";
Anna Zakscba4f292012-03-16 23:24:20 +00002933 StackHint = new StackHintGeneratorForReallocationFailed(Sym,
Anna Zaksa7f457a2012-03-16 23:44:28 +00002934 "Reallocation failed");
Jordy Rosebf38f202012-03-18 07:43:35 +00002935
Jordy Rose21ff76e2012-03-24 03:15:09 +00002936 if (SymbolRef sym = findFailedReallocSymbol(state, statePrev)) {
2937 // Is it possible to fail two reallocs WITHOUT testing in between?
2938 assert((!FailedReallocSymbol || FailedReallocSymbol == sym) &&
2939 "We only support one failed realloc at a time.");
Jordy Rosebf38f202012-03-18 07:43:35 +00002940 BR.markInteresting(sym);
Jordy Rose21ff76e2012-03-24 03:15:09 +00002941 FailedReallocSymbol = sym;
2942 }
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002943 }
2944
2945 // We are in a special mode if a reallocation failed later in the path.
2946 } else if (Mode == ReallocationFailed) {
Jordy Rose21ff76e2012-03-24 03:15:09 +00002947 assert(FailedReallocSymbol && "No symbol to look for.");
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002948
Jordy Rose21ff76e2012-03-24 03:15:09 +00002949 // Is this is the first appearance of the reallocated symbol?
2950 if (!statePrev->get<RegionState>(FailedReallocSymbol)) {
Jordy Rose21ff76e2012-03-24 03:15:09 +00002951 // We're at the reallocation point.
2952 Msg = "Attempt to reallocate memory";
2953 StackHint = new StackHintGeneratorForSymbol(Sym,
2954 "Returned reallocated memory");
Craig Topper0dbb7832014-05-27 02:45:47 +00002955 FailedReallocSymbol = nullptr;
Jordy Rose21ff76e2012-03-24 03:15:09 +00002956 Mode = Normal;
2957 }
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002958 }
2959
Anna Zaks2b5bb972012-02-09 06:25:51 +00002960 if (!Msg)
Craig Topper0dbb7832014-05-27 02:45:47 +00002961 return nullptr;
Anna Zakscba4f292012-03-16 23:24:20 +00002962 assert(StackHint);
Anna Zaks2b5bb972012-02-09 06:25:51 +00002963
2964 // Generate the extra diagnostic.
Anna Zaks9eb7bc82012-02-16 22:26:07 +00002965 PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
Anna Zaks2b5bb972012-02-09 06:25:51 +00002966 N->getLocationContext());
David Blaikie0a0c2752017-01-05 17:26:53 +00002967 return std::make_shared<PathDiagnosticEventPiece>(Pos, Msg, true, StackHint);
Anna Zaks2b5bb972012-02-09 06:25:51 +00002968}
2969
Anna Zaks263b7e02012-05-02 00:05:20 +00002970void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State,
2971 const char *NL, const char *Sep) const {
2972
2973 RegionStateTy RS = State->get<RegionState>();
2974
Ted Kremenek6fcefb52013-01-03 01:30:12 +00002975 if (!RS.isEmpty()) {
Anton Yartsev6a619222014-02-17 18:25:34 +00002976 Out << Sep << "MallocChecker :" << NL;
Ted Kremenek6fcefb52013-01-03 01:30:12 +00002977 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
Anton Yartsev6a619222014-02-17 18:25:34 +00002978 const RefState *RefS = State->get<RegionState>(I.getKey());
2979 AllocationFamily Family = RefS->getAllocationFamily();
Anton Yartsev4eb394d2015-03-07 00:31:53 +00002980 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
Anton Yartsev2487dd62015-03-10 22:24:21 +00002981 if (!CheckKind.hasValue())
2982 CheckKind = getCheckIfTracked(Family, true);
Anton Yartsev4eb394d2015-03-07 00:31:53 +00002983
Ted Kremenek6fcefb52013-01-03 01:30:12 +00002984 I.getKey()->dumpToStream(Out);
2985 Out << " : ";
2986 I.getData().dump(Out);
Anton Yartsev6a619222014-02-17 18:25:34 +00002987 if (CheckKind.hasValue())
2988 Out << " (" << CheckNames[*CheckKind].getName() << ")";
Ted Kremenek6fcefb52013-01-03 01:30:12 +00002989 Out << NL;
2990 }
2991 }
Anna Zaks263b7e02012-05-02 00:05:20 +00002992}
Anna Zaks2b5bb972012-02-09 06:25:51 +00002993
Anna Zakse4cfcd42013-04-16 00:22:55 +00002994void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) {
2995 registerCStringCheckerBasic(mgr);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002996 MallocChecker *checker = mgr.registerChecker<MallocChecker>();
Gabor Horvathe40c71c2015-03-04 17:59:34 +00002997 checker->IsOptimistic = mgr.getAnalyzerOptions().getBooleanOption(
2998 "Optimistic", false, checker);
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00002999 checker->ChecksEnabled[MallocChecker::CK_NewDeleteLeaksChecker] = true;
3000 checker->CheckNames[MallocChecker::CK_NewDeleteLeaksChecker] =
3001 mgr.getCurrentCheckName();
Ted Kremenek3a0678e2015-09-08 03:50:52 +00003002 // We currently treat NewDeleteLeaks checker as a subchecker of NewDelete
Anna Zakse4cfcd42013-04-16 00:22:55 +00003003 // checker.
Gabor Horvathb77bc6b2018-01-06 10:51:00 +00003004 if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker]) {
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00003005 checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker] = true;
Gabor Horvathb77bc6b2018-01-06 10:51:00 +00003006 // FIXME: This does not set the correct name, but without this workaround
3007 // no name will be set at all.
3008 checker->CheckNames[MallocChecker::CK_NewDeleteChecker] =
3009 mgr.getCurrentCheckName();
3010 }
Anna Zakse4cfcd42013-04-16 00:22:55 +00003011}
Anton Yartsev7af0aa82013-04-12 23:25:40 +00003012
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00003013#define REGISTER_CHECKER(name) \
3014 void ento::register##name(CheckerManager &mgr) { \
3015 registerCStringCheckerBasic(mgr); \
3016 MallocChecker *checker = mgr.registerChecker<MallocChecker>(); \
Gabor Horvathe40c71c2015-03-04 17:59:34 +00003017 checker->IsOptimistic = mgr.getAnalyzerOptions().getBooleanOption( \
3018 "Optimistic", false, checker); \
Alexander Kornienko4aca9b12014-02-11 21:49:21 +00003019 checker->ChecksEnabled[MallocChecker::CK_##name] = true; \
3020 checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \
3021 }
Anna Zakscd37bf42012-02-08 23:16:52 +00003022
Gabor Horvathe40c71c2015-03-04 17:59:34 +00003023REGISTER_CHECKER(MallocChecker)
Anton Yartsev13df0362013-03-25 01:35:45 +00003024REGISTER_CHECKER(NewDeleteChecker)
Anton Yartsev05789592013-03-28 17:05:19 +00003025REGISTER_CHECKER(MismatchedDeallocatorChecker)