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