Coverage Report

Created: 2023-09-21 18:56

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
Line
Count
Source (jump to first uncovered line)
1
//=== MallocChecker.cpp - A malloc/free checker -------------------*- C++ -*--//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file defines a variety of memory management related checkers, such as
10
// leak, double free, and use-after-free.
11
//
12
// The following checkers are defined here:
13
//
14
//   * MallocChecker
15
//       Despite its name, it models all sorts of memory allocations and
16
//       de- or reallocation, including but not limited to malloc, free,
17
//       relloc, new, delete. It also reports on a variety of memory misuse
18
//       errors.
19
//       Many other checkers interact very closely with this checker, in fact,
20
//       most are merely options to this one. Other checkers may register
21
//       MallocChecker, but do not enable MallocChecker's reports (more details
22
//       to follow around its field, ChecksEnabled).
23
//       It also has a boolean "Optimistic" checker option, which if set to true
24
//       will cause the checker to model user defined memory management related
25
//       functions annotated via the attribute ownership_takes, ownership_holds
26
//       and ownership_returns.
27
//
28
//   * NewDeleteChecker
29
//       Enables the modeling of new, new[], delete, delete[] in MallocChecker,
30
//       and checks for related double-free and use-after-free errors.
31
//
32
//   * NewDeleteLeaksChecker
33
//       Checks for leaks related to new, new[], delete, delete[].
34
//       Depends on NewDeleteChecker.
35
//
36
//   * MismatchedDeallocatorChecker
37
//       Enables checking whether memory is deallocated with the correspending
38
//       allocation function in MallocChecker, such as malloc() allocated
39
//       regions are only freed by free(), new by delete, new[] by delete[].
40
//
41
//  InnerPointerChecker interacts very closely with MallocChecker, but unlike
42
//  the above checkers, it has it's own file, hence the many InnerPointerChecker
43
//  related headers and non-static functions.
44
//
45
//===----------------------------------------------------------------------===//
46
47
#include "AllocationState.h"
48
#include "InterCheckerAPI.h"
49
#include "clang/AST/Attr.h"
50
#include "clang/AST/DeclCXX.h"
51
#include "clang/AST/DeclTemplate.h"
52
#include "clang/AST/Expr.h"
53
#include "clang/AST/ExprCXX.h"
54
#include "clang/AST/ParentMap.h"
55
#include "clang/ASTMatchers/ASTMatchFinder.h"
56
#include "clang/ASTMatchers/ASTMatchers.h"
57
#include "clang/Analysis/ProgramPoint.h"
58
#include "clang/Basic/LLVM.h"
59
#include "clang/Basic/SourceManager.h"
60
#include "clang/Basic/TargetInfo.h"
61
#include "clang/Lex/Lexer.h"
62
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
63
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
64
#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
65
#include "clang/StaticAnalyzer/Core/Checker.h"
66
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
67
#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
68
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
69
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
70
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
71
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h"
72
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
73
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
74
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
75
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
76
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
77
#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
78
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
79
#include "llvm/ADT/STLExtras.h"
80
#include "llvm/ADT/SetOperations.h"
81
#include "llvm/ADT/SmallString.h"
82
#include "llvm/ADT/StringExtras.h"
83
#include "llvm/Support/Casting.h"
84
#include "llvm/Support/Compiler.h"
85
#include "llvm/Support/ErrorHandling.h"
86
#include "llvm/Support/raw_ostream.h"
87
#include <climits>
88
#include <functional>
89
#include <optional>
90
#include <utility>
91
92
using namespace clang;
93
using namespace ento;
94
using namespace std::placeholders;
95
96
//===----------------------------------------------------------------------===//
97
// The types of allocation we're modeling. This is used to check whether a
98
// dynamically allocated object is deallocated with the correct function, like
99
// not using operator delete on an object created by malloc(), or alloca regions
100
// aren't ever deallocated manually.
101
//===----------------------------------------------------------------------===//
102
103
namespace {
104
105
// Used to check correspondence between allocators and deallocators.
106
enum AllocationFamily {
107
  AF_None,
108
  AF_Malloc,
109
  AF_CXXNew,
110
  AF_CXXNewArray,
111
  AF_IfNameIndex,
112
  AF_Alloca,
113
  AF_InnerBuffer
114
};
115
116
} // end of anonymous namespace
117
118
/// Print names of allocators and deallocators.
119
///
120
/// \returns true on success.
121
static bool printMemFnName(raw_ostream &os, CheckerContext &C, const Expr *E);
122
123
/// Print expected name of an allocator based on the deallocator's family
124
/// derived from the DeallocExpr.
125
static void printExpectedAllocName(raw_ostream &os, AllocationFamily Family);
126
127
/// Print expected name of a deallocator based on the allocator's
128
/// family.
129
static void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family);
130
131
//===----------------------------------------------------------------------===//
132
// The state of a symbol, in terms of memory management.
133
//===----------------------------------------------------------------------===//
134
135
namespace {
136
137
class RefState {
138
  enum Kind {
139
    // Reference to allocated memory.
140
    Allocated,
141
    // Reference to zero-allocated memory.
142
    AllocatedOfSizeZero,
143
    // Reference to released/freed memory.
144
    Released,
145
    // The responsibility for freeing resources has transferred from
146
    // this reference. A relinquished symbol should not be freed.
147
    Relinquished,
148
    // We are no longer guaranteed to have observed all manipulations
149
    // of this pointer/memory. For example, it could have been
150
    // passed as a parameter to an opaque function.
151
    Escaped
152
  };
153
154
  const Stmt *S;
155
156
  Kind K;
157
  AllocationFamily Family;
158
159
  RefState(Kind k, const Stmt *s, AllocationFamily family)
160
2.84k
      : S(s), K(k), Family(family) {
161
2.84k
    assert(family != AF_None);
162
2.84k
  }
163
164
public:
165
29.1k
  bool isAllocated() const { return K == Allocated; }
166
5.54k
  bool isAllocatedOfSizeZero() const { return K == AllocatedOfSizeZero; }
167
18.5k
  bool isReleased() const { return K == Released; }
168
1.85k
  bool isRelinquished() const { return K == Relinquished; }
169
104
  bool isEscaped() const { return K == Escaped; }
170
4.46k
  AllocationFamily getAllocationFamily() const { return Family; }
171
669
  const Stmt *getStmt() const { return S; }
172
173
601
  bool operator==(const RefState &X) const {
174
601
    return K == X.K && S == X.S && Family == X.Family;
175
601
  }
176
177
1.53k
  static RefState getAllocated(AllocationFamily family, const Stmt *s) {
178
1.53k
    return RefState(Allocated, s, family);
179
1.53k
  }
180
80
  static RefState getAllocatedOfSizeZero(const RefState *RS) {
181
80
    return RefState(AllocatedOfSizeZero, RS->getStmt(),
182
80
                    RS->getAllocationFamily());
183
80
  }
184
780
  static RefState getReleased(AllocationFamily family, const Stmt *s) {
185
780
    return RefState(Released, s, family);
186
780
  }
187
27
  static RefState getRelinquished(AllocationFamily family, const Stmt *s) {
188
27
    return RefState(Relinquished, s, family);
189
27
  }
190
421
  static RefState getEscaped(const RefState *RS) {
191
421
    return RefState(Escaped, RS->getStmt(), RS->getAllocationFamily());
192
421
  }
193
194
3.88k
  void Profile(llvm::FoldingSetNodeID &ID) const {
195
3.88k
    ID.AddInteger(K);
196
3.88k
    ID.AddPointer(S);
197
3.88k
    ID.AddInteger(Family);
198
3.88k
  }
199
200
0
  LLVM_DUMP_METHOD void dump(raw_ostream &OS) const {
201
0
    switch (K) {
202
0
#define CASE(ID) case ID: OS << #ID; break;
203
0
    CASE(Allocated)
204
0
    CASE(AllocatedOfSizeZero)
205
0
    CASE(Released)
206
0
    CASE(Relinquished)
207
0
    CASE(Escaped)
208
0
    }
209
0
  }
210
211
0
  LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); }
212
};
213
214
} // end of anonymous namespace
215
216
REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState)
217
218
/// Check if the memory associated with this symbol was released.
219
static bool isReleased(SymbolRef Sym, CheckerContext &C);
220
221
/// Update the RefState to reflect the new memory allocation.
222
/// The optional \p RetVal parameter specifies the newly allocated pointer
223
/// value; if unspecified, the value of expression \p E is used.
224
static ProgramStateRef
225
MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State,
226
                     AllocationFamily Family,
227
                     std::optional<SVal> RetVal = std::nullopt);
228
229
//===----------------------------------------------------------------------===//
230
// The modeling of memory reallocation.
231
//
232
// The terminology 'toPtr' and 'fromPtr' will be used:
233
//   toPtr = realloc(fromPtr, 20);
234
//===----------------------------------------------------------------------===//
235
236
REGISTER_SET_WITH_PROGRAMSTATE(ReallocSizeZeroSymbols, SymbolRef)
237
238
namespace {
239
240
/// The state of 'fromPtr' after reallocation is known to have failed.
241
enum OwnershipAfterReallocKind {
242
  // The symbol needs to be freed (e.g.: realloc)
243
  OAR_ToBeFreedAfterFailure,
244
  // The symbol has been freed (e.g.: reallocf)
245
  OAR_FreeOnFailure,
246
  // The symbol doesn't have to freed (e.g.: we aren't sure if, how and where
247
  // 'fromPtr' was allocated:
248
  //    void Haha(int *ptr) {
249
  //      ptr = realloc(ptr, 67);
250
  //      // ...
251
  //    }
252
  // ).
253
  OAR_DoNotTrackAfterFailure
254
};
255
256
/// Stores information about the 'fromPtr' symbol after reallocation.
257
///
258
/// This is important because realloc may fail, and that needs special modeling.
259
/// Whether reallocation failed or not will not be known until later, so we'll
260
/// store whether upon failure 'fromPtr' will be freed, or needs to be freed
261
/// later, etc.
262
struct ReallocPair {
263
264
  // The 'fromPtr'.
265
  SymbolRef ReallocatedSym;
266
  OwnershipAfterReallocKind Kind;
267
268
  ReallocPair(SymbolRef S, OwnershipAfterReallocKind K)
269
56
      : ReallocatedSym(S), Kind(K) {}
270
114
  void Profile(llvm::FoldingSetNodeID &ID) const {
271
114
    ID.AddInteger(Kind);
272
114
    ID.AddPointer(ReallocatedSym);
273
114
  }
274
24
  bool operator==(const ReallocPair &X) const {
275
24
    return ReallocatedSym == X.ReallocatedSym &&
276
24
           Kind == X.Kind;
277
24
  }
278
};
279
280
} // end of anonymous namespace
281
282
REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair)
283
284
/// Tells if the callee is one of the builtin new/delete operators, including
285
/// placement operators and other standard overloads.
286
static bool isStandardNewDelete(const FunctionDecl *FD);
287
30.5k
static bool isStandardNewDelete(const CallEvent &Call) {
288
30.5k
  if (!Call.getDecl() || 
!isa<FunctionDecl>(Call.getDecl())30.5k
)
289
107
    return false;
290
30.4k
  return isStandardNewDelete(cast<FunctionDecl>(Call.getDecl()));
291
30.5k
}
292
293
//===----------------------------------------------------------------------===//
294
// Definition of the MallocChecker class.
295
//===----------------------------------------------------------------------===//
296
297
namespace {
298
299
class MallocChecker
300
    : public Checker<check::DeadSymbols, check::PointerEscape,
301
                     check::ConstPointerEscape, check::PreStmt<ReturnStmt>,
302
                     check::EndFunction, check::PreCall, check::PostCall,
303
                     check::NewAllocator, check::PostStmt<BlockExpr>,
304
                     check::PostObjCMessage, check::Location, eval::Assume> {
305
public:
306
  /// In pessimistic mode, the checker assumes that it does not know which
307
  /// functions might free the memory.
308
  /// In optimistic mode, the checker assumes that all user-defined functions
309
  /// which might free a pointer are annotated.
310
  bool ShouldIncludeOwnershipAnnotatedFunctions = false;
311
312
  bool ShouldRegisterNoOwnershipChangeVisitor = false;
313
314
  /// Many checkers are essentially built into this one, so enabling them will
315
  /// make MallocChecker perform additional modeling and reporting.
316
  enum CheckKind {
317
    /// When a subchecker is enabled but MallocChecker isn't, model memory
318
    /// management but do not emit warnings emitted with MallocChecker only
319
    /// enabled.
320
    CK_MallocChecker,
321
    CK_NewDeleteChecker,
322
    CK_NewDeleteLeaksChecker,
323
    CK_MismatchedDeallocatorChecker,
324
    CK_InnerPointerChecker,
325
    CK_NumCheckKinds
326
  };
327
328
  using LeakInfo = std::pair<const ExplodedNode *, const MemRegion *>;
329
330
  bool ChecksEnabled[CK_NumCheckKinds] = {false};
331
  CheckerNameRef CheckNames[CK_NumCheckKinds];
332
333
  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
334
  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
335
  void checkNewAllocator(const CXXAllocatorCall &Call, CheckerContext &C) const;
336
  void checkPostObjCMessage(const ObjCMethodCall &Call, CheckerContext &C) const;
337
  void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
338
  void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
339
  void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
340
  void checkEndFunction(const ReturnStmt *S, CheckerContext &C) const;
341
  ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
342
                            bool Assumption) const;
343
  void checkLocation(SVal l, bool isLoad, const Stmt *S,
344
                     CheckerContext &C) const;
345
346
  ProgramStateRef checkPointerEscape(ProgramStateRef State,
347
                                    const InvalidatedSymbols &Escaped,
348
                                    const CallEvent *Call,
349
                                    PointerEscapeKind Kind) const;
350
  ProgramStateRef checkConstPointerEscape(ProgramStateRef State,
351
                                          const InvalidatedSymbols &Escaped,
352
                                          const CallEvent *Call,
353
                                          PointerEscapeKind Kind) const;
354
355
  void printState(raw_ostream &Out, ProgramStateRef State,
356
                  const char *NL, const char *Sep) const override;
357
358
private:
359
  mutable std::unique_ptr<BugType> BT_DoubleFree[CK_NumCheckKinds];
360
  mutable std::unique_ptr<BugType> BT_DoubleDelete;
361
  mutable std::unique_ptr<BugType> BT_Leak[CK_NumCheckKinds];
362
  mutable std::unique_ptr<BugType> BT_UseFree[CK_NumCheckKinds];
363
  mutable std::unique_ptr<BugType> BT_BadFree[CK_NumCheckKinds];
364
  mutable std::unique_ptr<BugType> BT_FreeAlloca[CK_NumCheckKinds];
365
  mutable std::unique_ptr<BugType> BT_MismatchedDealloc;
366
  mutable std::unique_ptr<BugType> BT_OffsetFree[CK_NumCheckKinds];
367
  mutable std::unique_ptr<BugType> BT_UseZerroAllocated[CK_NumCheckKinds];
368
369
#define CHECK_FN(NAME)                                                         \
370
  void NAME(const CallEvent &Call, CheckerContext &C) const;
371
372
  CHECK_FN(checkFree)
373
  CHECK_FN(checkIfNameIndex)
374
  CHECK_FN(checkBasicAlloc)
375
  CHECK_FN(checkKernelMalloc)
376
  CHECK_FN(checkCalloc)
377
  CHECK_FN(checkAlloca)
378
  CHECK_FN(checkStrdup)
379
  CHECK_FN(checkIfFreeNameIndex)
380
  CHECK_FN(checkCXXNewOrCXXDelete)
381
  CHECK_FN(checkGMalloc0)
382
  CHECK_FN(checkGMemdup)
383
  CHECK_FN(checkGMallocN)
384
  CHECK_FN(checkGMallocN0)
385
  CHECK_FN(checkReallocN)
386
  CHECK_FN(checkOwnershipAttr)
387
388
  void checkRealloc(const CallEvent &Call, CheckerContext &C,
389
                    bool ShouldFreeOnFail) const;
390
391
  using CheckFn = std::function<void(const MallocChecker *,
392
                                     const CallEvent &Call, CheckerContext &C)>;
393
394
  const CallDescriptionMap<CheckFn> FreeingMemFnMap{
395
      {{{"free"}, 1}, &MallocChecker::checkFree},
396
      {{{"if_freenameindex"}, 1}, &MallocChecker::checkIfFreeNameIndex},
397
      {{{"kfree"}, 1}, &MallocChecker::checkFree},
398
      {{{"g_free"}, 1}, &MallocChecker::checkFree},
399
  };
400
401
  bool isFreeingCall(const CallEvent &Call) const;
402
  static bool isFreeingOwnershipAttrCall(const FunctionDecl *Func);
403
404
  friend class NoOwnershipChangeVisitor;
405
406
  CallDescriptionMap<CheckFn> AllocatingMemFnMap{
407
      {{{"alloca"}, 1}, &MallocChecker::checkAlloca},
408
      {{{"_alloca"}, 1}, &MallocChecker::checkAlloca},
409
      {{{"malloc"}, 1}, &MallocChecker::checkBasicAlloc},
410
      {{{"malloc"}, 3}, &MallocChecker::checkKernelMalloc},
411
      {{{"calloc"}, 2}, &MallocChecker::checkCalloc},
412
      {{{"valloc"}, 1}, &MallocChecker::checkBasicAlloc},
413
      {{CDF_MaybeBuiltin, {"strndup"}, 2}, &MallocChecker::checkStrdup},
414
      {{CDF_MaybeBuiltin, {"strdup"}, 1}, &MallocChecker::checkStrdup},
415
      {{{"_strdup"}, 1}, &MallocChecker::checkStrdup},
416
      {{{"kmalloc"}, 2}, &MallocChecker::checkKernelMalloc},
417
      {{{"if_nameindex"}, 1}, &MallocChecker::checkIfNameIndex},
418
      {{CDF_MaybeBuiltin, {"wcsdup"}, 1}, &MallocChecker::checkStrdup},
419
      {{CDF_MaybeBuiltin, {"_wcsdup"}, 1}, &MallocChecker::checkStrdup},
420
      {{{"g_malloc"}, 1}, &MallocChecker::checkBasicAlloc},
421
      {{{"g_malloc0"}, 1}, &MallocChecker::checkGMalloc0},
422
      {{{"g_try_malloc"}, 1}, &MallocChecker::checkBasicAlloc},
423
      {{{"g_try_malloc0"}, 1}, &MallocChecker::checkGMalloc0},
424
      {{{"g_memdup"}, 2}, &MallocChecker::checkGMemdup},
425
      {{{"g_malloc_n"}, 2}, &MallocChecker::checkGMallocN},
426
      {{{"g_malloc0_n"}, 2}, &MallocChecker::checkGMallocN0},
427
      {{{"g_try_malloc_n"}, 2}, &MallocChecker::checkGMallocN},
428
      {{{"g_try_malloc0_n"}, 2}, &MallocChecker::checkGMallocN0},
429
  };
430
431
  CallDescriptionMap<CheckFn> ReallocatingMemFnMap{
432
      {{{"realloc"}, 2},
433
       std::bind(&MallocChecker::checkRealloc, _1, _2, _3, false)},
434
      {{{"reallocf"}, 2},
435
       std::bind(&MallocChecker::checkRealloc, _1, _2, _3, true)},
436
      {{{"g_realloc"}, 2},
437
       std::bind(&MallocChecker::checkRealloc, _1, _2, _3, false)},
438
      {{{"g_try_realloc"}, 2},
439
       std::bind(&MallocChecker::checkRealloc, _1, _2, _3, false)},
440
      {{{"g_realloc_n"}, 3}, &MallocChecker::checkReallocN},
441
      {{{"g_try_realloc_n"}, 3}, &MallocChecker::checkReallocN},
442
  };
443
444
  bool isMemCall(const CallEvent &Call) const;
445
446
  // TODO: Remove mutable by moving the initializtaion to the registry function.
447
  mutable std::optional<uint64_t> KernelZeroFlagVal;
448
449
  using KernelZeroSizePtrValueTy = std::optional<int>;
450
  /// Store the value of macro called `ZERO_SIZE_PTR`.
451
  /// The value is initialized at first use, before first use the outer
452
  /// Optional is empty, afterwards it contains another Optional that indicates
453
  /// if the macro value could be determined, and if yes the value itself.
454
  mutable std::optional<KernelZeroSizePtrValueTy> KernelZeroSizePtrValue;
455
456
  /// Process C++ operator new()'s allocation, which is the part of C++
457
  /// new-expression that goes before the constructor.
458
  [[nodiscard]] ProgramStateRef
459
  processNewAllocation(const CXXAllocatorCall &Call, CheckerContext &C,
460
                       AllocationFamily Family) const;
461
462
  /// Perform a zero-allocation check.
463
  ///
464
  /// \param [in] Call The expression that allocates memory.
465
  /// \param [in] IndexOfSizeArg Index of the argument that specifies the size
466
  ///   of the memory that needs to be allocated. E.g. for malloc, this would be
467
  ///   0.
468
  /// \param [in] RetVal Specifies the newly allocated pointer value;
469
  ///   if unspecified, the value of expression \p E is used.
470
  [[nodiscard]] static ProgramStateRef
471
  ProcessZeroAllocCheck(const CallEvent &Call, const unsigned IndexOfSizeArg,
472
                        ProgramStateRef State,
473
                        std::optional<SVal> RetVal = std::nullopt);
474
475
  /// Model functions with the ownership_returns attribute.
476
  ///
477
  /// User-defined function may have the ownership_returns attribute, which
478
  /// annotates that the function returns with an object that was allocated on
479
  /// the heap, and passes the ownertship to the callee.
480
  ///
481
  ///   void __attribute((ownership_returns(malloc, 1))) *my_malloc(size_t);
482
  ///
483
  /// It has two parameters:
484
  ///   - first: name of the resource (e.g. 'malloc')
485
  ///   - (OPTIONAL) second: size of the allocated region
486
  ///
487
  /// \param [in] Call The expression that allocates memory.
488
  /// \param [in] Att The ownership_returns attribute.
489
  /// \param [in] State The \c ProgramState right before allocation.
490
  /// \returns The ProgramState right after allocation.
491
  [[nodiscard]] ProgramStateRef
492
  MallocMemReturnsAttr(CheckerContext &C, const CallEvent &Call,
493
                       const OwnershipAttr *Att, ProgramStateRef State) const;
494
495
  /// Models memory allocation.
496
  ///
497
  /// \param [in] Call The expression that allocates memory.
498
  /// \param [in] SizeEx Size of the memory that needs to be allocated.
499
  /// \param [in] Init The value the allocated memory needs to be initialized.
500
  /// with. For example, \c calloc initializes the allocated memory to 0,
501
  /// malloc leaves it undefined.
502
  /// \param [in] State The \c ProgramState right before allocation.
503
  /// \returns The ProgramState right after allocation.
504
  [[nodiscard]] static ProgramStateRef
505
  MallocMemAux(CheckerContext &C, const CallEvent &Call, const Expr *SizeEx,
506
               SVal Init, ProgramStateRef State, AllocationFamily Family);
507
508
  /// Models memory allocation.
509
  ///
510
  /// \param [in] Call The expression that allocates memory.
511
  /// \param [in] Size Size of the memory that needs to be allocated.
512
  /// \param [in] Init The value the allocated memory needs to be initialized.
513
  /// with. For example, \c calloc initializes the allocated memory to 0,
514
  /// malloc leaves it undefined.
515
  /// \param [in] State The \c ProgramState right before allocation.
516
  /// \returns The ProgramState right after allocation.
517
  [[nodiscard]] static ProgramStateRef
518
  MallocMemAux(CheckerContext &C, const CallEvent &Call, SVal Size, SVal Init,
519
               ProgramStateRef State, AllocationFamily Family);
520
521
  // Check if this malloc() for special flags. At present that means M_ZERO or
522
  // __GFP_ZERO (in which case, treat it like calloc).
523
  [[nodiscard]] std::optional<ProgramStateRef>
524
  performKernelMalloc(const CallEvent &Call, CheckerContext &C,
525
                      const ProgramStateRef &State) const;
526
527
  /// Model functions with the ownership_takes and ownership_holds attributes.
528
  ///
529
  /// User-defined function may have the ownership_takes and/or ownership_holds
530
  /// attributes, which annotates that the function frees the memory passed as a
531
  /// parameter.
532
  ///
533
  ///   void __attribute((ownership_takes(malloc, 1))) my_free(void *);
534
  ///   void __attribute((ownership_holds(malloc, 1))) my_hold(void *);
535
  ///
536
  /// They have two parameters:
537
  ///   - first: name of the resource (e.g. 'malloc')
538
  ///   - second: index of the parameter the attribute applies to
539
  ///
540
  /// \param [in] Call The expression that frees memory.
541
  /// \param [in] Att The ownership_takes or ownership_holds attribute.
542
  /// \param [in] State The \c ProgramState right before allocation.
543
  /// \returns The ProgramState right after deallocation.
544
  [[nodiscard]] ProgramStateRef FreeMemAttr(CheckerContext &C,
545
                                            const CallEvent &Call,
546
                                            const OwnershipAttr *Att,
547
                                            ProgramStateRef State) const;
548
549
  /// Models memory deallocation.
550
  ///
551
  /// \param [in] Call The expression that frees memory.
552
  /// \param [in] State The \c ProgramState right before allocation.
553
  /// \param [in] Num Index of the argument that needs to be freed. This is
554
  ///   normally 0, but for custom free functions it may be different.
555
  /// \param [in] Hold Whether the parameter at \p Index has the ownership_holds
556
  ///   attribute.
557
  /// \param [out] IsKnownToBeAllocated Whether the memory to be freed is known
558
  ///   to have been allocated, or in other words, the symbol to be freed was
559
  ///   registered as allocated by this checker. In the following case, \c ptr
560
  ///   isn't known to be allocated.
561
  ///      void Haha(int *ptr) {
562
  ///        ptr = realloc(ptr, 67);
563
  ///        // ...
564
  ///      }
565
  /// \param [in] ReturnsNullOnFailure Whether the memory deallocation function
566
  ///   we're modeling returns with Null on failure.
567
  /// \returns The ProgramState right after deallocation.
568
  [[nodiscard]] ProgramStateRef
569
  FreeMemAux(CheckerContext &C, const CallEvent &Call, ProgramStateRef State,
570
             unsigned Num, bool Hold, bool &IsKnownToBeAllocated,
571
             AllocationFamily Family, bool ReturnsNullOnFailure = false) const;
572
573
  /// Models memory deallocation.
574
  ///
575
  /// \param [in] ArgExpr The variable who's pointee needs to be freed.
576
  /// \param [in] Call The expression that frees the memory.
577
  /// \param [in] State The \c ProgramState right before allocation.
578
  ///   normally 0, but for custom free functions it may be different.
579
  /// \param [in] Hold Whether the parameter at \p Index has the ownership_holds
580
  ///   attribute.
581
  /// \param [out] IsKnownToBeAllocated Whether the memory to be freed is known
582
  ///   to have been allocated, or in other words, the symbol to be freed was
583
  ///   registered as allocated by this checker. In the following case, \c ptr
584
  ///   isn't known to be allocated.
585
  ///      void Haha(int *ptr) {
586
  ///        ptr = realloc(ptr, 67);
587
  ///        // ...
588
  ///      }
589
  /// \param [in] ReturnsNullOnFailure Whether the memory deallocation function
590
  ///   we're modeling returns with Null on failure.
591
  /// \returns The ProgramState right after deallocation.
592
  [[nodiscard]] ProgramStateRef
593
  FreeMemAux(CheckerContext &C, const Expr *ArgExpr, const CallEvent &Call,
594
             ProgramStateRef State, bool Hold, bool &IsKnownToBeAllocated,
595
             AllocationFamily Family, bool ReturnsNullOnFailure = false) const;
596
597
  // TODO: Needs some refactoring, as all other deallocation modeling
598
  // functions are suffering from out parameters and messy code due to how
599
  // realloc is handled.
600
  //
601
  /// Models memory reallocation.
602
  ///
603
  /// \param [in] Call The expression that reallocated memory
604
  /// \param [in] ShouldFreeOnFail Whether if reallocation fails, the supplied
605
  ///   memory should be freed.
606
  /// \param [in] State The \c ProgramState right before reallocation.
607
  /// \param [in] SuffixWithN Whether the reallocation function we're modeling
608
  ///   has an '_n' suffix, such as g_realloc_n.
609
  /// \returns The ProgramState right after reallocation.
610
  [[nodiscard]] ProgramStateRef
611
  ReallocMemAux(CheckerContext &C, const CallEvent &Call, bool ShouldFreeOnFail,
612
                ProgramStateRef State, AllocationFamily Family,
613
                bool SuffixWithN = false) const;
614
615
  /// Evaluates the buffer size that needs to be allocated.
616
  ///
617
  /// \param [in] Blocks The amount of blocks that needs to be allocated.
618
  /// \param [in] BlockBytes The size of a block.
619
  /// \returns The symbolic value of \p Blocks * \p BlockBytes.
620
  [[nodiscard]] static SVal evalMulForBufferSize(CheckerContext &C,
621
                                                 const Expr *Blocks,
622
                                                 const Expr *BlockBytes);
623
624
  /// Models zero initialized array allocation.
625
  ///
626
  /// \param [in] Call The expression that reallocated memory
627
  /// \param [in] State The \c ProgramState right before reallocation.
628
  /// \returns The ProgramState right after allocation.
629
  [[nodiscard]] static ProgramStateRef
630
  CallocMem(CheckerContext &C, const CallEvent &Call, ProgramStateRef State);
631
632
  /// See if deallocation happens in a suspicious context. If so, escape the
633
  /// pointers that otherwise would have been deallocated and return true.
634
  bool suppressDeallocationsInSuspiciousContexts(const CallEvent &Call,
635
                                                 CheckerContext &C) const;
636
637
  /// If in \p S  \p Sym is used, check whether \p Sym was already freed.
638
  bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const;
639
640
  /// If in \p S \p Sym is used, check whether \p Sym was allocated as a zero
641
  /// sized memory region.
642
  void checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C,
643
                             const Stmt *S) const;
