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