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