644
645
  /// If in \p S \p Sym is being freed, check whether \p Sym was already freed.
646
  bool checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const;
647
648
  /// Check if the function is known to free memory, or if it is
649
  /// "interesting" and should be modeled explicitly.
650
  ///
651
  /// \param [out] EscapingSymbol A function might not free memory in general,
652
  ///   but could be known to free a particular symbol. In this case, false is
653
  ///   returned and the single escaping symbol is returned through the out
654
  ///   parameter.
655
  ///
656
  /// We assume that pointers do not escape through calls to system functions
657
  /// not handled by this checker.
658
  bool mayFreeAnyEscapedMemoryOrIsModeledExplicitly(const CallEvent *Call,
659
                                   ProgramStateRef State,
660
                                   SymbolRef &EscapingSymbol) const;
661
662
  /// Implementation of the checkPointerEscape callbacks.
663
  [[nodiscard]] ProgramStateRef
664
  checkPointerEscapeAux(ProgramStateRef State,
665
                        const InvalidatedSymbols &Escaped,
666
                        const CallEvent *Call, PointerEscapeKind Kind,
667
                        bool IsConstPointerEscape) const;
668
669
  // Implementation of the checkPreStmt and checkEndFunction callbacks.
670
  void checkEscapeOnReturn(const ReturnStmt *S, CheckerContext &C) const;
671
672
  ///@{
673
  /// Tells if a given family/call/symbol is tracked by the current checker.
674
  /// Sets CheckKind to the kind of the checker responsible for this
675
  /// family/call/symbol.
676
  std::optional<CheckKind> getCheckIfTracked(AllocationFamily Family,
677
                                             bool IsALeakCheck = false) const;
678
679
  std::optional<CheckKind> getCheckIfTracked(CheckerContext &C, SymbolRef Sym,
680
                                             bool IsALeakCheck = false) const;
681
  ///@}
682
  static bool SummarizeValue(raw_ostream &os, SVal V);
683
  static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
684
685
  void HandleNonHeapDealloc(CheckerContext &C, SVal ArgVal, SourceRange Range,
686
                            const Expr *DeallocExpr,
687
                            AllocationFamily Family) const;
688
689
  void HandleFreeAlloca(CheckerContext &C, SVal ArgVal,
690
                        SourceRange Range) const;
691
692
  void HandleMismatchedDealloc(CheckerContext &C, SourceRange Range,
693
                               const Expr *DeallocExpr, const RefState *RS,
694
                               SymbolRef Sym, bool OwnershipTransferred) const;
695
696
  void HandleOffsetFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
697
                        const Expr *DeallocExpr, AllocationFamily Family,
698
                        const Expr *AllocExpr = nullptr) const;
699
700
  void HandleUseAfterFree(CheckerContext &C, SourceRange Range,
701
                          SymbolRef Sym) const;
702
703
  void HandleDoubleFree(CheckerContext &C, SourceRange Range, bool Released,
704
                        SymbolRef Sym, SymbolRef PrevSym) const;
705
706
  void HandleDoubleDelete(CheckerContext &C, SymbolRef Sym) const;
707
708
  void HandleUseZeroAlloc(CheckerContext &C, SourceRange Range,
709
                          SymbolRef Sym) const;
710
711
  void HandleFunctionPtrFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
712
                             const Expr *FreeExpr,
713
                             AllocationFamily Family) const;
714
715
  /// Find the location of the allocation for Sym on the path leading to the
716
  /// exploded node N.
717
  static LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
718
                                    CheckerContext &C);
719
720
  void HandleLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const;
721
722
  /// Test if value in ArgVal equals to value in macro `ZERO_SIZE_PTR`.
723
  bool isArgZERO_SIZE_PTR(ProgramStateRef State, CheckerContext &C,
724
                          SVal ArgVal) const;
725
};
726
} // end anonymous namespace
727
728
//===----------------------------------------------------------------------===//
729
// Definition of NoOwnershipChangeVisitor.
730
//===----------------------------------------------------------------------===//
731
732
namespace {
733
class NoOwnershipChangeVisitor final : public NoStateChangeFuncVisitor {
734
  // The symbol whose (lack of) ownership change we are interested in.
735
  SymbolRef Sym;
736
  const MallocChecker &Checker;
737
  using OwnerSet = llvm::SmallPtrSet<const MemRegion *, 8>;
738
739
  // Collect which entities point to the allocated memory, and could be
740
  // responsible for deallocating it.
741
  class OwnershipBindingsHandler : public StoreManager::BindingsHandler {
742
    SymbolRef Sym;
743
    OwnerSet &Owners;
744
745
  public:
746
    OwnershipBindingsHandler(SymbolRef Sym, OwnerSet &Owners)
747
8
        : Sym(Sym), Owners(Owners) {}
748
749
    bool HandleBinding(StoreManager &SMgr, Store Store, const MemRegion *Region,
750
12
                       SVal Val) override {
751
12
      if (Val.getAsSymbol() == Sym)
752
5
        Owners.insert(Region);
753
12
      return true;
754
12
    }
755
756
0
    LLVM_DUMP_METHOD void dump() const { dumpToStream(llvm::errs()); }
757
0
    LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &out) const {
758
0
      out << "Owners: {\n";
759
0
      for (const MemRegion *Owner : Owners) {
760
0
        out << "  ";
761
0
        Owner->dumpToStream(out);
762
0
        out << ",\n";
763
0
      }
764
0
      out << "}\n";
765
0
    }
766
  };
767
768
protected:
769
8
  OwnerSet getOwnersAtNode(const ExplodedNode *N) {
770
8
    OwnerSet Ret;
771
772
8
    ProgramStateRef State = N->getState();
773
8
    OwnershipBindingsHandler Handler{Sym, Ret};
774
8
    State->getStateManager().getStoreManager().iterBindings(State->getStore(),
775
8
                                                            Handler);
776
8
    return Ret;
777
8
  }
778
779
  LLVM_DUMP_METHOD static std::string
780
0
  getFunctionName(const ExplodedNode *CallEnterN) {
781
0
    if (const CallExpr *CE = llvm::dyn_cast_or_null<CallExpr>(
782
0
            CallEnterN->getLocationAs<CallEnter>()->getCallExpr()))
783
0
      if (const FunctionDecl *FD = CE->getDirectCallee())
784
0
        return FD->getQualifiedNameAsString();
785
0
    return "";
786
0
  }
787
788
  /// Syntactically checks whether the callee is a deallocating function. Since
789
  /// we have no path-sensitive information on this call (we would need a
790
  /// CallEvent instead of a CallExpr for that), its possible that a
791
  /// deallocation function was called indirectly through a function pointer,
792
  /// but we are not able to tell, so this is a best effort analysis.
793
  /// See namespace `memory_passed_to_fn_call_free_through_fn_ptr` in
794
  /// clang/test/Analysis/NewDeleteLeaks.cpp.
795
40
  bool isFreeingCallAsWritten(const CallExpr &Call) const {
796
40
    if (Checker.FreeingMemFnMap.lookupAsWritten(Call) ||
797
40
        
Checker.ReallocatingMemFnMap.lookupAsWritten(Call)38
)
798
3
      return true;
799
800
37
    if (const auto *Func =
801
37
            llvm::dyn_cast_or_null<FunctionDecl>(Call.getCalleeDecl()))
802
36
      return MallocChecker::isFreeingOwnershipAttrCall(Func);
803
804
1
    return false;
805
37
  }
806
807
  /// Heuristically guess whether the callee intended to free memory. This is
808
  /// done syntactically, because we are trying to argue about alternative
809
  /// paths of execution, and as a consequence we don't have path-sensitive
810
  /// information.
811
88
  bool doesFnIntendToHandleOwnership(const Decl *Callee, ASTContext &ACtx) {
812
88
    using namespace clang::ast_matchers;
813
88
    const FunctionDecl *FD = dyn_cast<FunctionDecl>(Callee);
814
815
    // Given that the stack frame was entered, the body should always be
816
    // theoretically obtainable. In case of body farms, the synthesized body
817
    // is not attached to declaration, thus triggering the '!FD->hasBody()'
818
    // branch. That said, would a synthesized body ever intend to handle
819
    // ownership? As of today they don't. And if they did, how would we
820
    // put notes inside it, given that it doesn't match any source locations?
821
88
    if (!FD || 
!FD->hasBody()86
)
822
7
      return false;
823
824
81
    auto Matches = match(findAll(stmt(anyOf(cxxDeleteExpr().bind("delete"),
825
81
                                            callExpr().bind("call")))),
826
81
                         *FD->getBody(), ACtx);
827
81
    for (BoundNodes Match : Matches) {
828
43
      if (Match.getNodeAs<CXXDeleteExpr>("delete"))
829
3
        return true;
830
831
40
      if (const auto *Call = Match.getNodeAs<CallExpr>("call"))
832
40
        if (isFreeingCallAsWritten(*Call))
833
3
          return true;
834
40
    }
835
    // TODO: Ownership might change with an attempt to store the allocated
836
    // memory, not only through deallocation. Check for attempted stores as
837
    // well.
838
75
    return false;
839
81
  }
840
841
  bool wasModifiedInFunction(const ExplodedNode *CallEnterN,
842
88
                             const ExplodedNode *CallExitEndN) override {
843
88
    if (!doesFnIntendToHandleOwnership(
844
88
            CallExitEndN->getFirstPred()->getLocationContext()->getDecl(),
845
88
            CallExitEndN->getState()->getAnalysisManager().getASTContext()))
846
82
      return true;
847
848
6
    if (CallEnterN->getState()->get<RegionState>(Sym) !=
849
6
        CallExitEndN->getState()->get<RegionState>(Sym))
850
2
      return true;
851
852
4
    OwnerSet CurrOwners = getOwnersAtNode(CallEnterN);
853
4
    OwnerSet ExitOwners = getOwnersAtNode(CallExitEndN);
854
855
    // Owners in the current set may be purged from the analyzer later on.
856
    // If a variable is dead (is not referenced directly or indirectly after
857
    // some point), it will be removed from the Store before the end of its
858
    // actual lifetime.
859
    // This means that if the ownership status didn't change, CurrOwners
860
    // must be a superset of, but not necessarily equal to ExitOwners.
861
4
    return !llvm::set_is_subset(ExitOwners, CurrOwners);
862
6
  }
863
864
3
  static PathDiagnosticPieceRef emitNote(const ExplodedNode *N) {
865
3
    PathDiagnosticLocation L = PathDiagnosticLocation::create(
866
3
        N->getLocation(),
867
3
        N->getState()->getStateManager().getContext().getSourceManager());
868
3
    return std::make_shared<PathDiagnosticEventPiece>(
869
3
        L, "Returning without deallocating memory or storing the pointer for "
870
3
           "later deallocation");
871
3
  }
872
873
  PathDiagnosticPieceRef
874
  maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R,
875
                           const ObjCMethodCall &Call,
876
0
                           const ExplodedNode *N) override {
877
    // TODO: Implement.
878
0
    return nullptr;
879
0
  }
880
881
  PathDiagnosticPieceRef
882
  maybeEmitNoteForCXXThis(PathSensitiveBugReport &R,
883
                          const CXXConstructorCall &Call,
884
0
                          const ExplodedNode *N) override {
885
    // TODO: Implement.
886
0
    return nullptr;
887
0
  }
888
889
  PathDiagnosticPieceRef
890
  maybeEmitNoteForParameters(PathSensitiveBugReport &R, const CallEvent &Call,
891
5
                             const ExplodedNode *N) override {
892
    // TODO: Factor the logic of "what constitutes as an entity being passed
893
    // into a function call" out by reusing the code in
894
    // NoStoreFuncVisitor::maybeEmitNoteForParameters, maybe by incorporating
895
    // the printing technology in UninitializedObject's FieldChainInfo.
896
5
    ArrayRef<ParmVarDecl *> Parameters = Call.parameters();
897
6
    for (unsigned I = 0; I < Call.getNumArgs() && 
I < Parameters.size()4
;
++I1
) {
898
4
      SVal V = Call.getArgSVal(I);
899
4
      if (V.getAsSymbol() == Sym)
900
3
        return emitNote(N);
901
4
    }
902
2
    return nullptr;
903
5
  }
904
905
public:
906
  NoOwnershipChangeVisitor(SymbolRef Sym, const MallocChecker *Checker)
907
268
      : NoStateChangeFuncVisitor(bugreporter::TrackingKind::Thorough), Sym(Sym),
908
268
        Checker(*Checker) {}
909
910
268
  void Profile(llvm::FoldingSetNodeID &ID) const override {
911
268
    static int Tag = 0;
912
268
    ID.AddPointer(&Tag);
913
268
    ID.AddPointer(Sym);
914
268
  }
915
};
916
917
} // end anonymous namespace
918
919
//===----------------------------------------------------------------------===//
920
// Definition of MallocBugVisitor.
921
//===----------------------------------------------------------------------===//
922
923
namespace {
924
/// The bug visitor which allows us to print extra diagnostics along the
925
/// BugReport path. For example, showing the allocation site of the leaked
926
/// region.
927
class MallocBugVisitor final : public BugReporterVisitor {
928
protected:
929
  enum NotificationMode { Normal, ReallocationFailed };
930
931
  // The allocated region symbol tracked by the main analysis.
932
  SymbolRef Sym;
933
934
  // The mode we are in, i.e. what kind of diagnostics will be emitted.
935
  NotificationMode Mode;
936
937
  // A symbol from when the primary region should have been reallocated.
938
  SymbolRef FailedReallocSymbol;
939
940
  // A C++ destructor stack frame in which memory was released. Used for
941
  // miscellaneous false positive suppression.
942
  const StackFrameContext *ReleaseDestructorLC;
943
944
  bool IsLeak;
945
946
public:
947
  MallocBugVisitor(SymbolRef S, bool isLeak = false)
948
544
      : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr),
949
544
        ReleaseDestructorLC(nullptr), IsLeak(isLeak) {}
950
951
552
  static void *getTag() {
952
552
    static int Tag = 0;
953
552
    return &Tag;
954
552
  }
955
956
544
  void Profile(llvm::FoldingSetNodeID &ID) const override {
957
544
    ID.AddPointer(getTag());
958
544
    ID.AddPointer(Sym);
959
544
  }
960
961
  /// Did not track -> allocated. Other state (released) -> allocated.
962
  static inline bool isAllocated(const RefState *RSCurr, const RefState *RSPrev,
963
24.5k
                                 const Stmt *Stmt) {
964
24.5k
    return (isa_and_nonnull<CallExpr, CXXNewExpr>(Stmt) &&
965
24.5k
            
(4.36k
RSCurr4.36k
&&
966
4.36k
             
(2.04k
RSCurr->isAllocated()2.04k
||
RSCurr->isAllocatedOfSizeZero()452
)) &&
967
24.5k
            
(1.66k
!RSPrev1.66k
||
968
1.66k
             
!(1.23k
RSPrev->isAllocated()1.23k
||
RSPrev->isAllocatedOfSizeZero()28
)));
969
24.5k
  }
970
971
  /// Did not track -> released. Other state (allocated) -> released.
972
  /// The statement associated with the release might be missing.
973
  static inline bool isReleased(const RefState *RSCurr, const RefState *RSPrev,
974
24.0k
                                const Stmt *Stmt) {
975
24.0k
    bool IsReleased =
976
24.0k
        (RSCurr && 
RSCurr->isReleased()13.4k
) &&
(2.17k
!RSPrev2.17k
||
!RSPrev->isReleased()2.10k
);
977
24.0k
    assert(!IsReleased || (isa_and_nonnull<CallExpr, CXXDeleteExpr>(Stmt)) ||
978
24.0k
           (!Stmt && RSCurr->getAllocationFamily() == AF_InnerBuffer));
979
24.0k
    return IsReleased;
980
24.0k
  }
981
982
  /// Did not track -> relinquished. Other state (allocated) -> relinquished.
983
  static inline bool isRelinquished(const RefState *RSCurr,
984
23.8k
                                    const RefState *RSPrev, const Stmt *Stmt) {
985
23.8k
    return (
986
23.8k
        isa_and_nonnull<CallExpr, ObjCMessageExpr, ObjCPropertyRefExpr>(Stmt) &&
987
23.8k
        
(2.80k
RSCurr2.80k
&&
RSCurr->isRelinquished()1.16k
) &&
988
23.8k
        
(18
!RSPrev18
||
!RSPrev->isRelinquished()17
));
989
23.8k
  }
990
991
  /// If the expression is not a call, and the state change is
992
  /// released -> allocated, it must be the realloc return value
993
  /// check. If we have to handle more cases here, it might be cleaner just
994
  /// to track this extra bit in the state itself.
995
  static inline bool hasReallocFailed(const RefState *RSCurr,
996
                                      const RefState *RSPrev,
997
23.8k
                                      const Stmt *Stmt) {
998
23.8k
    return ((!isa_and_nonnull<CallExpr>(Stmt)) &&
999
23.8k
            
(21.1k
RSCurr21.1k
&&
1000
21.1k
             
(12.1k
RSCurr->isAllocated()12.1k
||
RSCurr->isAllocatedOfSizeZero()2.42k
)) &&
1001
23.8k
            
(10.1k
RSPrev10.1k
&&
1002
10.1k
             !(RSPrev->isAllocated() || 
RSPrev->isAllocatedOfSizeZero()446
)));
1003
23.8k
  }
1004
1005
  PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
1006
                                   BugReporterContext &BRC,
1007
                                   PathSensitiveBugReport &BR) override;
1008
1009
  PathDiagnosticPieceRef getEndPath(BugReporterContext &BRC,
1010
                                    const ExplodedNode *EndPathNode,
1011
506
                                    PathSensitiveBugReport &BR) override {
1012
506
    if (!IsLeak)
1013
254
      return nullptr;
1014
1015
252
    PathDiagnosticLocation L = BR.getLocation();
1016
    // Do not add the statement itself as a range in case of leak.
1017
252
    return std::make_shared<PathDiagnosticEventPiece>(L, BR.getDescription(),
1018
252
                                                      false);
1019
506
  }
1020
1021
private:
1022
  class StackHintGeneratorForReallocationFailed
1023
      : public StackHintGeneratorForSymbol {
1024
  public:
1025
    StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M)
1026
6
        : StackHintGeneratorForSymbol(S, M) {}
1027
1028
1
    std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex) override {
1029
      // Printed parameters start at 1, not 0.
1030
1
      ++ArgIndex;
1031
1032
1
      SmallString<200> buf;
1033
1
      llvm::raw_svector_ostream os(buf);
1034
1035
1
      os << "Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex)
1036
1
         << " parameter failed";
1037
1038
1
      return std::string(os.str());
1039
1
    }
1040
1041
0
    std::string getMessageForReturn(const CallExpr *CallExpr) override {
1042
0
      return "Reallocation of returned value failed";
1043
0
    }
1044
  };
1045
};
1046
} // end anonymous namespace
1047
1048
// A map from the freed symbol to the symbol representing the return value of
1049
// the free function.
1050
REGISTER_MAP_WITH_PROGRAMSTATE(FreeReturnValue, SymbolRef, SymbolRef)
1051
1052
namespace {
1053
class StopTrackingCallback final : public SymbolVisitor {
1054
  ProgramStateRef state;
1055
1056
public:
1057
5
  StopTrackingCallback(ProgramStateRef st) : state(std::move(st)) {}
1058
5
  ProgramStateRef getState() const { return state; }
1059
1060
1
  bool VisitSymbol(SymbolRef sym) override {
1061
1
    state = state->remove<RegionState>(sym);
1062
1
    return true;
1063
1
  }
1064
};
1065
} // end anonymous namespace
1066
1067
30.8k
static bool isStandardNewDelete(const FunctionDecl *FD) {
1068
30.8k
  if (!FD)
1069
0
    return false;
1070
1071
30.8k
  OverloadedOperatorKind Kind = FD->getOverloadedOperator();
1072
30.8k
  if (Kind != OO_New && 
Kind != OO_Array_New29.8k
&&
Kind != OO_Delete29.6k
&&
1073
30.8k
      
Kind != OO_Array_Delete29.0k
)
1074
28.9k
    return false;
1075
1076
  // This is standard if and only if it's not defined in a user file.
1077
1.86k
  SourceLocation L = FD->getLocation();
1078
  // If the header for operator delete is not included, it's still defined
1079
  // in an invalid source location. Check to make sure we don't crash.
1080
1.86k
  return !L.isValid() ||
1081
1.86k
         
FD->getASTContext().getSourceManager().isInSystemHeader(L)1.21k
;
1082
30.8k
}
1083
1084
//===----------------------------------------------------------------------===//
1085
// Methods of MallocChecker and MallocBugVisitor.
1086
//===----------------------------------------------------------------------===//
1087
1088
8.92k
bool MallocChecker::isFreeingOwnershipAttrCall(const FunctionDecl *Func) {
1089
8.92k
  if (Func->hasAttrs()) {
1090
2.26k
    for (const auto *I : Func->specific_attrs<OwnershipAttr>()) {
1091
45
      OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind();
1092
45
      if (OwnKind == OwnershipAttr::Takes || 
OwnKind == OwnershipAttr::Holds39
)
1093
14
        return true;
1094
45
    }
1095
2.26k
  }
1096
8.90k
  return false;
1097
8.92k
}
1098
1099
9.57k
bool MallocChecker::isFreeingCall(const CallEvent &Call) const {
1100
9.57k
  if (FreeingMemFnMap.lookup(Call) || 
ReallocatingMemFnMap.lookup(Call)9.04k
)
1101
693
    return true;
1102
1103
8.88k
  if (const auto *Func = dyn_cast_or_null<FunctionDecl>(Call.getDecl()))
1104
8.88k
    return isFreeingOwnershipAttrCall(Func);
1105
1106
0
  return false;
1107
8.88k
}
1108
1109
1.04k
bool MallocChecker::isMemCall(const CallEvent &Call) const {
1110
1.04k
  if (FreeingMemFnMap.lookup(Call) || 
AllocatingMemFnMap.lookup(Call)587
||
1111
1.04k
      
ReallocatingMemFnMap.lookup(Call)547
)
1112
584
    return true;
1113
1114
456
  if (!ShouldIncludeOwnershipAnnotatedFunctions)
1115
448
    return false;
1116
1117
8
  const auto *Func = dyn_cast<FunctionDecl>(Call.getDecl());
1118
8
  return Func && Func->hasAttr<OwnershipAttr>();
1119
456
}
1120
1121
std::optional<ProgramStateRef>
1122
MallocChecker::performKernelMalloc(const CallEvent &Call, CheckerContext &C,
1123
7
                                   const ProgramStateRef &State) const {
1124
  // 3-argument malloc(), as commonly used in {Free,Net,Open}BSD Kernels:
1125
  //
1126
  // void *malloc(unsigned long size, struct malloc_type *mtp, int flags);
1127
  //
1128
  // One of the possible flags is M_ZERO, which means 'give me back an
1129
  // allocation which is already zeroed', like calloc.
1130
1131
  // 2-argument kmalloc(), as used in the Linux kernel:
1132
  //
1133
  // void *kmalloc(size_t size, gfp_t flags);
1134
  //
1135
  // Has the similar flag value __GFP_ZERO.
1136
1137
  // This logic is largely cloned from O_CREAT in UnixAPIChecker, maybe some
1138
  // code could be shared.
1139
1140
7
  ASTContext &Ctx = C.getASTContext();
1141
7
  llvm::Triple::OSType OS = Ctx.getTargetInfo().getTriple().getOS();
1142
1143
7
  if (!KernelZeroFlagVal) {
1144
1
    switch (OS) {
1145
0
    case llvm::Triple::FreeBSD:
1146
0
      KernelZeroFlagVal = 0x0100;
1147
0
      break;
1148
0
    case llvm::Triple::NetBSD:
1149
0
      KernelZeroFlagVal = 0x0002;
1150
0
      break;
1151
0
    case llvm::Triple::OpenBSD:
1152
0
      KernelZeroFlagVal = 0x0008;
1153
0
      break;
1154
1
    case llvm::Triple::Linux:
1155
      // __GFP_ZERO
1156
1
      KernelZeroFlagVal = 0x8000;
1157
1
      break;
1158
0
    default:
1159
      // FIXME: We need a more general way of getting the M_ZERO value.
1160
      // See also: O_CREAT in UnixAPIChecker.cpp.
1161
1162
      // Fall back to normal malloc behavior on platforms where we don't
1163
      // know M_ZERO.
1164
0
      return std::nullopt;
1165
1
    }
1166
1
  }
1167
1168
  // We treat the last argument as the flags argument, and callers fall-back to
1169
  // normal malloc on a None return. This works for the FreeBSD kernel malloc
1170
  // as well as Linux kmalloc.
1171
7
  if (Call.getNumArgs() < 2)
1172
0
    return std::nullopt;
1173
1174
7
  const Expr *FlagsEx = Call.getArgExpr(Call.getNumArgs() - 1);
1175
7
  const SVal V = C.getSVal(FlagsEx);
1176
7
  if (!isa<NonLoc>(V)) {
1177
    // The case where 'V' can be a location can only be due to a bad header,
1178
    // so in this case bail out.
1179
0
    return std::nullopt;
1180
0
  }
1181
1182
7
  NonLoc Flags = V.castAs<NonLoc>();
1183
7
  NonLoc ZeroFlag = C.getSValBuilder()
1184
7
                        .makeIntVal(*KernelZeroFlagVal, FlagsEx->getType())
1185
7
                        .castAs<NonLoc>();
1186
7
  SVal MaskedFlagsUC = C.getSValBuilder().evalBinOpNN(State, BO_And,
1187
7
                                                      Flags, ZeroFlag,
1188
7
                                                      FlagsEx->getType());
1189
7
  if (MaskedFlagsUC.isUnknownOrUndef())
1190
0
    return std::nullopt;
1191
7
  DefinedSVal MaskedFlags = MaskedFlagsUC.castAs<DefinedSVal>();
1192
1193
  // Check if maskedFlags is non-zero.
1194
7
  ProgramStateRef TrueState, FalseState;
1195
7
  std::tie(TrueState, FalseState) = State->assume(MaskedFlags);
1196
1197
  // If M_ZERO is set, treat this like calloc (initialized).
1198
7
  if (TrueState && 
!FalseState5
) {
1199
2
    SVal ZeroVal = C.getSValBuilder().makeZeroVal(Ctx.CharTy);
1200
2
    return MallocMemAux(C, Call, Call.getArgExpr(0), ZeroVal, TrueState,
1201
2
                        AF_Malloc);
1202
2
  }
1203
1204
5
  return std::nullopt;
1205
7
}
1206
1207
SVal MallocChecker::evalMulForBufferSize(CheckerContext &C, const Expr *Blocks,
1208
69
                                         const Expr *BlockBytes) {
1209
69
  SValBuilder &SB = C.getSValBuilder();
1210
69
  SVal BlocksVal = C.getSVal(Blocks);
1211
69
  SVal BlockBytesVal = C.getSVal(BlockBytes);
1212
69
  ProgramStateRef State = C.getState();
1213
69
  SVal TotalSize = SB.evalBinOp(State, BO_Mul, BlocksVal, BlockBytesVal,
1214
69
                                SB.getContext().getSizeType());
1215
69
  return TotalSize;
1216
69
}
1217
1218
void MallocChecker::checkBasicAlloc(const CallEvent &Call,
1219
635
                                    CheckerContext &C) const {
1220
635
  ProgramStateRef State = C.getState();
1221
635
  State = MallocMemAux(C, Call, Call.getArgExpr(0), UndefinedVal(), State,
1222
635
                       AF_Malloc);
1223
635
  State = ProcessZeroAllocCheck(Call, 0, State);
1224
635
  C.addTransition(State);
1225
635
}
1226
1227
void MallocChecker::checkKernelMalloc(const CallEvent &Call,
1228
7
                                      CheckerContext &C) const {
1229
7
  ProgramStateRef State = C.getState();
1230
7
  std::optional<ProgramStateRef> MaybeState =
1231
7
      performKernelMalloc(Call, C, State);
1232
7
  if (MaybeState)
1233
2
    State = *MaybeState;
1234
5
  else
1235
5
    State = MallocMemAux(C, Call, Call.getArgExpr(0), UndefinedVal(), State,
1236
5
                         AF_Malloc);
1237
7
  C.addTransition(State);
1238
7
}
1239
1240
92
static bool isStandardRealloc(const CallEvent &Call) {
1241
92
  const FunctionDecl *FD = dyn_cast<FunctionDecl>(Call.getDecl());
1242
92
  assert(FD);
1243
92
  ASTContext &AC = FD->getASTContext();
1244
1245
92
  if (isa<CXXMethodDecl>(FD))
1246
4
    return false;
1247
1248
88
  return FD->getDeclaredReturnType().getDesugaredType(AC) == AC.VoidPtrTy &&
1249
88
         
FD->getParamDecl(0)->getType().getDesugaredType(AC) == AC.VoidPtrTy84
&&
1250
88
         FD->getParamDecl(1)->getType().getDesugaredType(AC) ==
1251
80
             AC.getSizeType();
1252
92
}
1253
1254
16
static bool isGRealloc(const CallEvent &Call) {
1255
16
  const FunctionDecl *FD = dyn_cast<FunctionDecl>(Call.getDecl());
1256
16
  assert(FD);
1257
16
  ASTContext &AC = FD->getASTContext();
1258
1259
16
  if (isa<CXXMethodDecl>(FD))
1260
4
    return false;
1261
1262
12
  return FD->getDeclaredReturnType().getDesugaredType(AC) == AC.VoidPtrTy &&
1263
12
         
FD->getParamDecl(0)->getType().getDesugaredType(AC) == AC.VoidPtrTy8
&&
1264
12
         FD->getParamDecl(1)->getType().getDesugaredType(AC) ==
1265
4
             AC.UnsignedLongTy;
1266
16
}
1267
1268
void MallocChecker::checkRealloc(const CallEvent &Call, CheckerContext &C,
1269
92
                                 bool ShouldFreeOnFail) const {
1270
  // HACK: CallDescription currently recognizes non-standard realloc functions
1271
  // as standard because it doesn't check the type, or wether its a non-method
1272
  // function. This should be solved by making CallDescription smarter.
1273
  // Mind that this came from a bug report, and all other functions suffer from
1274
  // this.
1275
  // https://bugs.llvm.org/show_bug.cgi?id=46253
1276
92
  if (!isStandardRealloc(Call) && 
!isGRealloc(Call)16
)
1277
16
    return;
1278
76
  ProgramStateRef State = C.getState();
1279
76
  State = ReallocMemAux(C, Call, ShouldFreeOnFail, State, AF_Malloc);
1280
76
  State = ProcessZeroAllocCheck(Call, 1, State);
1281
76
  C.addTransition(State);
1282
76
}
1283
1284
void MallocChecker::checkCalloc(const CallEvent &Call,
1285
27
                                CheckerContext &C) const {
1286
27
  ProgramStateRef State = C.getState();
1287
27
  State = CallocMem(C, Call, State);
1288
27
  State = ProcessZeroAllocCheck(Call, 0, State);
1289
27
  State = ProcessZeroAllocCheck(Call, 1, State);
1290
27
  C.addTransition(State);
1291
27
}
1292
1293
567
void MallocChecker::checkFree(const CallEvent &Call, CheckerContext &C) const {
1294
567
  ProgramStateRef State = C.getState();
1295
567
  bool IsKnownToBeAllocatedMemory = false;
1296
567
  if (suppressDeallocationsInSuspiciousContexts(Call, C))
1297
1
    return;
1298
566
  State = FreeMemAux(C, Call, State, 0, false, IsKnownToBeAllocatedMemory,
1299
566
                     AF_Malloc);
1300
566
  C.addTransition(State);
1301
566
}
1302
1303
void MallocChecker::checkAlloca(const CallEvent &Call,
1304
47
                                CheckerContext &C) const {
1305
47
  ProgramStateRef State = C.getState();
1306
47
  State = MallocMemAux(C, Call, Call.getArgExpr(0), UndefinedVal(), State,
1307
47
                       AF_Alloca);
1308
47
  State = ProcessZeroAllocCheck(Call, 0, State);
1309
47
  C.addTransition(State);
1310
47
}
1311
1312
void MallocChecker::checkStrdup(const CallEvent &Call,
1313
88
                                CheckerContext &C) const {
1314
88
  ProgramStateRef State = C.getState();
1315
88
  const auto *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
1316
88
  if (!CE)
1317
0
    return;
1318
88
  State = MallocUpdateRefState(C, CE, State, AF_Malloc);
1319
1320
88
  C.addTransition(State);
1321
88
}
1322
1323
void MallocChecker::checkIfNameIndex(const CallEvent &Call,
1324
0
                                     CheckerContext &C) const {
1325
0
  ProgramStateRef State = C.getState();
1326
  // Should we model this differently? We can allocate a fixed number of
1327
  // elements with zeros in the last one.
1328
0
  State =
1329
0
      MallocMemAux(C, Call, UnknownVal(), UnknownVal(), State, AF_IfNameIndex);
1330
1331
0
  C.addTransition(State);
1332
0
}
1333
1334
void MallocChecker::checkIfFreeNameIndex(const CallEvent &Call,
1335
0
                                         CheckerContext &C) const {
1336
0
  ProgramStateRef State = C.getState();
1337
0
  bool IsKnownToBeAllocatedMemory = false;
1338
0
  State = FreeMemAux(C, Call, State, 0, false, IsKnownToBeAllocatedMemory,
1339
0
                     AF_IfNameIndex);
1340
0
  C.addTransition(State);
1341
0
}
1342
1343
void MallocChecker::checkCXXNewOrCXXDelete(const CallEvent &Call,
1344
871
                                           CheckerContext &C) const {
1345
871
  ProgramStateRef State = C.getState();
1346
871
  bool IsKnownToBeAllocatedMemory = false;
1347
871
  const auto *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
1348
871
  if (!CE)
1349
773
    return;
1350
1351
98
  assert(isStandardNewDelete(Call));
1352
1353
  // Process direct calls to operator new/new[]/delete/delete[] functions
1354
  // as distinct from new/new[]/delete/delete[] expressions that are
1355
  // processed by the checkPostStmt callbacks for CXXNewExpr and
1356
  // CXXDeleteExpr.
1357
98
  const FunctionDecl *FD = C.getCalleeDecl(CE);
1358
98
  switch (FD->getOverloadedOperator()) {
1359
56
  case OO_New:
1360
56
    State =
1361
56
        MallocMemAux(C, Call, CE->getArg(0), UndefinedVal(), State, AF_CXXNew);
1362
56
    State = ProcessZeroAllocCheck(Call, 0, State);
1363
56
    break;
1364
15
  case OO_Array_New:
1365
15
    State = MallocMemAux(C, Call, CE->getArg(0), UndefinedVal(), State,
1366
15
                         AF_CXXNewArray);
1367
15
    State = ProcessZeroAllocCheck(Call, 0, State);
1368
15
    break;
1369
24
  case OO_Delete:
1370
24
    State = FreeMemAux(C, Call, State, 0, false, IsKnownToBeAllocatedMemory,
1371
24
                       AF_CXXNew);
1372
24
    break;
1373
3
  case OO_Array_Delete:
1374
3
    State = FreeMemAux(C, Call, State, 0, false, IsKnownToBeAllocatedMemory,
1375
3
                       AF_CXXNewArray);
1376
3
    break;
1377
0
  default:
1378
0
    llvm_unreachable("not a new/delete operator");
1379
98
  }
1380
1381
98
  C.addTransition(State);
1382
98
}
1383
1384
void MallocChecker::checkGMalloc0(const CallEvent &Call,
1385
15
                                  CheckerContext &C) const {
1386
15
  ProgramStateRef State = C.getState();
1387
15
  SValBuilder &svalBuilder = C.getSValBuilder();
1388
15
  SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
1389
15
  State = MallocMemAux(C, Call, Call.getArgExpr(0), zeroVal, State, AF_Malloc);
1390
15
  State = ProcessZeroAllocCheck(Call, 0, State);
1391
15
  C.addTransition(State);
1392
15
}
1393
1394
void MallocChecker::checkGMemdup(const CallEvent &Call,
1395
1
                                 CheckerContext &C) const {
1396
1
  ProgramStateRef State = C.getState();
1397
1
  State =
1398
1
      MallocMemAux(C, Call, Call.getArgExpr(1), UnknownVal(), State, AF_Malloc);
1399
1
  State = ProcessZeroAllocCheck(Call, 1, State);
1400
1
  C.addTransition(State);
1401
1
}
1402
1403
void MallocChecker::checkGMallocN(const CallEvent &Call,
1404
14
                                  CheckerContext &C) const {
1405
14
  ProgramStateRef State = C.getState();
1406
14
  SVal Init = UndefinedVal();
1407
14
  SVal TotalSize = evalMulForBufferSize(C, Call.getArgExpr(0), Call.getArgExpr(1));
1408
14
  State = MallocMemAux(C, Call, TotalSize, Init, State, AF_Malloc);
1409
14
  State = ProcessZeroAllocCheck(Call, 0, State);
1410
14
  State = ProcessZeroAllocCheck(Call, 1, State);
1411
14
  C.addTransition(State);
1412
14
}
1413
1414
void MallocChecker::checkGMallocN0(const CallEvent &Call,
1415
14
                                   CheckerContext &C) const {
1416
14
  ProgramStateRef State = C.getState();
1417
14
  SValBuilder &SB = C.getSValBuilder();
1418
14
  SVal Init = SB.makeZeroVal(SB.getContext().CharTy);
1419
14
  SVal TotalSize = evalMulForBufferSize(C, Call.getArgExpr(0), Call.getArgExpr(1));
1420
14
  State = MallocMemAux(C, Call, TotalSize, Init, State, AF_Malloc);
1421
14
  State = ProcessZeroAllocCheck(Call, 0, State);
1422
14
  State = ProcessZeroAllocCheck(Call, 1, State);
1423
14
  C.addTransition(State);
1424
14
}
1425
1426
void MallocChecker::checkReallocN(const CallEvent &Call,
1427
14
                                  CheckerContext &C) const {
1428
14
  ProgramStateRef State = C.getState();
1429
14
  State = ReallocMemAux(C, Call, /*ShouldFreeOnFail=*/false, State, AF_Malloc,
1430
14
                        /*SuffixWithN=*/true);
1431
14
  State = ProcessZeroAllocCheck(Call, 1, State);
1432
14
  State = ProcessZeroAllocCheck(Call, 2, State);
1433
14
  C.addTransition(State);
1434
14
}
1435
1436
void MallocChecker::checkOwnershipAttr(const CallEvent &Call,
1437
29.0k
                                       CheckerContext &C) const {
1438
29.0k
  ProgramStateRef State = C.getState();
1439
29.0k
  const auto *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
1440
29.0k
  if (!CE)
1441
6.64k
    return;
1442
22.4k
  const FunctionDecl *FD = C.getCalleeDecl(CE);
1443
22.4k
  if (!FD)
1444
11
    return;
1445
22.4k
  if (ShouldIncludeOwnershipAnnotatedFunctions ||
1446
22.4k
      
ChecksEnabled[CK_MismatchedDeallocatorChecker]22.3k
) {
1447
    // Check all the attributes, if there are any.
1448
    // There can be multiple of these attributes.
1449
889
    if (FD->hasAttrs())
1450
97
      for (const auto *I : FD->specific_attrs<OwnershipAttr>()) {
1451
49
        switch (I->getOwnKind()) {
1452
33
        case OwnershipAttr::Returns:
1453
33
          State = MallocMemReturnsAttr(C, Call, I, State);
1454
33
          break;
1455
6
        case OwnershipAttr::Takes:
1456
16
        case OwnershipAttr::Holds:
1457
16
          State = FreeMemAttr(C, Call, I, State);
1458
16
          break;
1459
49
        }
1460
49
      }
1461
889
  }
1462
22.4k
  C.addTransition(State);
1463
22.4k
}
1464
1465
void MallocChecker::checkPostCall(const CallEvent &Call,
1466
45.4k
                                  CheckerContext &C) const {
1467
45.4k
  if (C.wasInlined)
1468
13.6k
    return;
1469
31.7k
  if (!Call.getOriginExpr())
1470
312
    return;
1471
1472
31.4k
  ProgramStateRef State = C.getState();
1473
1474
31.4k
  if (const CheckFn *Callback = FreeingMemFnMap.lookup(Call)) {
1475
567
    (*Callback)(this, Call, C);
1476
567
    return;
1477
567
  }
1478
1479
30.9k
  if (const CheckFn *Callback = AllocatingMemFnMap.lookup(Call)) {
1480
848
    (*Callback)(this, Call, C);
1481
848
    return;
1482
848
  }
1483
1484
30.0k
  if (const CheckFn *Callback = ReallocatingMemFnMap.lookup(Call)) {
1485
106
    (*Callback)(this, Call, C);
1486
106
    return;
1487
106
  }
1488
1489
29.9k
  if (isStandardNewDelete(Call)) {
1490
871
    checkCXXNewOrCXXDelete(Call, C);
1491
871
    return;
1492
871
  }
1493
1494
29.0k
  checkOwnershipAttr(Call, C);
1495
29.0k
}
1496
1497
// Performs a 0-sized allocations check.
1498
ProgramStateRef MallocChecker::ProcessZeroAllocCheck(
1499
    const CallEvent &Call, const unsigned IndexOfSizeArg, ProgramStateRef State,
1500
1.47k
    std::optional<SVal> RetVal) {
1501
1.47k
  if (!State)
1502
13
    return nullptr;
1503
1504
1.46k
  if (!RetVal)
1505
970
    RetVal = Call.getReturnValue();
1506
1507
1.46k
  const Expr *Arg = nullptr;
1508
1509
1.46k
  if (const CallExpr *CE = dyn_cast<CallExpr>(Call.getOriginExpr())) {
1510
970
    Arg = CE->getArg(IndexOfSizeArg);
1511
970
  } else 
if (const CXXNewExpr *496
NE496
=
1512
496
                 dyn_cast<CXXNewExpr>(Call.getOriginExpr())) {
1513
496
    if (NE->isArray()) {
1514
83
      Arg = *NE->getArraySize();
1515
413
    } else {
1516
413
      return State;
1517
413
    }
1518
496
  } else
1519
0
    llvm_unreachable("not a CallExpr or CXXNewExpr");
1520
1521
1.05k
  assert(Arg);
1522
1523
1.05k
  auto DefArgVal =
1524
1.05k
      State->getSVal(Arg, Call.getLocationContext()).getAs<DefinedSVal>();
1525
1526
1.05k
  if (!DefArgVal)
1527
0
    return State;
1528
1529
  // Check if the allocation size is 0.
1530
1.05k
  ProgramStateRef TrueState, FalseState;
1531
1.05k
  SValBuilder &SvalBuilder = State->getStateManager().getSValBuilder();
1532
1.05k
  DefinedSVal Zero =
1533
1.05k
      SvalBuilder.makeZeroVal(Arg->getType()).castAs<DefinedSVal>();
1534
1535
1.05k
  std::tie(TrueState, FalseState) =
1536
1.05k
      State->assume(SvalBuilder.evalEQ(State, *DefArgVal, Zero));
1537
1538
1.05k
  if (TrueState && 
!FalseState123
) {
1539
99
    SymbolRef Sym = RetVal->getAsLocSymbol();
1540
99
    if (!Sym)
1541
0
      return State;
1542
1543
99
    const RefState *RS = State->get<RegionState>(Sym);
1544
99
    if (RS) {
1545
80
      if (RS->isAllocated())
1546
80
        return TrueState->set<RegionState>(Sym,
1547
80
                                          RefState::getAllocatedOfSizeZero(RS));
1548
0
      else
1549
0
        return State;
1550
80
    } else {
1551
      // Case of zero-size realloc. Historically 'realloc(ptr, 0)' is treated as
1552
      // 'free(ptr)' and the returned value from 'realloc(ptr, 0)' is not
1553
      // tracked. Add zero-reallocated Sym to the state to catch references
1554
      // to zero-allocated memory.
1555
19
      return TrueState->add<ReallocSizeZeroSymbols>(Sym);
1556
19
    }
1557
99
  }
1558
1559
  // Assume the value is non-zero going forward.
1560
954
  assert(FalseState);
1561
954
  return FalseState;
1562
954
}
1563
1564
4
static QualType getDeepPointeeType(QualType T) {
1565
4
  QualType Result = T, PointeeType = T->getPointeeType();
1566
5
  while (!PointeeType.isNull()) {
1567
1
    Result = PointeeType;
1568
1
    PointeeType = PointeeType->getPointeeType();
1569
1
  }
1570
4
  return Result;
1571
4
}
1572
1573
/// \returns true if the constructor invoked by \p NE has an argument of a
1574
/// pointer/reference to a record type.
1575
70
static bool hasNonTrivialConstructorCall(const CXXNewExpr *NE) {
1576
1577
70
  const CXXConstructExpr *ConstructE = NE->getConstructExpr();
1578
70
  if (!ConstructE)
1579
14
    return false;
1580
1581
56
  if (!NE->getAllocatedType()->getAsCXXRecordDecl())
1582
0
    return false;
1583
1584
56
  const CXXConstructorDecl *CtorD = ConstructE->getConstructor();
1585
1586
  // Iterate over the constructor parameters.
1587
56
  for (const auto *CtorParam : CtorD->parameters()) {
1588
1589
7
    QualType CtorParamPointeeT = CtorParam->getType()->getPointeeType();
1590
7
    if (CtorParamPointeeT.isNull())
1591
3
      continue;
1592
1593
4
    CtorParamPointeeT = getDeepPointeeType(CtorParamPointeeT);
1594
1595
4
    if (CtorParamPointeeT->getAsCXXRecordDecl())
1596
3
      return true;
1597
4
  }
1598
1599
53
  return false;
1600
56
}
1601
1602
ProgramStateRef
1603
MallocChecker::processNewAllocation(const CXXAllocatorCall &Call,
1604
                                    CheckerContext &C,
1605
508
                                    AllocationFamily Family) const {
1606
508
  if (!isStandardNewDelete(Call))
1607
9
    return nullptr;
1608
1609
499
  const CXXNewExpr *NE = Call.getOriginExpr();
1610
499
  const ParentMap &PM = C.getLocationContext()->getParentMap();
1611
499
  ProgramStateRef State = C.getState();
1612
1613
  // Non-trivial constructors have a chance to escape 'this', but marking all
1614
  // invocations of trivial constructors as escaped would cause too great of
1615
  // reduction of true positives, so let's just do that for constructors that
1616
  // have an argument of a pointer-to-record type.
1617
499
  if (!PM.isConsumedExpr(NE) && 
hasNonTrivialConstructorCall(NE)70
)
1618
3
    return State;
1619
1620
  // The return value from operator new is bound to a specified initialization
1621
  // value (if any) and we don't want to loose this value. So we call
1622
  // MallocUpdateRefState() instead of MallocMemAux() which breaks the
1623
  // existing binding.
1624
496
  SVal Target = Call.getObjectUnderConstruction();
1625
496
  State = MallocUpdateRefState(C, NE, State, Family, Target);
1626
496
  State = ProcessZeroAllocCheck(Call, 0, State, Target);
1627
496
  return State;
1628
499
}
1629
1630
void MallocChecker::checkNewAllocator(const CXXAllocatorCall &Call,
1631
619
                                      CheckerContext &C) const {
1632
619
  if (!C.wasInlined) {
1633
508
    ProgramStateRef State = processNewAllocation(
1634
508
        Call, C,
1635
508
        (Call.getOriginExpr()->isArray() ? 
AF_CXXNewArray85
:
AF_CXXNew423
));
1636
508
    C.addTransition(State);
1637
508
  }
1638
619
}
1639
1640
152
static bool isKnownDeallocObjCMethodName(const ObjCMethodCall &Call) {
1641
  // If the first selector piece is one of the names below, assume that the
1642
  // object takes ownership of the memory, promising to eventually deallocate it
1643
  // with free().
1644
  // Ex:  [NSData dataWithBytesNoCopy:bytes length:10];
1645
  // (...unless a 'freeWhenDone' parameter is false, but that's checked later.)
1646
152
  StringRef FirstSlot = Call.getSelector().getNameForSlot(0);
1647
152
  return FirstSlot == "dataWithBytesNoCopy" ||
1648
152
         
FirstSlot == "initWithBytesNoCopy"131
||
1649
152
         
FirstSlot == "initWithCharactersNoCopy"116
;
1650
152
}
1651
1652
58
static std::optional<bool> getFreeWhenDoneArg(const ObjCMethodCall &Call) {
1653
58
  Selector S = Call.getSelector();
1654
1655
  // FIXME: We should not rely on fully-constrained symbols being folded.
1656
103
  for (unsigned i = 1; i < S.getNumArgs(); 
++i45
)
1657
79
    if (S.getNameForSlot(i).equals("freeWhenDone"))
1658
34
      return !Call.getArgSVal(i).isZeroConstant();
1659
1660
24
  return std::nullopt;
1661
58
}
1662
1663
void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call,
1664
97
                                         CheckerContext &C) const {
1665
97
  if (C.wasInlined)
1666
1
    return;
1667
1668
96
  if (!isKnownDeallocObjCMethodName(Call))
1669
63
    return;
1670
1671
33
  if (std::optional<bool> FreeWhenDone = getFreeWhenDoneArg(Call))
1672
30
    if (!*FreeWhenDone)
1673
4
      return;
1674
1675
29
  if (Call.hasNonZeroCallbackArg())
1676
1
    return;
1677
1678
28
  bool IsKnownToBeAllocatedMemory;
1679
28
  ProgramStateRef State =
1680
28
      FreeMemAux(C, Call.getArgExpr(0), Call, C.getState(),
1681
28
                 /*Hold=*/true, IsKnownToBeAllocatedMemory, AF_Malloc,
1682
28
                 /*ReturnsNullOnFailure=*/true);
1683
1684
28
  C.addTransition(State);
1685
28
}
1686
1687
ProgramStateRef
1688
MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallEvent &Call,
1689
                                    const OwnershipAttr *Att,
1690
33
                                    ProgramStateRef State) const {
1691
33
  if (!State)
1692
0
    return nullptr;
1693
1694
33
  if (Att->getModule()->getName() != "malloc")
1695
0
    return nullptr;
1696
1697
33
  if (!Att->args().empty()) {
1698
1
    return MallocMemAux(C, Call,
1699
1
                        Call.getArgExpr(Att->args_begin()->getASTIndex()),
1700
1
                        UndefinedVal(), State, AF_Malloc);
1701
1
  }
1702
32
  return MallocMemAux(C, Call, UnknownVal(), UndefinedVal(), State, AF_Malloc);
1703
33
}
1704
1705
ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
1706
                                            const CallEvent &Call,
1707
                                            const Expr *SizeEx, SVal Init,
1708
                                            ProgramStateRef State,
1709
777
                                            AllocationFamily Family) {
1710
777
  if (!State)
1711
0
    return nullptr;
1712
1713
777
  assert(SizeEx);
1714
777
  return MallocMemAux(C, Call, C.getSVal(SizeEx), Init, State, Family);
1715
777
}
1716
1717
ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
1718
                                            const CallEvent &Call, SVal Size,
1719
                                            SVal Init, ProgramStateRef State,
1720
925
                                            AllocationFamily Family) {
1721
925
  if (!State)
1722
0
    return nullptr;
1723
1724
925
  const Expr *CE = Call.getOriginExpr();
1725
1726
  // We expect the malloc functions to return a pointer.
1727
925
  if (!Loc::isLocType(CE->getType()))
1728
3
    return nullptr;
1729
1730
  // Bind the return value to the symbolic value from the heap region.
1731
  // TODO: We could rewrite post visit to eval call; 'malloc' does not have
1732
  // side effects other than what we model here.
1733
922
  unsigned Count = C.blockCount();
1734
922
  SValBuilder &svalBuilder = C.getSValBuilder();
1735
922
  const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
1736
922
  DefinedSVal RetVal = svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count)
1737
922
      .castAs<DefinedSVal>();
1738
922
  State = State->BindExpr(CE, C.getLocationContext(), RetVal);
1739
1740
  // Fill the region with the initialization value.
1741
922
  State = State->bindDefaultInitial(RetVal, Init, LCtx);
1742
1743
  // If Size is somehow undefined at this point, this line prevents a crash.
1744
922
  if (Size.isUndef())
1745
0
    Size = UnknownVal();
1746
1747
  // Set the region's extent.
1748
922
  State = setDynamicExtent(State, RetVal.getAsRegion(),
1749
922
                           Size.castAs<DefinedOrUnknownSVal>(), svalBuilder);
1750
1751
922
  return MallocUpdateRefState(C, CE, State, Family);
1752
925
}
1753
1754
static ProgramStateRef MallocUpdateRefState(CheckerContext &C, const Expr *E,
1755
                                            ProgramStateRef State,
1756
                                            AllocationFamily Family,
1757
1.50k
                                            std::optional<SVal> RetVal) {
1758
1.50k
  if (!State)
1759
0
    return nullptr;
1760
1761
  // Get the return value.
1762
1.50k
  if (!RetVal)
1763
1.01k
    RetVal = C.getSVal(E);
1764
1765
  // We expect the malloc functions to return a pointer.
1766
1.50k
  if (!RetVal->getAs<Loc>())
1767
0
    return nullptr;
1768
1769
1.50k
  SymbolRef Sym = RetVal->getAsLocSymbol();
1770
  // This is a return value of a function that was not inlined, such as malloc()
1771
  // or new(). We've checked that in the caller. Therefore, it must be a symbol.
1772
1.50k
  assert(Sym);
1773
1774
  // Set the symbol's state to Allocated.
1775
1.50k
  return State->set<RegionState>(Sym, RefState::getAllocated(Family, E));
1776
1.50k
}
1777
1778
ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C,
1779
                                           const CallEvent &Call,
1780
                                           const OwnershipAttr *Att,
1781
16
                                           ProgramStateRef State) const {
1782
16
  if (!State)
1783
0
    return nullptr;
1784
1785
16
  if (Att->getModule()->getName() != "malloc")
1786
0
    return nullptr;
1787
1788
16
  bool IsKnownToBeAllocated = false;
1789
1790
17
  for (const auto &Arg : Att->args()) {
1791
17
    ProgramStateRef StateI =
1792
17
        FreeMemAux(C, Call, State, Arg.getASTIndex(),
1793
17
                   Att->getOwnKind() == OwnershipAttr::Holds,
1794
17
                   IsKnownToBeAllocated, AF_Malloc);
1795
17
    if (StateI)
1796
10
      State = StateI;
1797
17
  }
1798
16
  return State;
1799
16
}
1800
1801
ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
1802
                                          const CallEvent &Call,
1803
                                          ProgramStateRef State, unsigned Num,
1804
                                          bool Hold, bool &IsKnownToBeAllocated,
1805
                                          AllocationFamily Family,
1806
693
                                          bool ReturnsNullOnFailure) const {
1807
693
  if (!State)
1808
0
    return nullptr;
1809
1810
693
  if (Call.getNumArgs() < (Num + 1))
1811
0
    return nullptr;
1812
1813
693
  return FreeMemAux(C, Call.getArgExpr(Num), Call, State, Hold,
1814
693
                    IsKnownToBeAllocated, Family, ReturnsNullOnFailure);
1815
693
}
1816
1817
/// Checks if the previous call to free on the given symbol failed - if free
1818
/// failed, returns true. Also, returns the corresponding return value symbol.
1819
static bool didPreviousFreeFail(ProgramStateRef State,
1820
68
                                SymbolRef Sym, SymbolRef &RetStatusSymbol) {
1821
68
  const SymbolRef *Ret = State->get<FreeReturnValue>(Sym);
1822
68
  if (Ret) {
1823
10
    assert(*Ret && "We should not store the null return symbol");
1824
10
    ConstraintManager &CMgr = State->getConstraintManager();
1825
10
    ConditionTruthVal FreeFailed = CMgr.isNull(State, *Ret);
1826
10
    RetStatusSymbol = *Ret;
1827
10
    return FreeFailed.isConstrainedTrue();
1828
10
  }
1829
58
  return false;
1830
68
}
1831
1832
238
static bool printMemFnName(raw_ostream &os, CheckerContext &C, const Expr *E) {
1833
238
  if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
1834
    // FIXME: This doesn't handle indirect calls.
1835
143
    const FunctionDecl *FD = CE->getDirectCallee();
1836
143
    if (!FD)
1837
0
      return false;
1838
1839
143
    os << *FD;
1840
143
    if (!FD->isOverloadedOperator())
1841
128
      os << "()";
1842
143
    return true;
1843
143
  }
1844
1845
95
  if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) {
1846
5
    if (Msg->isInstanceMessage())
1847
1
      os << "-";
1848
4
    else
1849
4
      os << "+";
1850
5
    Msg->getSelector().print(os);
1851
5
    return true;
1852
5
  }
1853
1854
90
  if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) {
1855
31
    os << "'"
1856
31
       << getOperatorSpelling(NE->getOperatorNew()->getOverloadedOperator())
1857
31
       << "'";
1858
31
    return true;
1859
31
  }
1860
1861
59
  if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(E)) {
1862
59
    os << "'"
1863
59
       << getOperatorSpelling(DE->getOperatorDelete()->getOverloadedOperator())
1864
59
       << "'";
1865
59
    return true;
1866
59
  }
1867
1868
0
  return false;
1869
59
}
1870
1871
85
static void printExpectedAllocName(raw_ostream &os, AllocationFamily Family) {
1872
1873
85
  switch(Family) {
1874
67
    case AF_Malloc: os << "malloc()"; return;
1875
14
    case AF_CXXNew: os << "'new'"; return;
1876
4
    case AF_CXXNewArray: os << "'new[]'"; return;
1877
0
    case AF_IfNameIndex: os << "'if_nameindex()'"; return;
1878
0
    case AF_InnerBuffer: os << "container-specific allocator"; return;
1879
0
    case AF_Alloca:
1880
0
    case AF_None: llvm_unreachable("not a deallocation expression");
1881
85
  }
1882
85
}
1883
1884
55
static void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) {
1885
55
  switch(Family) {
1886
25
    case AF_Malloc: os << "free()"; return;
1887
14
    case AF_CXXNew: os << "'delete'"; return;
1888
16
    case AF_CXXNewArray: os << "'delete[]'"; return;
1889
0
    case AF_IfNameIndex: os << "'if_freenameindex()'"; return;
1890
0
    case AF_InnerBuffer: os << "container-specific deallocator"; return;
1891
0
    case AF_Alloca:
1892
0
    case AF_None: llvm_unreachable("suspicious argument");
1893
55
  }
1894
55
}
1895
1896
ProgramStateRef MallocChecker::FreeMemAux(
1897
    CheckerContext &C, const Expr *ArgExpr, const CallEvent &Call,
1898
    ProgramStateRef State, bool Hold, bool &IsKnownToBeAllocated,
1899
1.08k
    AllocationFamily Family, bool ReturnsNullOnFailure) const {
1900
1901
1.08k
  if (!State)
1902
0
    return nullptr;
1903
1904
1.08k
  SVal ArgVal = C.getSVal(ArgExpr);
1905
1.08k
  if (!isa<DefinedOrUnknownSVal>(ArgVal))
1906
1
    return nullptr;
1907
1.08k
  DefinedOrUnknownSVal location = ArgVal.castAs<DefinedOrUnknownSVal>();
1908
1909
  // Check for null dereferences.
1910
1.08k
  if (!isa<Loc>(location))
1911
6
    return nullptr;
1912
1913
  // The explicit NULL case, no operation is performed.
1914
1.08k
  ProgramStateRef notNullState, nullState;
1915
1.08k
  std::tie(notNullState, nullState) = State->assume(location);
1916
1.08k
  if (nullState && 
!notNullState641
)
1917
35
    return nullptr;
1918
1919
  // Unknown values could easily be okay
1920
  // Undefined values are handled elsewhere
1921
1.04k
  if (ArgVal.isUnknownOrUndef())
1922
0
    return nullptr;
1923
1924
1.04k
  const MemRegion *R = ArgVal.getAsRegion();
1925
1.04k
  const Expr *ParentExpr = Call.getOriginExpr();
1926
1927
  // NOTE: We detected a bug, but the checker under whose name we would emit the
1928
  // error could be disabled. Generally speaking, the MallocChecker family is an
1929
  // integral part of the Static Analyzer, and disabling any part of it should
1930
  // only be done under exceptional circumstances, such as frequent false
1931
  // positives. If this is the case, we can reasonably believe that there are
1932
  // serious faults in our understanding of the source code, and even if we
1933
  // don't emit an warning, we should terminate further analysis with a sink
1934
  // node.
1935
1936
  // Nonlocs can't be freed, of course.
1937
  // Non-region locations (labels and fixed addresses) also shouldn't be freed.
1938
1.04k
  if (!R) {
1939
    // Exception:
1940
    // If the macro ZERO_SIZE_PTR is defined, this could be a kernel source
1941
    // code. In that case, the ZERO_SIZE_PTR defines a special value used for a
1942
    // zero-sized memory block which is allowed to be freed, despite not being a
1943
    // null pointer.
1944
20
    if (Family != AF_Malloc || 
!isArgZERO_SIZE_PTR(State, C, ArgVal)14
)
1945
19
      HandleNonHeapDealloc(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
1946
19
                           Family);
1947
20
    return nullptr;
1948
20
  }
1949
1950
1.02k
  R = R->StripCasts();
1951
1952
  // Blocks might show up as heap data, but should not be free()d
1953
1.02k
  if (isa<BlockDataRegion>(R)) {
1954
6
    HandleNonHeapDealloc(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
1955
6
                         Family);
1956
6
    return nullptr;
1957
6
  }
1958
1959
1.01k
  const MemSpaceRegion *MS = R->getMemorySpace();
1960
1961
  // Parameters, locals, statics, globals, and memory returned by
1962
  // __builtin_alloca() shouldn't be freed.
1963
1.01k
  if (!isa<UnknownSpaceRegion, HeapSpaceRegion>(MS)) {
1964
    // FIXME: at the time this code was written, malloc() regions were
1965
    // represented by conjured symbols, which are all in UnknownSpaceRegion.
1966
    // This means that there isn't actually anything from HeapSpaceRegion
1967
    // that should be freed, even though we allow it here.
1968
    // Of course, free() can work on memory allocated outside the current
1969
    // function, so UnknownSpaceRegion is always a possibility.
1970
    // False negatives are better than false positives.
1971
1972
85
    if (isa<AllocaRegion>(R))
1973
8
      HandleFreeAlloca(C, ArgVal, ArgExpr->getSourceRange());
1974
77
    else
1975
77
      HandleNonHeapDealloc(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
1976
77
                           Family);
1977
1978
85
    return nullptr;
1979
85
  }
1980
1981
934
  const SymbolicRegion *SrBase = dyn_cast<SymbolicRegion>(R->getBaseRegion());
1982
  // Various cases could lead to non-symbol values here.
1983
  // For now, ignore them.
1984
934
  if (!SrBase)
1985
0
    return nullptr;
1986
1987
934
  SymbolRef SymBase = SrBase->getSymbol();
1988
934
  const RefState *RsBase = State->get<RegionState>(SymBase);
1989
934
  SymbolRef PreviousRetStatusSymbol = nullptr;
1990
1991
934
  IsKnownToBeAllocated =
1992
934
      RsBase && 
(743
RsBase->isAllocated()743
||
RsBase->isAllocatedOfSizeZero()185
);
1993
1994
934
  if (RsBase) {
1995
1996
    // Memory returned by alloca() shouldn't be freed.
1997
743
    if (RsBase->getAllocationFamily() == AF_Alloca) {
1998
7
      HandleFreeAlloca(C, ArgVal, ArgExpr->getSourceRange());
1999
7
      return nullptr;
2000
7
    }
2001
2002
    // Check for double free first.
2003
736
    if ((RsBase->isReleased() || 
RsBase->isRelinquished()680
) &&
2004
736
        
!didPreviousFreeFail(State, SymBase, PreviousRetStatusSymbol)68
) {
2005
62
      HandleDoubleFree(C, ParentExpr->getSourceRange(), RsBase->isReleased(),
2006
62
                       SymBase, PreviousRetStatusSymbol);
2007
62
      return nullptr;
2008
2009
    // If the pointer is allocated or escaped, but we are now trying to free it,
2010
    // check that the call to free is proper.
2011
674
    } else if (RsBase->isAllocated() || 
RsBase->isAllocatedOfSizeZero()123
||
2012
674
               
RsBase->isEscaped()104
) {
2013
2014
      // Check if an expected deallocation function matches the real one.
2015
668
      bool DeallocMatchesAlloc = RsBase->getAllocationFamily() == Family;
2016
668
      if (!DeallocMatchesAlloc) {
2017
69
        HandleMismatchedDealloc(C, ArgExpr->getSourceRange(), ParentExpr,
2018
69
                                RsBase, SymBase, Hold);
2019
69
        return nullptr;
2020
69
      }
2021
2022
      // Check if the memory location being freed is the actual location
2023
      // allocated, or an offset.
2024
599
      RegionOffset Offset = R->getAsOffset();
2025
599
      if (Offset.isValid() &&
2026
599
          !Offset.hasSymbolicOffset() &&
2027
599
          
Offset.getOffset() != 0598
) {
2028
26
        const Expr *AllocExpr = cast<Expr>(RsBase->getStmt());
2029
26
        HandleOffsetFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
2030
26
                         Family, AllocExpr);
2031
26
        return nullptr;
2032
26
      }
2033
599
    }
2034
736
  }
2035
2036
770
  if (SymBase->getType()->isFunctionPointerType()) {
2037
3
    HandleFunctionPtrFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
2038
3
                          Family);
2039
3
    return nullptr;
2040
3
  }
2041
2042
  // Clean out the info on previous call to free return info.
2043
767
  State = State->remove<FreeReturnValue>(SymBase);
2044
2045
  // Keep track of the return value. If it is NULL, we will know that free
2046
  // failed.
2047
767
  if (ReturnsNullOnFailure) {
2048
21
    SVal RetVal = C.getSVal(ParentExpr);
2049
21
    SymbolRef RetStatusSymbol = RetVal.getAsSymbol();
2050
21
    if (RetStatusSymbol) {
2051
21
      C.getSymbolManager().addSymbolDependency(SymBase, RetStatusSymbol);
2052
21
      State = State->set<FreeReturnValue>(SymBase, RetStatusSymbol);
2053
21
    }
2054
21
  }
2055
2056
  // If we don't know anything about this symbol, a free on it may be totally
2057
  // valid. If this is the case, lets assume that the allocation family of the
2058
  // freeing function is the same as the symbols allocation family, and go with
2059
  // that.
2060
767
  assert(!RsBase || (RsBase && RsBase->getAllocationFamily() == Family));
2061
2062
  // Normal free.
2063
767
  if (Hold)
2064
27
    return State->set<RegionState>(SymBase,
2065
27
                                   RefState::getRelinquished(Family,
2066
27
                                                             ParentExpr));
2067
2068
740
  return State->set<RegionState>(SymBase,
2069
740
                                 RefState::getReleased(Family, ParentExpr));
2070
767
}
2071
2072
std::optional<MallocChecker::CheckKind>
2073
MallocChecker::getCheckIfTracked(AllocationFamily Family,
2074
656
                                 bool IsALeakCheck) const {
2075
656
  switch (Family) {
2076
395
  case AF_Malloc:
2077
397
  case AF_Alloca:
2078
397
  case AF_IfNameIndex: {
2079
397
    if (ChecksEnabled[CK_MallocChecker])
2080
377
      return CK_MallocChecker;
2081
20
    return std::nullopt;
2082
397
  }
2083
188
  case AF_CXXNew:
2084
228
  case AF_CXXNewArray: {
2085
228
    if (IsALeakCheck) {
2086
100
      if (ChecksEnabled[CK_NewDeleteLeaksChecker])
2087
77
        return CK_NewDeleteLeaksChecker;
2088
100
    }
2089
128
    else {
2090
128
      if (ChecksEnabled[CK_NewDeleteChecker])
2091
104
        return CK_NewDeleteChecker;
2092
128
    }
2093
47
    return std::nullopt;
2094
228
  }
2095
31
  case AF_InnerBuffer: {
2096
31
    if (ChecksEnabled[CK_InnerPointerChecker])
2097
31
      return CK_InnerPointerChecker;
2098
0
    return std::nullopt;
2099
31
  }
2100
0
  case AF_None: {
2101
0
    llvm_unreachable("no family");
2102
0
  }
2103
656
  }
2104
0
  llvm_unreachable("unhandled family");
2105
0
}
2106
2107
std::optional<MallocChecker::CheckKind>
2108
MallocChecker::getCheckIfTracked(CheckerContext &C, SymbolRef Sym,
2109
233
                                 bool IsALeakCheck) const {
2110
233
  if (C.getState()->contains<ReallocSizeZeroSymbols>(Sym))
2111
4
    return CK_MallocChecker;
2112
2113
229
  const RefState *RS = C.getState()->get<RegionState>(Sym);
2114
229
  assert(RS);
2115
229
  return getCheckIfTracked(RS->getAllocationFamily(), IsALeakCheck);
2116
229
}
2117
2118
19
bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
2119
19
  if (std::optional<nonloc::ConcreteInt> IntVal =
2120
19
          V.getAs<nonloc::ConcreteInt>())
2121
0
    os << "an integer (" << IntVal->getValue() << ")";
2122
19
  else if (std::optional<loc::ConcreteInt> ConstAddr =
2123
19
               V.getAs<loc::ConcreteInt>())
2124
13
    os << "a constant address (" << ConstAddr->getValue() << ")";
2125
6
  else if (std::optional<loc::GotoLabel> Label = V.getAs<loc::GotoLabel>())
2126
6
    os << "the address of the label '" << Label->getLabel()->getName() << "'";
2127
0
  else
2128
0
    return false;
2129
2130
19
  return true;
2131
19
}
2132
2133
bool MallocChecker::SummarizeRegion(raw_ostream &os,
2134
66
                                    const MemRegion *MR) {
2135
66
  switch (MR->getKind()) {
2136
13
  case MemRegion::FunctionCodeRegionKind: {
2137
13
    const NamedDecl *FD = cast<FunctionCodeRegion>(MR)->getDecl();
2138
13
    if (FD)
2139
13
      os << "the address of the function '" << *FD << '\'';
2140
0
    else
2141
0
      os << "the address of a function";
2142
13
    return true;
2143
0
  }
2144
0
  case MemRegion::BlockCodeRegionKind:
2145
0
    os << "block text";
2146
0
    return true;
2147
6
  case MemRegion::BlockDataRegionKind:
2148
    // FIXME: where the block came from?
2149
6
    os << "a block";
2150
6
    return true;
2151
47
  default: {
2152
47
    const MemSpaceRegion *MS = MR->getMemorySpace();
2153
2154
47
    if (isa<StackLocalsSpaceRegion>(MS)) {
2155
29
      const VarRegion *VR = dyn_cast<VarRegion>(MR);
2156
29
      const VarDecl *VD;
2157
29
      if (VR)
2158
27
        VD = VR->getDecl();
2159
2
      else
2160
2
        VD = nullptr;
2161
2162
29
      if (VD)
2163
27
        os << "the address of the local variable '" << VD->getName() << "'";
2164
2
      else
2165
2
        os << "the address of a local stack variable";
2166
29
      return true;
2167
29
    }
2168
2169
18
    if (isa<StackArgumentsSpaceRegion>(MS)) {
2170
6
      const VarRegion *VR = dyn_cast<VarRegion>(MR);
2171
6
      const VarDecl *VD;
2172
6
      if (VR)
2173
6
        VD = VR->getDecl();
2174
0
      else
2175
0
        VD = nullptr;
2176
2177
6
      if (VD)
2178
6
        os << "the address of the parameter '" << VD->getName() << "'";
2179
0
      else
2180
0
        os << "the address of a parameter";
2181
6
      return true;
2182
6
    }
2183
2184
12
    if (isa<GlobalsSpaceRegion>(MS)) {
2185
12
      const VarRegion *VR = dyn_cast<VarRegion>(MR);
2186
12
      const VarDecl *VD;
2187
12
      if (VR)
2188
12
        VD = VR->getDecl();
2189
0
      else
2190
0
        VD = nullptr;
2191
2192
12
      if (VD) {
2193
12
        if (VD->isStaticLocal())
2194
6
          os << "the address of the static variable '" << VD->getName() << "'";
2195
6
        else
2196
6
          os << "the address of the global variable '" << VD->getName() << "'";
2197
12
      } else
2198
0
        os << "the address of a global variable";
2199
12
      return true;
2200
12
    }
2201
2202
0
    return false;
2203
12
  }
2204
66
  }
2205
66
}
2206
2207
void MallocChecker::HandleNonHeapDealloc(CheckerContext &C, SVal ArgVal,
2208
                                         SourceRange Range,
2209
                                         const Expr *DeallocExpr,
2210
102
                                         AllocationFamily Family) const {
2211
2212
102
  if (!ChecksEnabled[CK_MallocChecker] && 
!ChecksEnabled[CK_NewDeleteChecker]18
) {
2213
8
    C.addSink();
2214
8
    return;
2215
8
  }
2216
2217
94
  std::optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
2218
94
  if (!CheckKind)
2219
9
    return;
2220
2221
85
  if (ExplodedNode *N = C.generateErrorNode()) {
2222
85
    if (!BT_BadFree[*CheckKind])
2223
23
      BT_BadFree[*CheckKind].reset(new BugType(
2224
23
          CheckNames[*CheckKind], "Bad free", categories::MemoryError));
2225
2226
85
    SmallString<100> buf;
2227
85
    llvm::raw_svector_ostream os(buf);
2228
2229
85
    const MemRegion *MR = ArgVal.getAsRegion();
2230
108
    while (const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(MR))
2231
23
      MR = ER->getSuperRegion();
2232
2233
85
    os << "Argument to ";
2234
85
    if (!printMemFnName(os, C, DeallocExpr))
2235
0
      os << "deallocator";
2236
2237
85
    os << " is ";
2238
85
    bool Summarized = MR ? 
SummarizeRegion(os, MR)66
2239
85
                         : 
SummarizeValue(os, ArgVal)19
;
2240
85
    if (Summarized)
2241
85
      os << ", which is not memory allocated by ";
2242
0
    else
2243
0
      os << "not memory allocated by ";
2244
2245
85
    printExpectedAllocName(os, Family);
2246
2247
85
    auto R = std::make_unique<PathSensitiveBugReport>(*BT_BadFree[*CheckKind],
2248
85
                                                      os.str(), N);
2249
85
    R->markInteresting(MR);
2250
85
    R->addRange(Range);
2251
85
    C.emitReport(std::move(R));
2252
85
  }
2253
85
}
2254
2255
void MallocChecker::HandleFreeAlloca(CheckerContext &C, SVal ArgVal,
2256
15
                                     SourceRange Range) const {
2257
2258
15
  std::optional<MallocChecker::CheckKind> CheckKind;
2259
2260
15
  if (ChecksEnabled[CK_MallocChecker])
2261
12
    CheckKind = CK_MallocChecker;
2262
3
  else if (ChecksEnabled[CK_MismatchedDeallocatorChecker])
2263
2
    CheckKind = CK_MismatchedDeallocatorChecker;
2264
1
  else {
2265
1
    C.addSink();
2266
1
    return;
2267
1
  }
2268
2269
14
  if (ExplodedNode *N = C.generateErrorNode()) {
2270
14
    if (!BT_FreeAlloca[*CheckKind])
2271
6
      BT_FreeAlloca[*CheckKind].reset(new BugType(
2272
6
          CheckNames[*CheckKind], "Free alloca()", categories::MemoryError));
2273
2274
14
    auto R = std::make_unique<PathSensitiveBugReport>(
2275
14
        *BT_FreeAlloca[*CheckKind],
2276
14
        "Memory allocated by alloca() should not be deallocated", N);
2277
14
    R->markInteresting(ArgVal.getAsRegion());
2278
14
    R->addRange(Range);
2279
14
    C.emitReport(std::move(R));
2280
14
  }
2281
14
}
2282
2283
void MallocChecker::HandleMismatchedDealloc(CheckerContext &C,
2284
                                            SourceRange Range,
2285
                                            const Expr *DeallocExpr,
2286
                                            const RefState *RS, SymbolRef Sym,
2287
69
                                            bool OwnershipTransferred) const {
2288
2289
69
  if (!ChecksEnabled[CK_MismatchedDeallocatorChecker]) {
2290
10
    C.addSink();
2291
10
    return;
2292
10
  }
2293
2294
59
  if (ExplodedNode *N = C.generateErrorNode()) {
2295
59
    if (!BT_MismatchedDealloc)
2296
12
      BT_MismatchedDealloc.reset(
2297
12
          new BugType(CheckNames[CK_MismatchedDeallocatorChecker],
2298
12
                      "Bad deallocator", categories::MemoryError));
2299
2300
59
    SmallString<100> buf;
2301
59
    llvm::raw_svector_ostream os(buf);
2302
2303
59
    const Expr *AllocExpr = cast<Expr>(RS->getStmt());
2304
59
    SmallString<20> AllocBuf;
2305
59
    llvm::raw_svector_ostream AllocOs(AllocBuf);
2306
59
    SmallString<20> DeallocBuf;
2307
59
    llvm::raw_svector_ostream DeallocOs(DeallocBuf);
2308
2309
59
    if (OwnershipTransferred) {
2310
4
      if (printMemFnName(DeallocOs, C, DeallocExpr))
2311
4
        os << DeallocOs.str() << " cannot";
2312
0
      else
2313
0
        os << "Cannot";
2314
2315
4
      os << " take ownership of memory";
2316
2317
4
      if (printMemFnName(AllocOs, C, AllocExpr))
2318
4
        os << " allocated by " << AllocOs.str();
2319
55
    } else {
2320
55
      os << "Memory";
2321
55
      if (printMemFnName(AllocOs, C, AllocExpr))
2322
55
        os << " allocated by " << AllocOs.str();
2323
2324
55
      os << " should be deallocated by ";
2325
55
        printExpectedDeallocName(os, RS->getAllocationFamily());
2326
2327
55
        if (printMemFnName(DeallocOs, C, DeallocExpr))
2328
55
          os << ", not " << DeallocOs.str();
2329
55
    }
2330
2331
59
    auto R = std::make_unique<PathSensitiveBugReport>(*BT_MismatchedDealloc,
2332
59
                                                      os.str(), N);
2333
59
    R->markInteresting(Sym);
2334
59
    R->addRange(Range);
2335
59
    R->addVisitor<MallocBugVisitor>(Sym);
2336
59
    C.emitReport(std::move(R));
2337
59
  }
2338
59
}
2339
2340
void MallocChecker::HandleOffsetFree(CheckerContext &C, SVal ArgVal,
2341
                                     SourceRange Range, const Expr *DeallocExpr,
2342
                                     AllocationFamily Family,
2343
26
                                     const Expr *AllocExpr) const {
2344
2345
26
  if (!ChecksEnabled[CK_MallocChecker] && 
!ChecksEnabled[CK_NewDeleteChecker]11
) {
2346
4
    C.addSink();
2347
4
    return;
2348
4
  }
2349
2350
22
  std::optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
2351
22
  if (!CheckKind)
2352
6
    return;
2353
2354
16
  ExplodedNode *N = C.generateErrorNode();
2355
16
  if (!N)
2356
0
    return;
2357
2358
16
  if (!BT_OffsetFree[*CheckKind])
2359
10
    BT_OffsetFree[*CheckKind].reset(new BugType(
2360
10
        CheckNames[*CheckKind], "Offset free", categories::MemoryError));
2361
2362
16
  SmallString<100> buf;
2363
16
  llvm::raw_svector_ostream os(buf);
2364
16
  SmallString<20> AllocNameBuf;
2365
16
  llvm::raw_svector_ostream AllocNameOs(AllocNameBuf);
2366
2367
16
  const MemRegion *MR = ArgVal.getAsRegion();
2368
16
  assert(MR && "Only MemRegion based symbols can have offset free errors");
2369
2370
16
  RegionOffset Offset = MR->getAsOffset();
2371
16
  assert((Offset.isValid() &&
2372
16
          !Offset.hasSymbolicOffset() &&
2373
16
          Offset.getOffset() != 0) &&
2374
16
         "Only symbols with a valid offset can have offset free errors");
2375
2376
16
  int offsetBytes = Offset.getOffset() / C.getASTContext().getCharWidth();
2377
2378
16
  os << "Argument to ";
2379
16
  if (!printMemFnName(os, C, DeallocExpr))
2380
0
    os << "deallocator";
2381
16
  os << " is offset by "
2382
16
     << offsetBytes
2383
16
     << " "
2384
16
     << ((abs(offsetBytes) > 1) ? 
"bytes"14
:
"byte"2
)
2385
16
     << " from the start of ";
2386
16
  if (AllocExpr && printMemFnName(AllocNameOs, C, AllocExpr))
2387
16
    os << "memory allocated by " << AllocNameOs.str();
2388
0
  else
2389
0
    os << "allocated memory";
2390
2391
16
  auto R = std::make_unique<PathSensitiveBugReport>(*BT_OffsetFree[*CheckKind],
2392
16
                                                    os.str(), N);
2393
16
  R->markInteresting(MR->getBaseRegion());
2394
16
  R->addRange(Range);
2395
16
  C.emitReport(std::move(R));
2396
16
}
2397
2398
void MallocChecker::HandleUseAfterFree(CheckerContext &C, SourceRange Range,
2399
179
                                       SymbolRef Sym) const {
2400
2401
179
  if (!ChecksEnabled[CK_MallocChecker] && 
!ChecksEnabled[CK_NewDeleteChecker]122
&&
2402
179
      
!ChecksEnabled[CK_InnerPointerChecker]71
) {
2403
40
    C.addSink();
2404
40
    return;
2405
40
  }
2406
2407
139
  std::optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
2408
139
  if (!CheckKind)
2409
14
    return;
2410
2411
125
  if (ExplodedNode *N = C.generateErrorNode()) {
2412
125
    if (!BT_UseFree[*CheckKind])
2413
29
      BT_UseFree[*CheckKind].reset(new BugType(
2414
29
          CheckNames[*CheckKind], "Use-after-free", categories::MemoryError));
2415
2416
125
    AllocationFamily AF =
2417
125
        C.getState()->get<RegionState>(Sym)->getAllocationFamily();
2418
2419
125
    auto R = std::make_unique<PathSensitiveBugReport>(
2420
125
        *BT_UseFree[*CheckKind],
2421
125
        AF == AF_InnerBuffer
2422
125
            ? 
"Inner pointer of container used after re/deallocation"31
2423
125
            : 
"Use of memory after it is freed"94
,
2424
125
        N);
2425
2426
125
    R->markInteresting(Sym);
2427
125
    R->addRange(Range);
2428
125
    R->addVisitor<MallocBugVisitor>(Sym);
2429
2430
125
    if (AF == AF_InnerBuffer)
2431
31
      R->addVisitor(allocation_state::getInnerPointerBRVisitor(Sym));
2432
2433
125
    C.emitReport(std::move(R));
2434
125
  }
2435
125
}
2436
2437
void MallocChecker::HandleDoubleFree(CheckerContext &C, SourceRange Range,
2438
                                     bool Released, SymbolRef Sym,
2439
62
                                     SymbolRef PrevSym) const {
2440
2441
62
  if (!ChecksEnabled[CK_MallocChecker] && 
!ChecksEnabled[CK_NewDeleteChecker]11
) {
2442
4
    C.addSink();
2443
4
    return;
2444
4
  }
2445
2446
58
  std::optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
2447
58
  if (!CheckKind)
2448
6
    return;
2449
2450
52
  if (ExplodedNode *N = C.generateErrorNode()) {
2451
48
    if (!BT_DoubleFree[*CheckKind])
2452
19
      BT_DoubleFree[*CheckKind].reset(new BugType(
2453
19
          CheckNames[*CheckKind], "Double free", categories::MemoryError));
2454
2455
48
    auto R = std::make_unique<PathSensitiveBugReport>(
2456
48
        *BT_DoubleFree[*CheckKind],
2457
48
        (Released ? 
"Attempt to free released memory"42
2458
48
                  : 
"Attempt to free non-owned memory"6
),
2459
48
        N);
2460
48
    R->addRange(Range);
2461
48
    R->markInteresting(Sym);
2462
48
    if (PrevSym)
2463
4
      R->markInteresting(PrevSym);
2464
48
    R->addVisitor<MallocBugVisitor>(Sym);
2465
48
    C.emitReport(std::move(R));
2466
48
  }
2467
52
}
2468
2469
12
void MallocChecker::HandleDoubleDelete(CheckerContext &C, SymbolRef Sym) const {
2470
2471
12
  if (!ChecksEnabled[CK_NewDeleteChecker]) {
2472
4
    C.addSink();
2473
4
    return;
2474
4
  }
2475
2476
8
  std::optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
2477
8
  if (!CheckKind)
2478
0
    return;
2479
2480
8
  if (ExplodedNode *N = C.generateErrorNode()) {
2481
8
    if (!BT_DoubleDelete)
2482
4
      BT_DoubleDelete.reset(new BugType(CheckNames[CK_NewDeleteChecker],
2483
4
                                        "Double delete",
2484
4
                                        categories::MemoryError));
2485
2486
8
    auto R = std::make_unique<PathSensitiveBugReport>(
2487
8
        *BT_DoubleDelete, "Attempt to delete released memory", N);
2488
2489
8
    R->markInteresting(Sym);
2490
8
    R->addVisitor<MallocBugVisitor>(Sym);
2491
8
    C.emitReport(std::move(R));
2492
8
  }
2493
8
}
2494
2495
void MallocChecker::HandleUseZeroAlloc(CheckerContext &C, SourceRange Range,
2496
36
                                       SymbolRef Sym) const {
2497
2498
36
  if (!ChecksEnabled[CK_MallocChecker] && 
!ChecksEnabled[CK_NewDeleteChecker]21
) {
2499
8
    C.addSink();
2500
8
    return;
2501
8
  }
2502
2503
28
  std::optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
2504
2505
28
  if (!CheckKind)
2506
4
    return;
2507
2508
24
  if (ExplodedNode *N = C.generateErrorNode()) {
2509
24
    if (!BT_UseZerroAllocated[*CheckKind])
2510
5
      BT_UseZerroAllocated[*CheckKind].reset(
2511
5
          new BugType(CheckNames[*CheckKind], "Use of zero allocated",
2512
5
                      categories::MemoryError));
2513
2514
24
    auto R = std::make_unique<PathSensitiveBugReport>(
2515
24
        *BT_UseZerroAllocated[*CheckKind],
2516
24
        "Use of memory allocated with size zero", N);
2517
2518
24
    R->addRange(Range);
2519
24
    if (Sym) {
2520
24
      R->markInteresting(Sym);
2521
24
      R->addVisitor<MallocBugVisitor>(Sym);
2522
24
    }
2523
24
    C.emitReport(std::move(R));
2524
24
  }
2525
24
}
2526
2527
void MallocChecker::HandleFunctionPtrFree(CheckerContext &C, SVal ArgVal,
2528
                                          SourceRange Range,
2529
                                          const Expr *FreeExpr,
2530
3
                                          AllocationFamily Family) const {
2531
3
  if (!ChecksEnabled[CK_MallocChecker]) {
2532
0
    C.addSink();
2533
0
    return;
2534
0
  }
2535
2536
3
  std::optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
2537
3
  if (!CheckKind)
2538
0
    return;
2539
2540
3
  if (ExplodedNode *N = C.generateErrorNode()) {
2541
3
    if (!BT_BadFree[*CheckKind])
2542
1
      BT_BadFree[*CheckKind].reset(new BugType(
2543
1
          CheckNames[*CheckKind], "Bad free", categories::MemoryError));
2544
2545
3
    SmallString<100> Buf;
2546
3
    llvm::raw_svector_ostream Os(Buf);
2547
2548
3
    const MemRegion *MR = ArgVal.getAsRegion();
2549
3
    while (const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(MR))
2550
0
      MR = ER->getSuperRegion();
2551
2552
3
    Os << "Argument to ";
2553
3
    if (!printMemFnName(Os, C, FreeExpr))
2554
0
      Os << "deallocator";
2555
2556
3
    Os << " is a function pointer";
2557
2558
3
    auto R = std::make_unique<PathSensitiveBugReport>(*BT_BadFree[*CheckKind],
2559
3
                                                      Os.str(), N);
2560
3
    R->markInteresting(MR);
2561
3
    R->addRange(Range);
2562
3
    C.emitReport(std::move(R));
2563
3
  }
2564
3
}
2565
2566
ProgramStateRef
2567
MallocChecker::ReallocMemAux(CheckerContext &C, const CallEvent &Call,
2568
                             bool ShouldFreeOnFail, ProgramStateRef State,
2569
90
                             AllocationFamily Family, bool SuffixWithN) const {
2570
90
  if (!State)
2571
0
    return nullptr;
2572
2573
90
  const CallExpr *CE = cast<CallExpr>(Call.getOriginExpr());
2574
2575
90
  if (SuffixWithN && 
CE->getNumArgs() < 314
)
2576
0
    return nullptr;
2577
90
  else if (CE->getNumArgs() < 2)
2578
0
    return nullptr;
2579
2580
90
  const Expr *arg0Expr = CE->getArg(0);
2581
90
  SVal Arg0Val = C.getSVal(arg0Expr);
2582
90
  if (!isa<DefinedOrUnknownSVal>(Arg0Val))
2583
0
    return nullptr;
2584
90
  DefinedOrUnknownSVal arg0Val = Arg0Val.castAs<DefinedOrUnknownSVal>();
2585
2586
90
  SValBuilder &svalBuilder = C.getSValBuilder();
2587
2588
90
  DefinedOrUnknownSVal PtrEQ = svalBuilder.evalEQ(
2589
90
      State, arg0Val, svalBuilder.makeNullWithType(arg0Expr->getType()));
2590
2591
  // Get the size argument.
2592
90
  const Expr *Arg1 = CE->getArg(1);
2593
2594
  // Get the value of the size argument.
2595
90
  SVal TotalSize = C.getSVal(Arg1);
2596
90
  if (SuffixWithN)
2597
14
    TotalSize = evalMulForBufferSize(C, Arg1, CE->getArg(2));
2598
90
  if (!isa<DefinedOrUnknownSVal>(TotalSize))
2599
0
    return nullptr;
2600
2601
  // Compare the size argument to 0.
2602
90
  DefinedOrUnknownSVal SizeZero =
2603
90
      svalBuilder.evalEQ(State, TotalSize.castAs<DefinedOrUnknownSVal>(),
2604
90
                         svalBuilder.makeIntValWithWidth(
2605
90
                             svalBuilder.getContext().getSizeType(), 0));
2606
2607
90
  ProgramStateRef StatePtrIsNull, StatePtrNotNull;
2608
90
  std::tie(StatePtrIsNull, StatePtrNotNull) = State->assume(PtrEQ);
2609
90
  ProgramStateRef StateSizeIsZero, StateSizeNotZero;
2610
90
  std::tie(StateSizeIsZero, StateSizeNotZero) = State->assume(SizeZero);
2611
  // We only assume exceptional states if they are definitely true; if the
2612
  // state is under-constrained, assume regular realloc behavior.
2613
90
  bool PrtIsNull = StatePtrIsNull && 
!StatePtrNotNull82
;
2614
90
  bool SizeIsZero = StateSizeIsZero && 
!StateSizeNotZero24
;
2615
2616
  // If the ptr is NULL and the size is not 0, the call is equivalent to
2617
  // malloc(size).
2618
90
  if (PrtIsNull && 
!SizeIsZero9
) {
2619
5
    ProgramStateRef stateMalloc = MallocMemAux(
2620
5
        C, Call, TotalSize, UndefinedVal(), StatePtrIsNull, Family);
2621
5
    return stateMalloc;
2622
5
  }
2623
2624
85
  if (PrtIsNull && 
SizeIsZero4
)
2625
4
    return State;
2626
2627
81
  assert(!PrtIsNull);
2628
2629
81
  bool IsKnownToBeAllocated = false;
2630
2631
  // If the size is 0, free the memory.
2632
81
  if (SizeIsZero)
2633
    // The semantics of the return value are:
2634
    // If size was equal to 0, either NULL or a pointer suitable to be passed
2635
    // to free() is returned. We just free the input pointer and do not add
2636
    // any constrains on the output pointer.
2637
17
    if (ProgramStateRef stateFree = FreeMemAux(
2638
17
            C, Call, StateSizeIsZero, 0, false, IsKnownToBeAllocated, Family))
2639
15
      return stateFree;
2640
2641
  // Default behavior.
2642
66
  if (ProgramStateRef stateFree =
2643
66
          FreeMemAux(C, Call, State, 0, false, IsKnownToBeAllocated, Family)) {
2644
2645
56
    ProgramStateRef stateRealloc =
2646
56
        MallocMemAux(C, Call, TotalSize, UnknownVal(), stateFree, Family);
2647
56
    if (!stateRealloc)
2648
0
      return nullptr;
2649
2650
56
    OwnershipAfterReallocKind Kind = OAR_ToBeFreedAfterFailure;
2651
56
    if (ShouldFreeOnFail)
2652
3
      Kind = OAR_FreeOnFailure;
2653
53
    else if (!IsKnownToBeAllocated)
2654
7
      Kind = OAR_DoNotTrackAfterFailure;
2655
2656
    // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size).
2657
56
    SymbolRef FromPtr = arg0Val.getLocSymbolInBase();
2658
56
    SVal RetVal = C.getSVal(CE);
2659
56
    SymbolRef ToPtr = RetVal.getAsSymbol();
2660
56
    assert(FromPtr && ToPtr &&
2661
56
           "By this point, FreeMemAux and MallocMemAux should have checked "
2662
56
           "whether the argument or the return value is symbolic!");
2663
2664
    // Record the info about the reallocated symbol so that we could properly
2665
    // process failed reallocation.
2666
56
    stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr,
2667
56
                                                   ReallocPair(FromPtr, Kind));
2668
    // The reallocated symbol should stay alive for as long as the new symbol.
2669
56
    C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
2670
56
    return stateRealloc;
2671
56
  }
2672
10
  return nullptr;
2673
66
}
2674
2675
ProgramStateRef MallocChecker::CallocMem(CheckerContext &C,
2676
                                         const CallEvent &Call,
2677
27
                                         ProgramStateRef State) {
2678
27
  if (!State)
2679
0
    return nullptr;
2680
2681
27
  if (Call.getNumArgs() < 2)
2682
0
    return nullptr;
2683
2684
27
  SValBuilder &svalBuilder = C.getSValBuilder();
2685
27
  SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
2686
27
  SVal TotalSize =
2687
27
      evalMulForBufferSize(C, Call.getArgExpr(0), Call.getArgExpr(1));
2688
2689
27
  return MallocMemAux(C, Call, TotalSize, zeroVal, State, AF_Malloc);
2690
27
}
2691
2692
MallocChecker::LeakInfo MallocChecker::getAllocationSite(const ExplodedNode *N,
2693
                                                         SymbolRef Sym,
2694
280
                                                         CheckerContext &C) {
2695
280
  const LocationContext *LeakContext = N->getLocationContext();
2696
  // Walk the ExplodedGraph backwards and find the first node that referred to
2697
  // the tracked symbol.
2698
280
  const ExplodedNode *AllocNode = N;
2699
280
  const MemRegion *ReferenceRegion = nullptr;
2700
2701
9.06k
  while (N) {
2702
9.06k
    ProgramStateRef State = N->getState();
2703
9.06k
    if (!State->get<RegionState>(Sym))
2704
280
      break;
2705
2706
    // Find the most recent expression bound to the symbol in the current
2707
    // context.
2708
8.78k
    if (!ReferenceRegion) {
2709
7.28k
      if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) {
2710
386
        SVal Val = State->getSVal(MR);
2711
386
        if (Val.getAsLocSymbol() == Sym) {
2712
260
          const VarRegion *VR = MR->getBaseRegion()->getAs<VarRegion>();
2713
          // Do not show local variables belonging to a function other than
2714
          // where the error is reported.
2715
260
          if (!VR || (VR->getStackFrame() == LeakContext->getStackFrame()))
2716
248
            ReferenceRegion = MR;
2717
260
        }
2718
386
      }
2719
7.28k
    }
2720
2721
    // Allocation node, is the last node in the current or parent context in
2722
    // which the symbol was tracked.
2723
8.78k
    const LocationContext *NContext = N->getLocationContext();
2724
8.78k
    if (NContext == LeakContext ||
2725
8.78k
        
NContext->isParentOf(LeakContext)1.00k
)
2726
7.80k
      AllocNode = N;
2727
8.78k
    N = N->pred_empty() ? 
nullptr0
: *(N->pred_begin());
2728
8.78k
  }
2729
2730
280
  return LeakInfo(AllocNode, ReferenceRegion);
2731
280
}
2732
2733
void MallocChecker::HandleLeak(SymbolRef Sym, ExplodedNode *N,
2734
365
                               CheckerContext &C) const {
2735
2736
365
  if (!ChecksEnabled[CK_MallocChecker] &&
2737
365
      
!ChecksEnabled[CK_NewDeleteLeaksChecker]82
)
2738
19
    return;
2739
2740
346
  const RefState *RS = C.getState()->get<RegionState>(Sym);
2741
346
  assert(RS && "cannot leak an untracked symbol");
2742
346
  AllocationFamily Family = RS->getAllocationFamily();
2743
2744
346
  if (Family == AF_Alloca)
2745
38
    return;
2746
2747
308
  std::optional<MallocChecker::CheckKind> CheckKind =
2748
308
      getCheckIfTracked(Family, true);
2749
2750
308
  if (!CheckKind)
2751
28
    return;
2752
2753
280
  assert(N);
2754
280
  if (!BT_Leak[*CheckKind]) {
2755
    // Leaks should not be reported if they are post-dominated by a sink:
2756
    // (1) Sinks are higher importance bugs.
2757
    // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
2758
    //     with __noreturn functions such as assert() or exit(). We choose not
2759
    //     to report leaks on such paths.
2760
66
    BT_Leak[*CheckKind].reset(new BugType(CheckNames[*CheckKind], "Memory leak",
2761
66
                                          categories::MemoryError,
2762
66
                                          /*SuppressOnSink=*/true));
2763
66
  }
2764
2765
  // Most bug reports are cached at the location where they occurred.
2766
  // With leaks, we want to unique them by the location where they were
2767
  // allocated, and only report a single path.
2768
280
  PathDiagnosticLocation LocUsedForUniqueing;
2769
280
  const ExplodedNode *AllocNode = nullptr;
2770
280
  const MemRegion *Region = nullptr;
2771
280
  std::tie(AllocNode, Region) = getAllocationSite(N, Sym, C);
2772
2773
280
  const Stmt *AllocationStmt = AllocNode->getStmtForDiagnostics();
2774
280
  if (AllocationStmt)
2775
280
    LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocationStmt,
2776
280
                                              C.getSourceManager(),
2777
280
                                              AllocNode->getLocationContext());
2778
2779
280
  SmallString<200> buf;
2780
280
  llvm::raw_svector_ostream os(buf);
2781
280
  if (Region && 
Region->canPrintPretty()248
) {
2782
244
    os << "Potential leak of memory pointed to by ";
2783
244
    Region->printPretty(os);
2784
244
  } else {
2785
36
    os << "Potential memory leak";
2786
36
  }
2787
2788
280
  auto R = std::make_unique<PathSensitiveBugReport>(
2789
280
      *BT_Leak[*CheckKind], os.str(), N, LocUsedForUniqueing,
2790
280
      AllocNode->getLocationContext()->getDecl());
2791
280
  R->markInteresting(Sym);
2792
280
  R->addVisitor<MallocBugVisitor>(Sym, true);
2793
280
  if (ShouldRegisterNoOwnershipChangeVisitor)
2794
268
    R->addVisitor<NoOwnershipChangeVisitor>(Sym, this);
2795
280
  C.emitReport(std::move(R));
2796
280
}
2797
2798
void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
2799
                                     CheckerContext &C) const
2800
134k
{
2801
134k
  ProgramStateRef state = C.getState();
2802
134k
  RegionStateTy OldRS = state->get<RegionState>();
2803
134k
  RegionStateTy::Factory &F = state->get_context<RegionState>();
2804
2805
134k
  RegionStateTy RS = OldRS;
2806
134k
  SmallVector<SymbolRef, 2> Errors;
2807
134k
  for (auto [Sym, State] : RS) {
2808
12.1k
    if (SymReaper.isDead(Sym)) {
2809
1.21k
      if (State.isAllocated() || 
State.isAllocatedOfSizeZero()884
)
2810
365
        Errors.push_back(Sym);
2811
      // Remove the dead symbol from the map.
2812
1.21k
      RS = F.remove(RS, Sym);
2813
1.21k
    }
2814
12.1k
  }
2815
2816
134k
  if (RS == OldRS) {
2817
    // We shouldn't have touched other maps yet.
2818
133k
    assert(state->get<ReallocPairs>() ==
2819
133k
           C.getState()->get<ReallocPairs>());
2820
133k
    assert(state->get<FreeReturnValue>() ==
2821
133k
           C.getState()->get<FreeReturnValue>());
2822
133k
    return;
2823
133k
  }
2824
2825
  // Cleanup the Realloc Pairs Map.
2826
1.11k
  ReallocPairsTy RP = state->get<ReallocPairs>();
2827
1.11k
  for (auto [Sym, ReallocPair] : RP) {
2828
127
    if (SymReaper.isDead(Sym) || 
SymReaper.isDead(ReallocPair.ReallocatedSym)79
) {
2829
48
      state = state->remove<ReallocPairs>(Sym);
2830
48
    }
2831
127
  }
2832
2833
  // Cleanup the FreeReturnValue Map.
2834
1.11k
  FreeReturnValueTy FR = state->get<FreeReturnValue>();
2835
1.11k
  for (auto [Sym, RetSym] : FR) {
2836
18
    if (SymReaper.isDead(Sym) || 
SymReaper.isDead(RetSym)0
) {
2837
18
      state = state->remove<FreeReturnValue>(Sym);
2838
18
    }
2839
18
  }
2840
2841
  // Generate leak node.
2842
1.11k
  ExplodedNode *N = C.getPredecessor();
2843
1.11k
  if (!Errors.empty()) {
2844
361
    static CheckerProgramPointTag Tag("MallocChecker", "DeadSymbolsLeak");
2845
361
    N = C.generateNonFatalErrorNode(C.getState(), &Tag);
2846
361
    if (N) {
2847
365
      for (SymbolRef Sym : Errors) {
2848
365
        HandleLeak(Sym, N, C);
2849
365
      }
2850
361
    }
2851
361
  }
2852
2853
1.11k
  C.addTransition(state->set<RegionState>(RS), N);
2854
1.11k
}
2855
2856
void MallocChecker::checkPreCall(const CallEvent &Call,
2857
42.4k
                                 CheckerContext &C) const {
2858
2859
42.4k
  if (const auto *DC = dyn_cast<CXXDeallocatorCall>(&Call)) {
2860
369
    const CXXDeleteExpr *DE = DC->getOriginExpr();
2861
2862
369
    if (!ChecksEnabled[CK_NewDeleteChecker])
2863
165
      if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol())
2864
127
        checkUseAfterFree(Sym, C, DE->getArgument());
2865
2866
369
    if (!isStandardNewDelete(DC->getDecl()))
2867
3
      return;
2868
2869
366
    ProgramStateRef State = C.getState();
2870
366
    bool IsKnownToBeAllocated;
2871
366
    State = FreeMemAux(C, DE->getArgument(), Call, State,
2872
366
                       /*Hold*/ false, IsKnownToBeAllocated,
2873
366
                       (DE->isArrayForm() ? 
AF_CXXNewArray62
:
AF_CXXNew304
));
2874
2875
366
    C.addTransition(State);
2876
366
    return;
2877
369
  }
2878
2879
42.0k
  if (const auto *DC = dyn_cast<CXXDestructorCall>(&Call)) {
2880
787
    SymbolRef Sym = DC->getCXXThisVal().getAsSymbol();
2881
787
    if (!Sym || 
checkDoubleDelete(Sym, C)57
)
2882
742
      return;
2883
787
  }
2884
2885
  // We will check for double free in the post visit.
2886
41.2k
  if (const AnyFunctionCall *FC = dyn_cast<AnyFunctionCall>(&Call)) {
2887
41.1k
    const FunctionDecl *FD = FC->getDecl();
2888
41.1k
    if (!FD)
2889
11
      return;
2890
2891
41.1k
    if (ChecksEnabled[CK_MallocChecker] && 
isFreeingCall(Call)9.57k
)
2892
707
      return;
2893
41.1k
  }
2894
2895
  // Check if the callee of a method is deleted.
2896
40.5k
  if (const CXXInstanceCall *CC = dyn_cast<CXXInstanceCall>(&Call)) {
2897
5.38k
    SymbolRef Sym = CC->getCXXThisVal().getAsSymbol();
2898
5.38k
    if (!Sym || 
checkUseAfterFree(Sym, C, CC->getCXXThisExpr())3.39k
)
2899
1.99k
      return;
2900
5.38k
  }
2901
2902
  // Check arguments for being used after free.
2903
75.7k
  
for (unsigned I = 0, E = Call.getNumArgs(); 38.5k
I != E;
++I37.1k
) {
2904
37.2k
    SVal ArgSVal = Call.getArgSVal(I);
2905
37.2k
    if (isa<Loc>(ArgSVal)) {
2906
20.9k
      SymbolRef Sym = ArgSVal.getAsSymbol();
2907
20.9k
      if (!Sym)
2908
15.3k
        continue;
2909
5.67k
      if (checkUseAfterFree(Sym, C, Call.getArgExpr(I)))
2910
109
        return;
2911
5.67k
    }
2912
37.2k
  }
2913
38.5k
}
2914
2915
void MallocChecker::checkPreStmt(const ReturnStmt *S,
2916
7.03k
                                 CheckerContext &C) const {
2917
7.03k
  checkEscapeOnReturn(S, C);
2918
7.03k
}
2919
2920
// In the CFG, automatic destructors come after the return statement.
2921
// This callback checks for returning memory that is freed by automatic
2922
// destructors, as those cannot be reached in checkPreStmt().
2923
void MallocChecker::checkEndFunction(const ReturnStmt *S,
2924
22.3k
                                     CheckerContext &C) const {
2925
22.3k
  checkEscapeOnReturn(S, C);
2926
22.3k
}
2927
2928
void MallocChecker::checkEscapeOnReturn(const ReturnStmt *S,
2929
29.4k
                                        CheckerContext &C) const {
2930
29.4k
  if (!S)
2931
15.4k
    return;
2932
2933
14.0k
  const Expr *E = S->getRetValue();
2934
14.0k
  if (!E)
2935
273
    return;
2936
2937
  // Check if we are returning a symbol.
2938
13.7k
  ProgramStateRef State = C.getState();
2939
13.7k
  SVal RetVal = C.getSVal(E);
2940
13.7k
  SymbolRef Sym = RetVal.getAsSymbol();
2941
13.7k
  if (!Sym)
2942
    // If we are returning a field of the allocated struct or an array element,
2943
    // the callee could still free the memory.
2944
    // TODO: This logic should be a part of generic symbol escape callback.
2945
12.8k
    if (const MemRegion *MR = RetVal.getAsRegion())
2946
744
      if (isa<FieldRegion, ElementRegion>(MR))
2947
294
        if (const SymbolicRegion *BMR =
2948
294
              dyn_cast<SymbolicRegion>(MR->getBaseRegion()))
2949
70
          Sym = BMR->getSymbol();
2950
2951
  // Check if we are returning freed memory.
2952
13.7k
  if (Sym)
2953
983
    checkUseAfterFree(Sym, C, E);
2954
13.7k
}
2955
2956
// TODO: Blocks should be either inlined or should call invalidate regions
2957
// upon invocation. After that's in place, special casing here will not be
2958
// needed.
2959
void MallocChecker::checkPostStmt(const BlockExpr *BE,
2960
58
                                  CheckerContext &C) const {
2961
2962
  // Scan the BlockDecRefExprs for any object the retain count checker
2963
  // may be tracking.
2964
58
  if (!BE->getBlockDecl()->hasCaptures())
2965
53
    return;
2966
2967
5
  ProgramStateRef state = C.getState();
2968
5
  const BlockDataRegion *R =
2969
5
    cast<BlockDataRegion>(C.getSVal(BE).getAsRegion());
2970
2971
5
  auto ReferencedVars = R->referenced_vars();
2972
5
  if (ReferencedVars.empty())
2973
0
    return;
2974
2975
5
  SmallVector<const MemRegion*, 10> Regions;
2976
5
  const LocationContext *LC = C.getLocationContext();
2977
5
  MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager();
2978
2979
5
  for (const auto &Var : ReferencedVars) {
2980
5
    const VarRegion *VR = Var.getCapturedRegion();
2981
5
    if (VR->getSuperRegion() == R) {
2982
1
      VR = MemMgr.getVarRegion(VR->getDecl(), LC);
2983
1
    }
2984
5
    Regions.push_back(VR);
2985
5
  }
2986
2987
5
  state =
2988
5
    state->scanReachableSymbols<StopTrackingCallback>(Regions).getState();
2989
5
  C.addTransition(state);
2990
5
}
2991
2992
23.8k
static bool isReleased(SymbolRef Sym, CheckerContext &C) {
2993
23.8k
  assert(Sym);
2994
23.8k
  const RefState *RS = C.getState()->get<RegionState>(Sym);
2995
23.8k
  return (RS && 
RS->isReleased()2.18k
);
2996
23.8k
}
2997
2998
bool MallocChecker::suppressDeallocationsInSuspiciousContexts(
2999
567
    const CallEvent &Call, CheckerContext &C) const {
3000
567
  if (Call.getNumArgs() == 0)
3001
0
    return false;
3002
3003
567
  StringRef FunctionStr = "";
3004
567
  if (const auto *FD = dyn_cast<FunctionDecl>(C.getStackFrame()->getDecl()))
3005
564
    if (const Stmt *Body = FD->getBody())
3006
564
      if (Body->getBeginLoc().isValid())
3007
564
        FunctionStr =
3008
564
            Lexer::getSourceText(CharSourceRange::getTokenRange(
3009
564
                                     {FD->getBeginLoc(), Body->getBeginLoc()}),
3010
564
                                 C.getSourceManager(), C.getLangOpts());
3011
3012
  // We do not model the Integer Set Library's retain-count based allocation.
3013
567
  if (!FunctionStr.contains("__isl_"))
3014
566
    return false;
3015
3016
1
  ProgramStateRef State = C.getState();
3017
3018
1
  for (const Expr *Arg : cast<CallExpr>(Call.getOriginExpr())->arguments())
3019
1
    if (SymbolRef Sym = C.getSVal(Arg).getAsSymbol())
3020
1
      if (const RefState *RS = State->get<RegionState>(Sym))
3021
0
        State = State->set<RegionState>(Sym, RefState::getEscaped(RS));
3022
3023
1
  C.addTransition(State);
3024
1
  return true;
3025
567
}
3026
3027
bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
3028
23.8k
                                      const Stmt *S) const {
3029
3030
23.8k
  if (isReleased(Sym, C)) {
3031
179
    HandleUseAfterFree(C, S->getSourceRange(), Sym);
3032
179
    return true;
3033
179
  }
3034
3035
23.6k
  return false;
3036
23.8k
}
3037
3038
void MallocChecker::checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C,
3039
13.6k
                                          const Stmt *S) const {
3040
13.6k
  assert(Sym);
3041
3042
13.6k
  if (const RefState *RS = C.getState()->get<RegionState>(Sym)) {
3043
650
    if (RS->isAllocatedOfSizeZero())
3044
32
      HandleUseZeroAlloc(C, RS->getStmt()->getSourceRange(), Sym);
3045
650
  }
3046
13.0k
  else if (C.getState()->contains<ReallocSizeZeroSymbols>(Sym)) {
3047
4
    HandleUseZeroAlloc(C, S->getSourceRange(), Sym);
3048
4
  }
3049
13.6k
}
3050
3051
57
bool MallocChecker::checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const {
3052
3053
57
  if (isReleased(Sym, C)) {
3054
12
    HandleDoubleDelete(C, Sym);
3055
12
    return true;
3056
12
  }
3057
45
  return false;
3058
57
}
3059
3060
// Check if the location is a freed symbolic region.
3061
void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
3062
76.1k
                                  CheckerContext &C) const {
3063
76.1k
  SymbolRef Sym = l.getLocSymbolInBase();
3064
76.1k
  if (Sym) {
3065
13.6k
    checkUseAfterFree(Sym, C, S);
3066
13.6k
    checkUseZeroAllocated(Sym, C, S);
3067
13.6k
  }
3068
76.1k
}
3069
3070
// If a symbolic region is assumed to NULL (or another constant), stop tracking
3071
// it - assuming that allocation failed on this path.
3072
ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state,
3073
                                              SVal Cond,
3074
202k
                                              bool Assumption) const {
3075
202k
  RegionStateTy RS = state->get<RegionState>();
3076
202k
  for (SymbolRef Sym : llvm::make_first_range(RS)) {
3077
    // If the symbol is assumed to be NULL, remove it from consideration.
3078
16.9k
    ConstraintManager &CMgr = state->getConstraintManager();
3079
16.9k
    ConditionTruthVal AllocFailed = CMgr.isNull(state, Sym);
3080
16.9k
    if (AllocFailed.isConstrainedTrue())
3081
762
      state = state->remove<RegionState>(Sym);
3082
16.9k
  }
3083
3084
  // Realloc returns 0 when reallocation fails, which means that we should
3085
  // restore the state of the pointer being reallocated.
3086
202k
  ReallocPairsTy RP = state->get<ReallocPairs>();
3087
202k
  for (auto [Sym, ReallocPair] : RP) {
3088
    // If the symbol is assumed to be NULL, remove it from consideration.
3089
1.14k
    ConstraintManager &CMgr = state->getConstraintManager();
3090
1.14k
    ConditionTruthVal AllocFailed = CMgr.isNull(state, Sym);
3091
1.14k
    if (!AllocFailed.isConstrainedTrue())
3092
1.10k
      continue;
3093
3094
39
    SymbolRef ReallocSym = ReallocPair.ReallocatedSym;
3095
39
    if (const RefState *RS = state->get<RegionState>(ReallocSym)) {
3096
39
      if (RS->isReleased()) {
3097
39
        switch (ReallocPair.Kind) {
3098
32
        case OAR_ToBeFreedAfterFailure:
3099
32
          state = state->set<RegionState>(ReallocSym,
3100
32
              RefState::getAllocated(RS->getAllocationFamily(), RS->getStmt()));
3101
32
          break;
3102
5
        case OAR_DoNotTrackAfterFailure:
3103
5
          state = state->remove<RegionState>(ReallocSym);
3104
5
          break;
3105
2
        default:
3106
2
          assert(ReallocPair.Kind == OAR_FreeOnFailure);
3107
39
        }
3108
39
      }
3109
39
    }
3110
39
    state = state->remove<ReallocPairs>(Sym);
3111
39
  }
3112
3113
202k
  return state;
3114
202k
}
3115
3116
bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
3117
                                              const CallEvent *Call,
3118
                                              ProgramStateRef State,
3119
3.14k
                                              SymbolRef &EscapingSymbol) const {
3120
3.14k
  assert(Call);
3121
3.14k
  EscapingSymbol = nullptr;
3122
3123
  // For now, assume that any C++ or block call can free memory.
3124
  // TODO: If we want to be more optimistic here, we'll need to make sure that
3125
  // regions escape to C++ containers. They seem to do that even now, but for
3126
  // mysterious reasons.
3127
3.14k
  if (!isa<SimpleFunctionCall, ObjCMethodCall>(Call))
3128
2.03k
    return true;
3129
3130
  // Check Objective-C messages by selector name.
3131
1.11k
  if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) {
3132
    // If it's not a framework call, or if it takes a callback, assume it
3133
    // can free memory.
3134
69
    if (!Call->isInSystemHeader() || 
Call->argumentsMayEscape()58
)
3135
13
      return true;
3136
3137
    // If it's a method we know about, handle it explicitly post-call.
3138
    // This should happen before the "freeWhenDone" check below.
3139
56
    if (isKnownDeallocObjCMethodName(*Msg))
3140
31
      return false;
3141
3142
    // If there's a "freeWhenDone" parameter, but the method isn't one we know
3143
    // about, we can't be sure that the object will use free() to deallocate the
3144
    // memory, so we can't model it explicitly. The best we can do is use it to
3145
    // decide whether the pointer escapes.
3146
25
    if (std::optional<bool> FreeWhenDone = getFreeWhenDoneArg(*Msg))
3147
4
      return *FreeWhenDone;
3148
3149
    // If the first selector piece ends with "NoCopy", and there is no
3150
    // "freeWhenDone" parameter set to zero, we know ownership is being
3151
    // transferred. Again, though, we can't be sure that the object will use
3152
    // free() to deallocate the memory, so we can't model it explicitly.
3153
21
    StringRef FirstSlot = Msg->getSelector().getNameForSlot(0);
3154
21
    if (FirstSlot.endswith("NoCopy"))
3155
1
      return true;
3156
3157
    // If the first selector starts with addPointer, insertPointer,
3158
    // or replacePointer, assume we are dealing with NSPointerArray or similar.
3159
    // This is similar to C++ containers (vector); we still might want to check
3160
    // that the pointers get freed by following the container itself.
3161
20
    if (FirstSlot.startswith("addPointer") ||
3162
20
        
FirstSlot.startswith("insertPointer")19
||
3163
20
        
FirstSlot.startswith("replacePointer")17
||
3164
20
        
FirstSlot.equals("valueWithPointer")14
) {
3165
6
      return true;
3166
6
    }
3167
3168
    // We should escape receiver on call to 'init'. This is especially relevant
3169
    // to the receiver, as the corresponding symbol is usually not referenced
3170
    // after the call.
3171
14
    if (Msg->getMethodFamily() == OMF_init) {
3172
8
      EscapingSymbol = Msg->getReceiverSVal().getAsSymbol();
3173
8
      return true;
3174
8
    }
3175
3176
    // Otherwise, assume that the method does not free memory.
3177
    // Most framework methods do not free memory.
3178
6
    return false;
3179
14
  }
3180
3181
  // At this point the only thing left to handle is straight function calls.
3182
1.04k
  const FunctionDecl *FD = cast<SimpleFunctionCall>(Call)->getDecl();
3183
1.04k
  if (!FD)
3184
2
    return true;
3185
3186
  // If it's one of the allocation functions we can reason about, we model
3187
  // its behavior explicitly.
3188
1.04k
  if (isMemCall(*Call))
3189
592
    return false;
3190
3191
  // If it's not a system call, assume it frees memory.
3192
448
  if (!Call->isInSystemHeader())
3193
384
    return true;
3194
3195
  // White list the system functions whose arguments escape.
3196
64
  const IdentifierInfo *II = FD->getIdentifier();
3197
64
  if (!II)
3198
25
    return true;
3199
39
  StringRef FName = II->getName();
3200
3201
  // White list the 'XXXNoCopy' CoreFoundation functions.
3202
  // We specifically check these before
3203
39
  if (FName.endswith("NoCopy")) {
3204
    // Look for the deallocator argument. We know that the memory ownership
3205
    // is not transferred only if the deallocator argument is
3206
    // 'kCFAllocatorNull'.
3207
8
    for (unsigned i = 1; i < Call->getNumArgs(); 
++i6
) {
3208
7
      const Expr *ArgE = Call->getArgExpr(i)->IgnoreParenCasts();
3209
7
      if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) {
3210
4
        StringRef DeallocatorName = DE->getFoundDecl()->getName();
3211
4
        if (DeallocatorName == "kCFAllocatorNull")
3212
1
          return false;
3213
4
      }
3214
7
    }
3215
1
    return true;
3216
2
  }
3217
3218
  // Associating streams with malloced buffers. The pointer can escape if
3219
  // 'closefn' is specified (and if that function does free memory),
3220
  // but it will not if closefn is not specified.
3221
  // Currently, we do not inspect the 'closefn' function (PR12101).
3222
37
  if (FName == "funopen")
3223
3
    if (Call->getNumArgs() >= 4 && Call->getArgSVal(4).isConstant(0))
3224
2
      return false;
3225
3226
  // Do not warn on pointers passed to 'setbuf' when used with std streams,
3227
  // these leaks might be intentional when setting the buffer for stdio.
3228
  // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer
3229
35
  if (FName == "setbuf" || 
FName =="setbuffer"34
||
3230
35
      
FName == "setlinebuf"34
||
FName == "setvbuf"34
) {
3231
3
    if (Call->getNumArgs() >= 1) {
3232
3
      const Expr *ArgE = Call->getArgExpr(0)->IgnoreParenCasts();
3233
3
      if (const DeclRefExpr *ArgDRE = dyn_cast<DeclRefExpr>(ArgE))
3234
3
        if (const VarDecl *D = dyn_cast<VarDecl>(ArgDRE->getDecl()))
3235
3
          if (D->getCanonicalDecl()->getName().contains("std"))
3236
2
            return true;
3237
3
    }
3238
3
  }
3239
3240
  // A bunch of other functions which either take ownership of a pointer or
3241
  // wrap the result up in a struct or object, meaning it can be freed later.
3242
  // (See RetainCountChecker.) Not all the parameters here are invalidated,
3243
  // but the Malloc checker cannot differentiate between them. The right way
3244
  // of doing this would be to implement a pointer escapes callback.
3245
33
  if (FName == "CGBitmapContextCreate" ||
3246
33
      
FName == "CGBitmapContextCreateWithData"31
||
3247
33
      
FName == "CVPixelBufferCreateWithBytes"31
||
3248
33
      
FName == "CVPixelBufferCreateWithPlanarBytes"31
||
3249
33
      
FName == "OSAtomicEnqueue"31
) {
3250
2
    return true;
3251
2
  }
3252
3253
31
  if (FName == "postEvent" &&
3254
31
      
FD->getQualifiedNameAsString() == "QCoreApplication::postEvent"4
) {
3255
4
    return true;
3256
4
  }
3257
3258
27
  if (FName == "connectImpl" &&
3259
27
      
FD->getQualifiedNameAsString() == "QObject::connectImpl"1
) {
3260
1
    return true;
3261
1
  }
3262
3263
26
  if (FName == "singleShotImpl" &&
3264
26
      
FD->getQualifiedNameAsString() == "QTimer::singleShotImpl"1
) {
3265
1
    return true;
3266
1
  }
3267
3268
  // Handle cases where we know a buffer's /address/ can escape.
3269
  // Note that the above checks handle some special cases where we know that
3270
  // even though the address escapes, it's still our responsibility to free the
3271
  // buffer.
3272
25
  if (Call->argumentsMayEscape())
3273
15
    return true;
3274
3275
  // Otherwise, assume that the function does not free memory.
3276
  // Most system calls do not free the memory.
3277
10
  return false;
3278
25
}
3279
3280
ProgramStateRef MallocChecker::checkPointerEscape(ProgramStateRef State,
3281
                                             const InvalidatedSymbols &Escaped,
3282
                                             const CallEvent *Call,
3283
14.4k
                                             PointerEscapeKind Kind) const {
3284
14.4k
  return checkPointerEscapeAux(State, Escaped, Call, Kind,
3285
14.4k
                               /*IsConstPointerEscape*/ false);
3286
14.4k
}
3287
3288
ProgramStateRef MallocChecker::checkConstPointerEscape(ProgramStateRef State,
3289
                                              const InvalidatedSymbols &Escaped,
3290
                                              const CallEvent *Call,
3291
1.33k
                                              PointerEscapeKind Kind) const {
3292
  // If a const pointer escapes, it may not be freed(), but it could be deleted.
3293
1.33k
  return checkPointerEscapeAux(State, Escaped, Call, Kind,
3294
1.33k
                               /*IsConstPointerEscape*/ true);
3295
1.33k
}
3296
3297
42
static bool checkIfNewOrNewArrayFamily(const RefState *RS) {
3298
42
  return (RS->getAllocationFamily() == AF_CXXNewArray ||
3299
42
          
RS->getAllocationFamily() == AF_CXXNew41
);
3300
42
}
3301
3302
ProgramStateRef MallocChecker::checkPointerEscapeAux(
3303
    ProgramStateRef State, const InvalidatedSymbols &Escaped,
3304
    const CallEvent *Call, PointerEscapeKind Kind,
3305
15.8k
    bool IsConstPointerEscape) const {
3306
  // If we know that the call does not free memory, or we want to process the
3307
  // call later, keep tracking the top level arguments.
3308
15.8k
  SymbolRef EscapingSymbol = nullptr;
3309
15.8k
  if (Kind == PSK_DirectEscapeOnCall &&
3310
15.8k
      !mayFreeAnyEscapedMemoryOrIsModeledExplicitly(Call, State,
3311
3.14k
                                                    EscapingSymbol) &&
3312
15.8k
      
!EscapingSymbol644
) {
3313
644
    return State;
3314
644
  }
3315
3316
32.3k
  
for (SymbolRef sym : Escaped)15.1k
{
3317
32.3k
    if (EscapingSymbol && 
EscapingSymbol != sym9
)
3318
1
      continue;
3319
3320
32.3k
    if (const RefState *RS = State->get<RegionState>(sym))
3321
790
      if (RS->isAllocated() || 
RS->isAllocatedOfSizeZero()356
)
3322
436
        if (!IsConstPointerEscape || 
checkIfNewOrNewArrayFamily(RS)42
)
3323
421
          State = State->set<RegionState>(sym, RefState::getEscaped(RS));
3324
32.3k
  }
3325
15.1k
  return State;
3326
15.8k
}
3327
3328
bool MallocChecker::isArgZERO_SIZE_PTR(ProgramStateRef State, CheckerContext &C,
3329
14
                                       SVal ArgVal) const {
3330
14
  if (!KernelZeroSizePtrValue)
3331
5
    KernelZeroSizePtrValue =
3332
5
        tryExpandAsInteger("ZERO_SIZE_PTR", C.getPreprocessor());
3333
3334
14
  const llvm::APSInt *ArgValKnown =
3335
14
      C.getSValBuilder().getKnownValue(State, ArgVal);
3336
14
  return ArgValKnown && 
*KernelZeroSizePtrValue8
&&
3337
14
         
ArgValKnown->getSExtValue() == **KernelZeroSizePtrValue2
;
3338
14
}
3339
3340
static SymbolRef findFailedReallocSymbol(ProgramStateRef currState,
3341
6
                                         ProgramStateRef prevState) {
3342
6
  ReallocPairsTy currMap = currState->get<ReallocPairs>();
3343
6
  ReallocPairsTy prevMap = prevState->get<ReallocPairs>();
3344
3345
6
  for (const ReallocPairsTy::value_type &Pair : prevMap) {
3346
6
    SymbolRef sym = Pair.first;
3347
6
    if (!currMap.lookup(sym))
3348
6
      return sym;
3349
6
  }
3350
3351
0
  return nullptr;
3352
6
}
3353
3354
25
static bool isReferenceCountingPointerDestructor(const CXXDestructorDecl *DD) {
3355
25
  if (const IdentifierInfo *II = DD->getParent()->getIdentifier()) {
3356
25
    StringRef N = II->getName();
3357
25
    if (N.contains_insensitive("ptr") || 
N.contains_insensitive("pointer")17
) {
3358
16
      if (N.contains_insensitive("ref") || N.contains_insensitive("cnt") ||
3359
16
          N.contains_insensitive("intrusive") ||
3360
16
          
N.contains_insensitive("shared")8
) {
3361
8
        return true;
3362
8
      }
3363
16
    }
3364
25
  }
3365
17
  return false;
3366
25
}
3367
3368
PathDiagnosticPieceRef MallocBugVisitor::VisitNode(const ExplodedNode *N,
3369
                                                   BugReporterContext &BRC,
3370
26.3k
                                                   PathSensitiveBugReport &BR) {
3371
26.3k
  ProgramStateRef state = N->getState();
3372
26.3k
  ProgramStateRef statePrev = N->getFirstPred()->getState();
3373
3374
26.3k
  const RefState *RSCurr = state->get<RegionState>(Sym);
3375
26.3k
  const RefState *RSPrev = statePrev->get<RegionState>(Sym);
3376
3377
26.3k
  const Stmt *S = N->getStmtForDiagnostics();
3378
  // When dealing with containers, we sometimes want to give a note
3379
  // even if the statement is missing.
3380
26.3k
  if (!S && 
(1.84k
!RSCurr1.84k
||
RSCurr->getAllocationFamily() != AF_InnerBuffer907
))
3381
1.82k
    return nullptr;
3382
3383
24.5k
  const LocationContext *CurrentLC = N->getLocationContext();
3384
3385
  // If we find an atomic fetch_add or fetch_sub within the destructor in which
3386
  // the pointer was released (before the release), this is likely a destructor
3387
  // of a shared pointer.
3388
  // Because we don't model atomics, and also because we don't know that the
3389
  // original reference count is positive, we should not report use-after-frees
3390
  // on objects deleted in such destructors. This can probably be improved
3391
  // through better shared pointer modeling.
3392
24.5k
  if (ReleaseDestructorLC) {
3393
835
    if (const auto *AE = dyn_cast<AtomicExpr>(S)) {
3394
0
      AtomicExpr::AtomicOp Op = AE->getOp();
3395
0
      if (Op == AtomicExpr::AO__c11_atomic_fetch_add ||
3396
0
          Op == AtomicExpr::AO__c11_atomic_fetch_sub) {
3397
0
        if (ReleaseDestructorLC == CurrentLC ||
3398
0
            ReleaseDestructorLC->isParentOf(CurrentLC)) {
3399
0
          BR.markInvalid(getTag(), S);
3400
0
        }
3401
0
      }
3402
0
    }
3403
835
  }
3404
3405
  // FIXME: We will eventually need to handle non-statement-based events
3406
  // (__attribute__((cleanup))).
3407
3408
  // Find out if this is an interesting point and what is the kind.
3409
24.5k
  StringRef Msg;
3410
24.5k
  std::unique_ptr<StackHintGeneratorForSymbol> StackHint = nullptr;
3411
24.5k
  SmallString<256> Buf;
3412
24.5k
  llvm::raw_svector_ostream OS(Buf);
3413
3414
24.5k
  if (Mode == Normal) {
3415
24.5k
    if (isAllocated(RSCurr, RSPrev, S)) {
3416
435
      Msg = "Memory is allocated";
3417
435
      StackHint = std::make_unique<StackHintGeneratorForSymbol>(
3418
435
          Sym, "Returned allocated memory");
3419
24.0k
    } else if (isReleased(RSCurr, RSPrev, S)) {
3420
173
      const auto Family = RSCurr->getAllocationFamily();
3421
173
      switch (Family) {
3422
0
        case AF_Alloca:
3423
74
        case AF_Malloc:
3424
141
        case AF_CXXNew:
3425
142
        case AF_CXXNewArray:
3426
142
        case AF_IfNameIndex:
3427
142
          Msg = "Memory is released";
3428
142
          StackHint = std::make_unique<StackHintGeneratorForSymbol>(
3429
142
              Sym, "Returning; memory was released");
3430
142
          break;
3431
31
        case AF_InnerBuffer: {
3432
31
          const MemRegion *ObjRegion =
3433
31
              allocation_state::getContainerObjRegion(statePrev, Sym);
3434
31
          const auto *TypedRegion = cast<TypedValueRegion>(ObjRegion);
3435
31
          QualType ObjTy = TypedRegion->getValueType();
3436
31
          OS << "Inner buffer of '" << ObjTy << "' ";
3437
3438
31
          if (N->getLocation().getKind() == ProgramPoint::PostImplicitCallKind) {
3439
12
            OS << "deallocated by call to destructor";
3440
12
            StackHint = std::make_unique<StackHintGeneratorForSymbol>(
3441
12
                Sym, "Returning; inner buffer was deallocated");
3442
19
          } else {
3443
19
            OS << "reallocated by call to '";
3444
19
            const Stmt *S = RSCurr->getStmt();
3445
19
            if (const auto *MemCallE = dyn_cast<CXXMemberCallExpr>(S)) {
3446
14
              OS << MemCallE->getMethodDecl()->getDeclName();
3447
14
            } else 
if (const auto *5
OpCallE5
= dyn_cast<CXXOperatorCallExpr>(S)) {
3448
2
              OS << OpCallE->getDirectCallee()->getDeclName();
3449
3
            } else if (const auto *CallE = dyn_cast<CallExpr>(S)) {
3450
3
              auto &CEMgr = BRC.getStateManager().getCallEventManager();
3451
3
              CallEventRef<> Call =
3452
3
                  CEMgr.getSimpleCall(CallE, state, CurrentLC, {nullptr, 0});
3453
3
              if (const auto *D = dyn_cast_or_null<NamedDecl>(Call->getDecl()))
3454
3
                OS << D->getDeclName();
3455
0
              else
3456
0
                OS << "unknown";
3457
3
            }
3458
19
            OS << "'";
3459
19
            StackHint = std::make_unique<StackHintGeneratorForSymbol>(
3460
19
                Sym, "Returning; inner buffer was reallocated");
3461
19
          }
3462
31
          Msg = OS.str();
3463
31
          break;
3464
142
        }
3465
0
        case AF_None:
3466
0
          llvm_unreachable("Unhandled allocation family!");
3467
173
      }
3468
3469
      // See if we're releasing memory while inlining a destructor
3470
      // (or one of its callees). This turns on various common
3471
      // false positive suppressions.
3472
173
      bool FoundAnyDestructor = false;
3473
386
      for (const LocationContext *LC = CurrentLC; LC; 
LC = LC->getParent()213
) {
3474
213
        if (const auto *DD = dyn_cast<CXXDestructorDecl>(LC->getDecl())) {
3475
25
          if (isReferenceCountingPointerDestructor(DD)) {
3476
            // This immediately looks like a reference-counting destructor.
3477
            // We're bad at guessing the original reference count of the object,
3478
            // so suppress the report for now.
3479
8
            BR.markInvalid(getTag(), DD);
3480
17
          } else if (!FoundAnyDestructor) {
3481
11
            assert(!ReleaseDestructorLC &&
3482
11
                   "There can be only one release point!");
3483
            // Suspect that it's a reference counting pointer destructor.
3484
            // On one of the next nodes might find out that it has atomic
3485
            // reference counting operations within it (see the code above),
3486
            // and if so, we'd conclude that it likely is a reference counting
3487
            // pointer destructor.
3488
11
            ReleaseDestructorLC = LC->getStackFrame();
3489
            // It is unlikely that releasing memory is delegated to a destructor
3490
            // inside a destructor of a shared pointer, because it's fairly hard
3491
            // to pass the information that the pointer indeed needs to be
3492
            // released into it. So we're only interested in the innermost
3493
            // destructor.
3494
11
            FoundAnyDestructor = true;
3495
11
          }
3496
25
        }
3497
213
      }
3498
23.8k
    } else if (isRelinquished(RSCurr, RSPrev, S)) {
3499
6
      Msg = "Memory ownership is transferred";
3500
6
      StackHint = std::make_unique<StackHintGeneratorForSymbol>(Sym, "");
3501
23.8k
    } else if (hasReallocFailed(RSCurr, RSPrev, S)) {
3502
6
      Mode = ReallocationFailed;
3503
6
      Msg = "Reallocation failed";
3504
6
      StackHint = std::make_unique<StackHintGeneratorForReallocationFailed>(
3505
6
          Sym, "Reallocation failed");
3506
3507
6
      if (SymbolRef sym = findFailedReallocSymbol(state, statePrev)) {
3508
        // Is it possible to fail two reallocs WITHOUT testing in between?
3509
6
        assert((!FailedReallocSymbol || FailedReallocSymbol == sym) &&
3510
6
          "We only support one failed realloc at a time.");
3511
6
        BR.markInteresting(sym);
3512
6
        FailedReallocSymbol = sym;
3513
6
      }
3514
6
    }
3515
3516
  // We are in a special mode if a reallocation failed later in the path.
3517
24.5k
  } else 
if (73
Mode == ReallocationFailed73
) {
3518
73
    assert(FailedReallocSymbol && "No symbol to look for.");
3519
3520
    // Is this is the first appearance of the reallocated symbol?
3521
73
    if (!statePrev->get<RegionState>(FailedReallocSymbol)) {
3522
      // We're at the reallocation point.
3523
6
      Msg = "Attempt to reallocate memory";
3524
6
      StackHint = std::make_unique<StackHintGeneratorForSymbol>(
3525
6
          Sym, "Returned reallocated memory");
3526
6
      FailedReallocSymbol = nullptr;
3527
6
      Mode = Normal;
3528
6
    }
3529
73
  }
3530
3531
24.5k
  if (Msg.empty()) {
3532
23.9k
    assert(!StackHint);
3533
23.9k
    return nullptr;
3534
23.9k
  }
3535
3536
626
  assert(StackHint);
3537
3538
  // Generate the extra diagnostic.
3539
626
  PathDiagnosticLocation Pos;
3540
626
  if (!S) {
3541
12
    assert(RSCurr->getAllocationFamily() == AF_InnerBuffer);
3542
12
    auto PostImplCall = N->getLocation().getAs<PostImplicitCall>();
3543
12
    if (!PostImplCall)
3544
0
      return nullptr;
3545
12
    Pos = PathDiagnosticLocation(PostImplCall->getLocation(),
3546
12
                                 BRC.getSourceManager());
3547
614
  } else {
3548
614
    Pos = PathDiagnosticLocation(S, BRC.getSourceManager(),
3549
614
                                 N->getLocationContext());
3550
614
  }
3551
3552
626
  auto P = std::make_shared<PathDiagnosticEventPiece>(Pos, Msg, true);
3553
626
  BR.addCallStackHint(P, std::move(StackHint));
3554
626
  return P;
3555
626
}
3556
3557
void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State,
3558
36
                               const char *NL, const char *Sep) const {
3559
3560
36
  RegionStateTy RS = State->get<RegionState>();
3561
3562
36
  if (!RS.isEmpty()) {
3563
0
    Out << Sep << "MallocChecker :" << NL;
3564
0
    for (auto [Sym, Data] : RS) {
3565
0
      const RefState *RefS = State->get<RegionState>(Sym);
3566
0
      AllocationFamily Family = RefS->getAllocationFamily();
3567
0
      std::optional<MallocChecker::CheckKind> CheckKind =
3568
0
          getCheckIfTracked(Family);
3569
0
      if (!CheckKind)
3570
0
        CheckKind = getCheckIfTracked(Family, true);
3571
3572
0
      Sym->dumpToStream(Out);
3573
0
      Out << " : ";
3574
0
      Data.dump(Out);
3575
0
      if (CheckKind)
3576
0
        Out << " (" << CheckNames[*CheckKind].getName() << ")";
3577
0
      Out << NL;
3578
0
    }
3579
0
  }
3580
36
}
3581
3582
namespace clang {
3583
namespace ento {
3584
namespace allocation_state {
3585
3586
ProgramStateRef
3587
40
markReleased(ProgramStateRef State, SymbolRef Sym, const Expr *Origin) {
3588
40
  AllocationFamily Family = AF_InnerBuffer;
3589
40
  return State->set<RegionState>(Sym, RefState::getReleased(Family, Origin));
3590
40
}
3591
3592
} // end namespace allocation_state
3593
} // end namespace ento
3594
} // end namespace clang
3595
3596
// Intended to be used in InnerPointerChecker to register the part of
3597
// MallocChecker connected to it.
3598
66
void ento::registerInnerPointerCheckerAux(CheckerManager &mgr) {
3599
66
  MallocChecker *checker = mgr.getChecker<MallocChecker>();
3600
66
  checker->ChecksEnabled[MallocChecker::CK_InnerPointerChecker] = true;
3601
66
  checker->CheckNames[MallocChecker::CK_InnerPointerChecker] =
3602
66
      mgr.getCurrentCheckerName();
3603
66
}
3604
3605
244
void ento::registerDynamicMemoryModeling(CheckerManager &mgr) {
3606
244
  auto *checker = mgr.registerChecker<MallocChecker>();
3607
244
  checker->ShouldIncludeOwnershipAnnotatedFunctions =
3608
244
      mgr.getAnalyzerOptions().getCheckerBooleanOption(checker, "Optimistic");
3609
244
  checker->ShouldRegisterNoOwnershipChangeVisitor =
3610
244
      mgr.getAnalyzerOptions().getCheckerBooleanOption(
3611
244
          checker, "AddNoOwnershipChangeNotes");
3612
244
}
3613
3614
1.26k
bool ento::shouldRegisterDynamicMemoryModeling(const CheckerManager &mgr) {
3615
1.26k
  return true;
3616
1.26k
}
3617
3618
#define REGISTER_CHECKER(name)                                                 \
3619
427
  void ento::register##name(CheckerManager &mgr) {                             \
3620
427
    MallocChecker *checker = mgr.getChecker<MallocChecker>();                  \
3621
427
    checker->ChecksEnabled[MallocChecker::CK_##name] = true;                   \
3622
427
    checker->CheckNames[MallocChecker::CK_##name] =                            \
3623
427
        mgr.getCurrentCheckerName();                                           \
3624
427
  }                                                                            \
clang::ento::registerMallocChecker(clang::ento::CheckerManager&)
Line
Count
Source
3619
159
  void ento::register##name(CheckerManager &mgr) {                             \
3620
159
    MallocChecker *checker = mgr.getChecker<MallocChecker>();                  \
3621
159
    checker->ChecksEnabled[MallocChecker::CK_##name] = true;                   \
3622
159
    checker->CheckNames[MallocChecker::CK_##name] =                            \
3623
159
        mgr.getCurrentCheckerName();                                           \
3624
159
  }                                                                            \
clang::ento::registerNewDeleteChecker(clang::ento::CheckerManager&)
Line
Count
Source
3619
103
  void ento::register##name(CheckerManager &mgr) {                             \
3620
103
    MallocChecker *checker = mgr.getChecker<MallocChecker>();                  \
3621
103
    checker->ChecksEnabled[MallocChecker::CK_##name] = true;                   \
3622
103
    checker->CheckNames[MallocChecker::CK_##name] =                            \
3623
103
        mgr.getCurrentCheckerName();                                           \
3624
103
  }                                                                            \
clang::ento::registerNewDeleteLeaksChecker(clang::ento::CheckerManager&)
Line
Count
Source
3619
87
  void ento::register##name(CheckerManager &mgr) {                             \
3620
87
    MallocChecker *checker = mgr.getChecker<MallocChecker>();                  \
3621
87
    checker->ChecksEnabled[MallocChecker::CK_##name] = true;                   \
3622
87
    checker->CheckNames[MallocChecker::CK_##name] =                            \
3623
87
        mgr.getCurrentCheckerName();                                           \
3624
87
  }                                                                            \
clang::ento::registerMismatchedDeallocatorChecker(clang::ento::CheckerManager&)
Line
Count
Source
3619
78
  void ento::register##name(CheckerManager &mgr) {                             \
3620
78
    MallocChecker *checker = mgr.getChecker<MallocChecker>();                  \
3621
78
    checker->ChecksEnabled[MallocChecker::CK_##name] = true;                   \
3622
78
    checker->CheckNames[MallocChecker::CK_##name] =                            \
3623
78
        mgr.getCurrentCheckerName();                                           \
3624
78
  }                                                                            \
3625
                                                                               \
3626
862
  bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
clang::ento::shouldRegisterMallocChecker(clang::ento::CheckerManager const&)
Line
Count
Source
3626
322
  bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
clang::ento::shouldRegisterNewDeleteChecker(clang::ento::CheckerManager const&)
Line
Count
Source
3626
206
  bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
clang::ento::shouldRegisterNewDeleteLeaksChecker(clang::ento::CheckerManager const&)
Line
Count
Source
3626
174
  bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
clang::ento::shouldRegisterMismatchedDeallocatorChecker(clang::ento::CheckerManager const&)
Line
Count
Source
3626
160
  bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
3627
3628
REGISTER_CHECKER(MallocChecker)
3629
REGISTER_CHECKER(NewDeleteChecker)
3630
REGISTER_CHECKER(NewDeleteLeaksChecker)
3631
REGISTER_CHECKER(MismatchedDeallocatorChecker)