xref: /aosp_15_r20/external/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //=== MallocChecker.cpp - A malloc/free checker -------------------*- C++ -*--//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file defines malloc/free checker, which checks for potential memory
11*67e74705SXin Li // leaks, double free, and use-after-free problems.
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li 
15*67e74705SXin Li #include "ClangSACheckers.h"
16*67e74705SXin Li #include "InterCheckerAPI.h"
17*67e74705SXin Li #include "clang/AST/Attr.h"
18*67e74705SXin Li #include "clang/AST/ParentMap.h"
19*67e74705SXin Li #include "clang/Basic/SourceManager.h"
20*67e74705SXin Li #include "clang/Basic/TargetInfo.h"
21*67e74705SXin Li #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
22*67e74705SXin Li #include "clang/StaticAnalyzer/Core/Checker.h"
23*67e74705SXin Li #include "clang/StaticAnalyzer/Core/CheckerManager.h"
24*67e74705SXin Li #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
25*67e74705SXin Li #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
26*67e74705SXin Li #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
27*67e74705SXin Li #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
28*67e74705SXin Li #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
29*67e74705SXin Li #include "llvm/ADT/ImmutableMap.h"
30*67e74705SXin Li #include "llvm/ADT/STLExtras.h"
31*67e74705SXin Li #include "llvm/ADT/SmallString.h"
32*67e74705SXin Li #include "llvm/ADT/StringExtras.h"
33*67e74705SXin Li #include <climits>
34*67e74705SXin Li #include <utility>
35*67e74705SXin Li 
36*67e74705SXin Li using namespace clang;
37*67e74705SXin Li using namespace ento;
38*67e74705SXin Li 
39*67e74705SXin Li namespace {
40*67e74705SXin Li 
41*67e74705SXin Li // Used to check correspondence between allocators and deallocators.
42*67e74705SXin Li enum AllocationFamily {
43*67e74705SXin Li   AF_None,
44*67e74705SXin Li   AF_Malloc,
45*67e74705SXin Li   AF_CXXNew,
46*67e74705SXin Li   AF_CXXNewArray,
47*67e74705SXin Li   AF_IfNameIndex,
48*67e74705SXin Li   AF_Alloca
49*67e74705SXin Li };
50*67e74705SXin Li 
51*67e74705SXin Li class RefState {
52*67e74705SXin Li   enum Kind { // Reference to allocated memory.
53*67e74705SXin Li               Allocated,
54*67e74705SXin Li               // Reference to zero-allocated memory.
55*67e74705SXin Li               AllocatedOfSizeZero,
56*67e74705SXin Li               // Reference to released/freed memory.
57*67e74705SXin Li               Released,
58*67e74705SXin Li               // The responsibility for freeing resources has transferred from
59*67e74705SXin Li               // this reference. A relinquished symbol should not be freed.
60*67e74705SXin Li               Relinquished,
61*67e74705SXin Li               // We are no longer guaranteed to have observed all manipulations
62*67e74705SXin Li               // of this pointer/memory. For example, it could have been
63*67e74705SXin Li               // passed as a parameter to an opaque function.
64*67e74705SXin Li               Escaped
65*67e74705SXin Li   };
66*67e74705SXin Li 
67*67e74705SXin Li   const Stmt *S;
68*67e74705SXin Li   unsigned K : 3; // Kind enum, but stored as a bitfield.
69*67e74705SXin Li   unsigned Family : 29; // Rest of 32-bit word, currently just an allocation
70*67e74705SXin Li                         // family.
71*67e74705SXin Li 
RefState(Kind k,const Stmt * s,unsigned family)72*67e74705SXin Li   RefState(Kind k, const Stmt *s, unsigned family)
73*67e74705SXin Li     : S(s), K(k), Family(family) {
74*67e74705SXin Li     assert(family != AF_None);
75*67e74705SXin Li   }
76*67e74705SXin Li public:
isAllocated() const77*67e74705SXin Li   bool isAllocated() const { return K == Allocated; }
isAllocatedOfSizeZero() const78*67e74705SXin Li   bool isAllocatedOfSizeZero() const { return K == AllocatedOfSizeZero; }
isReleased() const79*67e74705SXin Li   bool isReleased() const { return K == Released; }
isRelinquished() const80*67e74705SXin Li   bool isRelinquished() const { return K == Relinquished; }
isEscaped() const81*67e74705SXin Li   bool isEscaped() const { return K == Escaped; }
getAllocationFamily() const82*67e74705SXin Li   AllocationFamily getAllocationFamily() const {
83*67e74705SXin Li     return (AllocationFamily)Family;
84*67e74705SXin Li   }
getStmt() const85*67e74705SXin Li   const Stmt *getStmt() const { return S; }
86*67e74705SXin Li 
operator ==(const RefState & X) const87*67e74705SXin Li   bool operator==(const RefState &X) const {
88*67e74705SXin Li     return K == X.K && S == X.S && Family == X.Family;
89*67e74705SXin Li   }
90*67e74705SXin Li 
getAllocated(unsigned family,const Stmt * s)91*67e74705SXin Li   static RefState getAllocated(unsigned family, const Stmt *s) {
92*67e74705SXin Li     return RefState(Allocated, s, family);
93*67e74705SXin Li   }
getAllocatedOfSizeZero(const RefState * RS)94*67e74705SXin Li   static RefState getAllocatedOfSizeZero(const RefState *RS) {
95*67e74705SXin Li     return RefState(AllocatedOfSizeZero, RS->getStmt(),
96*67e74705SXin Li                     RS->getAllocationFamily());
97*67e74705SXin Li   }
getReleased(unsigned family,const Stmt * s)98*67e74705SXin Li   static RefState getReleased(unsigned family, const Stmt *s) {
99*67e74705SXin Li     return RefState(Released, s, family);
100*67e74705SXin Li   }
getRelinquished(unsigned family,const Stmt * s)101*67e74705SXin Li   static RefState getRelinquished(unsigned family, const Stmt *s) {
102*67e74705SXin Li     return RefState(Relinquished, s, family);
103*67e74705SXin Li   }
getEscaped(const RefState * RS)104*67e74705SXin Li   static RefState getEscaped(const RefState *RS) {
105*67e74705SXin Li     return RefState(Escaped, RS->getStmt(), RS->getAllocationFamily());
106*67e74705SXin Li   }
107*67e74705SXin Li 
Profile(llvm::FoldingSetNodeID & ID) const108*67e74705SXin Li   void Profile(llvm::FoldingSetNodeID &ID) const {
109*67e74705SXin Li     ID.AddInteger(K);
110*67e74705SXin Li     ID.AddPointer(S);
111*67e74705SXin Li     ID.AddInteger(Family);
112*67e74705SXin Li   }
113*67e74705SXin Li 
dump(raw_ostream & OS) const114*67e74705SXin Li   void dump(raw_ostream &OS) const {
115*67e74705SXin Li     switch (static_cast<Kind>(K)) {
116*67e74705SXin Li #define CASE(ID) case ID: OS << #ID; break;
117*67e74705SXin Li     CASE(Allocated)
118*67e74705SXin Li     CASE(AllocatedOfSizeZero)
119*67e74705SXin Li     CASE(Released)
120*67e74705SXin Li     CASE(Relinquished)
121*67e74705SXin Li     CASE(Escaped)
122*67e74705SXin Li     }
123*67e74705SXin Li   }
124*67e74705SXin Li 
dump() const125*67e74705SXin Li   LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); }
126*67e74705SXin Li };
127*67e74705SXin Li 
128*67e74705SXin Li enum ReallocPairKind {
129*67e74705SXin Li   RPToBeFreedAfterFailure,
130*67e74705SXin Li   // The symbol has been freed when reallocation failed.
131*67e74705SXin Li   RPIsFreeOnFailure,
132*67e74705SXin Li   // The symbol does not need to be freed after reallocation fails.
133*67e74705SXin Li   RPDoNotTrackAfterFailure
134*67e74705SXin Li };
135*67e74705SXin Li 
136*67e74705SXin Li /// \class ReallocPair
137*67e74705SXin Li /// \brief Stores information about the symbol being reallocated by a call to
138*67e74705SXin Li /// 'realloc' to allow modeling failed reallocation later in the path.
139*67e74705SXin Li struct ReallocPair {
140*67e74705SXin Li   // \brief The symbol which realloc reallocated.
141*67e74705SXin Li   SymbolRef ReallocatedSym;
142*67e74705SXin Li   ReallocPairKind Kind;
143*67e74705SXin Li 
ReallocPair__anon94e9dcf30111::ReallocPair144*67e74705SXin Li   ReallocPair(SymbolRef S, ReallocPairKind K) :
145*67e74705SXin Li     ReallocatedSym(S), Kind(K) {}
Profile__anon94e9dcf30111::ReallocPair146*67e74705SXin Li   void Profile(llvm::FoldingSetNodeID &ID) const {
147*67e74705SXin Li     ID.AddInteger(Kind);
148*67e74705SXin Li     ID.AddPointer(ReallocatedSym);
149*67e74705SXin Li   }
operator ==__anon94e9dcf30111::ReallocPair150*67e74705SXin Li   bool operator==(const ReallocPair &X) const {
151*67e74705SXin Li     return ReallocatedSym == X.ReallocatedSym &&
152*67e74705SXin Li            Kind == X.Kind;
153*67e74705SXin Li   }
154*67e74705SXin Li };
155*67e74705SXin Li 
156*67e74705SXin Li typedef std::pair<const ExplodedNode*, const MemRegion*> LeakInfo;
157*67e74705SXin Li 
158*67e74705SXin Li class MallocChecker : public Checker<check::DeadSymbols,
159*67e74705SXin Li                                      check::PointerEscape,
160*67e74705SXin Li                                      check::ConstPointerEscape,
161*67e74705SXin Li                                      check::PreStmt<ReturnStmt>,
162*67e74705SXin Li                                      check::PreCall,
163*67e74705SXin Li                                      check::PostStmt<CallExpr>,
164*67e74705SXin Li                                      check::PostStmt<CXXNewExpr>,
165*67e74705SXin Li                                      check::PreStmt<CXXDeleteExpr>,
166*67e74705SXin Li                                      check::PostStmt<BlockExpr>,
167*67e74705SXin Li                                      check::PostObjCMessage,
168*67e74705SXin Li                                      check::Location,
169*67e74705SXin Li                                      eval::Assume>
170*67e74705SXin Li {
171*67e74705SXin Li public:
MallocChecker()172*67e74705SXin Li   MallocChecker()
173*67e74705SXin Li       : II_alloca(nullptr), II_win_alloca(nullptr), II_malloc(nullptr),
174*67e74705SXin Li         II_free(nullptr), II_realloc(nullptr), II_calloc(nullptr),
175*67e74705SXin Li         II_valloc(nullptr), II_reallocf(nullptr), II_strndup(nullptr),
176*67e74705SXin Li         II_strdup(nullptr), II_win_strdup(nullptr), II_kmalloc(nullptr),
177*67e74705SXin Li         II_if_nameindex(nullptr), II_if_freenameindex(nullptr),
178*67e74705SXin Li         II_wcsdup(nullptr), II_win_wcsdup(nullptr) {}
179*67e74705SXin Li 
180*67e74705SXin Li   /// In pessimistic mode, the checker assumes that it does not know which
181*67e74705SXin Li   /// functions might free the memory.
182*67e74705SXin Li   enum CheckKind {
183*67e74705SXin Li     CK_MallocChecker,
184*67e74705SXin Li     CK_NewDeleteChecker,
185*67e74705SXin Li     CK_NewDeleteLeaksChecker,
186*67e74705SXin Li     CK_MismatchedDeallocatorChecker,
187*67e74705SXin Li     CK_NumCheckKinds
188*67e74705SXin Li   };
189*67e74705SXin Li 
190*67e74705SXin Li   enum class MemoryOperationKind {
191*67e74705SXin Li     MOK_Allocate,
192*67e74705SXin Li     MOK_Free,
193*67e74705SXin Li     MOK_Any
194*67e74705SXin Li   };
195*67e74705SXin Li 
196*67e74705SXin Li   DefaultBool IsOptimistic;
197*67e74705SXin Li 
198*67e74705SXin Li   DefaultBool ChecksEnabled[CK_NumCheckKinds];
199*67e74705SXin Li   CheckName CheckNames[CK_NumCheckKinds];
200*67e74705SXin Li 
201*67e74705SXin Li   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
202*67e74705SXin Li   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
203*67e74705SXin Li   void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const;
204*67e74705SXin Li   void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
205*67e74705SXin Li   void checkPostObjCMessage(const ObjCMethodCall &Call, CheckerContext &C) const;
206*67e74705SXin Li   void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
207*67e74705SXin Li   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
208*67e74705SXin Li   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
209*67e74705SXin Li   ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
210*67e74705SXin Li                             bool Assumption) const;
211*67e74705SXin Li   void checkLocation(SVal l, bool isLoad, const Stmt *S,
212*67e74705SXin Li                      CheckerContext &C) const;
213*67e74705SXin Li 
214*67e74705SXin Li   ProgramStateRef checkPointerEscape(ProgramStateRef State,
215*67e74705SXin Li                                     const InvalidatedSymbols &Escaped,
216*67e74705SXin Li                                     const CallEvent *Call,
217*67e74705SXin Li                                     PointerEscapeKind Kind) const;
218*67e74705SXin Li   ProgramStateRef checkConstPointerEscape(ProgramStateRef State,
219*67e74705SXin Li                                           const InvalidatedSymbols &Escaped,
220*67e74705SXin Li                                           const CallEvent *Call,
221*67e74705SXin Li                                           PointerEscapeKind Kind) const;
222*67e74705SXin Li 
223*67e74705SXin Li   void printState(raw_ostream &Out, ProgramStateRef State,
224*67e74705SXin Li                   const char *NL, const char *Sep) const override;
225*67e74705SXin Li 
226*67e74705SXin Li private:
227*67e74705SXin Li   mutable std::unique_ptr<BugType> BT_DoubleFree[CK_NumCheckKinds];
228*67e74705SXin Li   mutable std::unique_ptr<BugType> BT_DoubleDelete;
229*67e74705SXin Li   mutable std::unique_ptr<BugType> BT_Leak[CK_NumCheckKinds];
230*67e74705SXin Li   mutable std::unique_ptr<BugType> BT_UseFree[CK_NumCheckKinds];
231*67e74705SXin Li   mutable std::unique_ptr<BugType> BT_BadFree[CK_NumCheckKinds];
232*67e74705SXin Li   mutable std::unique_ptr<BugType> BT_FreeAlloca[CK_NumCheckKinds];
233*67e74705SXin Li   mutable std::unique_ptr<BugType> BT_MismatchedDealloc;
234*67e74705SXin Li   mutable std::unique_ptr<BugType> BT_OffsetFree[CK_NumCheckKinds];
235*67e74705SXin Li   mutable std::unique_ptr<BugType> BT_UseZerroAllocated[CK_NumCheckKinds];
236*67e74705SXin Li   mutable IdentifierInfo *II_alloca, *II_win_alloca, *II_malloc, *II_free,
237*67e74705SXin Li                          *II_realloc, *II_calloc, *II_valloc, *II_reallocf,
238*67e74705SXin Li                          *II_strndup, *II_strdup, *II_win_strdup, *II_kmalloc,
239*67e74705SXin Li                          *II_if_nameindex, *II_if_freenameindex, *II_wcsdup,
240*67e74705SXin Li                          *II_win_wcsdup;
241*67e74705SXin Li   mutable Optional<uint64_t> KernelZeroFlagVal;
242*67e74705SXin Li 
243*67e74705SXin Li   void initIdentifierInfo(ASTContext &C) const;
244*67e74705SXin Li 
245*67e74705SXin Li   /// \brief Determine family of a deallocation expression.
246*67e74705SXin Li   AllocationFamily getAllocationFamily(CheckerContext &C, const Stmt *S) const;
247*67e74705SXin Li 
248*67e74705SXin Li   /// \brief Print names of allocators and deallocators.
249*67e74705SXin Li   ///
250*67e74705SXin Li   /// \returns true on success.
251*67e74705SXin Li   bool printAllocDeallocName(raw_ostream &os, CheckerContext &C,
252*67e74705SXin Li                              const Expr *E) const;
253*67e74705SXin Li 
254*67e74705SXin Li   /// \brief Print expected name of an allocator based on the deallocator's
255*67e74705SXin Li   /// family derived from the DeallocExpr.
256*67e74705SXin Li   void printExpectedAllocName(raw_ostream &os, CheckerContext &C,
257*67e74705SXin Li                               const Expr *DeallocExpr) const;
258*67e74705SXin Li   /// \brief Print expected name of a deallocator based on the allocator's
259*67e74705SXin Li   /// family.
260*67e74705SXin Li   void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) const;
261*67e74705SXin Li 
262*67e74705SXin Li   ///@{
263*67e74705SXin Li   /// Check if this is one of the functions which can allocate/reallocate memory
264*67e74705SXin Li   /// pointed to by one of its arguments.
265*67e74705SXin Li   bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const;
266*67e74705SXin Li   bool isCMemFunction(const FunctionDecl *FD,
267*67e74705SXin Li                       ASTContext &C,
268*67e74705SXin Li                       AllocationFamily Family,
269*67e74705SXin Li                       MemoryOperationKind MemKind) const;
270*67e74705SXin Li   bool isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const;
271*67e74705SXin Li   ///@}
272*67e74705SXin Li 
273*67e74705SXin Li   /// \brief Perform a zero-allocation check.
274*67e74705SXin Li   ProgramStateRef ProcessZeroAllocation(CheckerContext &C, const Expr *E,
275*67e74705SXin Li                                         const unsigned AllocationSizeArg,
276*67e74705SXin Li                                         ProgramStateRef State) const;
277*67e74705SXin Li 
278*67e74705SXin Li   ProgramStateRef MallocMemReturnsAttr(CheckerContext &C,
279*67e74705SXin Li                                        const CallExpr *CE,
280*67e74705SXin Li                                        const OwnershipAttr* Att,
281*67e74705SXin Li                                        ProgramStateRef State) const;
282*67e74705SXin Li   static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
283*67e74705SXin Li                                       const Expr *SizeEx, SVal Init,
284*67e74705SXin Li                                       ProgramStateRef State,
285*67e74705SXin Li                                       AllocationFamily Family = AF_Malloc);
286*67e74705SXin Li   static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
287*67e74705SXin Li                                       SVal SizeEx, SVal Init,
288*67e74705SXin Li                                       ProgramStateRef State,
289*67e74705SXin Li                                       AllocationFamily Family = AF_Malloc);
290*67e74705SXin Li 
291*67e74705SXin Li   // Check if this malloc() for special flags. At present that means M_ZERO or
292*67e74705SXin Li   // __GFP_ZERO (in which case, treat it like calloc).
293*67e74705SXin Li   llvm::Optional<ProgramStateRef>
294*67e74705SXin Li   performKernelMalloc(const CallExpr *CE, CheckerContext &C,
295*67e74705SXin Li                       const ProgramStateRef &State) const;
296*67e74705SXin Li 
297*67e74705SXin Li   /// Update the RefState to reflect the new memory allocation.
298*67e74705SXin Li   static ProgramStateRef
299*67e74705SXin Li   MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State,
300*67e74705SXin Li                        AllocationFamily Family = AF_Malloc);
301*67e74705SXin Li 
302*67e74705SXin Li   ProgramStateRef FreeMemAttr(CheckerContext &C, const CallExpr *CE,
303*67e74705SXin Li                               const OwnershipAttr* Att,
304*67e74705SXin Li                               ProgramStateRef State) const;
305*67e74705SXin Li   ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE,
306*67e74705SXin Li                              ProgramStateRef state, unsigned Num,
307*67e74705SXin Li                              bool Hold,
308*67e74705SXin Li                              bool &ReleasedAllocated,
309*67e74705SXin Li                              bool ReturnsNullOnFailure = false) const;
310*67e74705SXin Li   ProgramStateRef FreeMemAux(CheckerContext &C, const Expr *Arg,
311*67e74705SXin Li                              const Expr *ParentExpr,
312*67e74705SXin Li                              ProgramStateRef State,
313*67e74705SXin Li                              bool Hold,
314*67e74705SXin Li                              bool &ReleasedAllocated,
315*67e74705SXin Li                              bool ReturnsNullOnFailure = false) const;
316*67e74705SXin Li 
317*67e74705SXin Li   ProgramStateRef ReallocMem(CheckerContext &C, const CallExpr *CE,
318*67e74705SXin Li                              bool FreesMemOnFailure,
319*67e74705SXin Li                              ProgramStateRef State) const;
320*67e74705SXin Li   static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE,
321*67e74705SXin Li                                    ProgramStateRef State);
322*67e74705SXin Li 
323*67e74705SXin Li   ///\brief Check if the memory associated with this symbol was released.
324*67e74705SXin Li   bool isReleased(SymbolRef Sym, CheckerContext &C) const;
325*67e74705SXin Li 
326*67e74705SXin Li   bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const;
327*67e74705SXin Li 
328*67e74705SXin Li   void checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C,
329*67e74705SXin Li                              const Stmt *S) const;
330*67e74705SXin Li 
331*67e74705SXin Li   bool checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const;
332*67e74705SXin Li 
333*67e74705SXin Li   /// Check if the function is known free memory, or if it is
334*67e74705SXin Li   /// "interesting" and should be modeled explicitly.
335*67e74705SXin Li   ///
336*67e74705SXin Li   /// \param [out] EscapingSymbol A function might not free memory in general,
337*67e74705SXin Li   ///   but could be known to free a particular symbol. In this case, false is
338*67e74705SXin Li   ///   returned and the single escaping symbol is returned through the out
339*67e74705SXin Li   ///   parameter.
340*67e74705SXin Li   ///
341*67e74705SXin Li   /// We assume that pointers do not escape through calls to system functions
342*67e74705SXin Li   /// not handled by this checker.
343*67e74705SXin Li   bool mayFreeAnyEscapedMemoryOrIsModeledExplicitly(const CallEvent *Call,
344*67e74705SXin Li                                    ProgramStateRef State,
345*67e74705SXin Li                                    SymbolRef &EscapingSymbol) const;
346*67e74705SXin Li 
347*67e74705SXin Li   // Implementation of the checkPointerEscape callabcks.
348*67e74705SXin Li   ProgramStateRef checkPointerEscapeAux(ProgramStateRef State,
349*67e74705SXin Li                                   const InvalidatedSymbols &Escaped,
350*67e74705SXin Li                                   const CallEvent *Call,
351*67e74705SXin Li                                   PointerEscapeKind Kind,
352*67e74705SXin Li                                   bool(*CheckRefState)(const RefState*)) const;
353*67e74705SXin Li 
354*67e74705SXin Li   ///@{
355*67e74705SXin Li   /// Tells if a given family/call/symbol is tracked by the current checker.
356*67e74705SXin Li   /// Sets CheckKind to the kind of the checker responsible for this
357*67e74705SXin Li   /// family/call/symbol.
358*67e74705SXin Li   Optional<CheckKind> getCheckIfTracked(AllocationFamily Family,
359*67e74705SXin Li                                         bool IsALeakCheck = false) const;
360*67e74705SXin Li   Optional<CheckKind> getCheckIfTracked(CheckerContext &C,
361*67e74705SXin Li                                         const Stmt *AllocDeallocStmt,
362*67e74705SXin Li                                         bool IsALeakCheck = false) const;
363*67e74705SXin Li   Optional<CheckKind> getCheckIfTracked(CheckerContext &C, SymbolRef Sym,
364*67e74705SXin Li                                         bool IsALeakCheck = false) const;
365*67e74705SXin Li   ///@}
366*67e74705SXin Li   static bool SummarizeValue(raw_ostream &os, SVal V);
367*67e74705SXin Li   static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
368*67e74705SXin Li   void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
369*67e74705SXin Li                      const Expr *DeallocExpr) const;
370*67e74705SXin Li   void ReportFreeAlloca(CheckerContext &C, SVal ArgVal,
371*67e74705SXin Li                         SourceRange Range) const;
372*67e74705SXin Li   void ReportMismatchedDealloc(CheckerContext &C, SourceRange Range,
373*67e74705SXin Li                                const Expr *DeallocExpr, const RefState *RS,
374*67e74705SXin Li                                SymbolRef Sym, bool OwnershipTransferred) const;
375*67e74705SXin Li   void ReportOffsetFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
376*67e74705SXin Li                         const Expr *DeallocExpr,
377*67e74705SXin Li                         const Expr *AllocExpr = nullptr) const;
378*67e74705SXin Li   void ReportUseAfterFree(CheckerContext &C, SourceRange Range,
379*67e74705SXin Li                           SymbolRef Sym) const;
380*67e74705SXin Li   void ReportDoubleFree(CheckerContext &C, SourceRange Range, bool Released,
381*67e74705SXin Li                         SymbolRef Sym, SymbolRef PrevSym) const;
382*67e74705SXin Li 
383*67e74705SXin Li   void ReportDoubleDelete(CheckerContext &C, SymbolRef Sym) const;
384*67e74705SXin Li 
385*67e74705SXin Li   void ReportUseZeroAllocated(CheckerContext &C, SourceRange Range,
386*67e74705SXin Li                               SymbolRef Sym) const;
387*67e74705SXin Li 
388*67e74705SXin Li   /// Find the location of the allocation for Sym on the path leading to the
389*67e74705SXin Li   /// exploded node N.
390*67e74705SXin Li   LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
391*67e74705SXin Li                              CheckerContext &C) const;
392*67e74705SXin Li 
393*67e74705SXin Li   void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const;
394*67e74705SXin Li 
395*67e74705SXin Li   /// The bug visitor which allows us to print extra diagnostics along the
396*67e74705SXin Li   /// BugReport path. For example, showing the allocation site of the leaked
397*67e74705SXin Li   /// region.
398*67e74705SXin Li   class MallocBugVisitor final
399*67e74705SXin Li       : public BugReporterVisitorImpl<MallocBugVisitor> {
400*67e74705SXin Li   protected:
401*67e74705SXin Li     enum NotificationMode {
402*67e74705SXin Li       Normal,
403*67e74705SXin Li       ReallocationFailed
404*67e74705SXin Li     };
405*67e74705SXin Li 
406*67e74705SXin Li     // The allocated region symbol tracked by the main analysis.
407*67e74705SXin Li     SymbolRef Sym;
408*67e74705SXin Li 
409*67e74705SXin Li     // The mode we are in, i.e. what kind of diagnostics will be emitted.
410*67e74705SXin Li     NotificationMode Mode;
411*67e74705SXin Li 
412*67e74705SXin Li     // A symbol from when the primary region should have been reallocated.
413*67e74705SXin Li     SymbolRef FailedReallocSymbol;
414*67e74705SXin Li 
415*67e74705SXin Li     bool IsLeak;
416*67e74705SXin Li 
417*67e74705SXin Li   public:
MallocBugVisitor(SymbolRef S,bool isLeak=false)418*67e74705SXin Li     MallocBugVisitor(SymbolRef S, bool isLeak = false)
419*67e74705SXin Li        : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr), IsLeak(isLeak) {}
420*67e74705SXin Li 
Profile(llvm::FoldingSetNodeID & ID) const421*67e74705SXin Li     void Profile(llvm::FoldingSetNodeID &ID) const override {
422*67e74705SXin Li       static int X = 0;
423*67e74705SXin Li       ID.AddPointer(&X);
424*67e74705SXin Li       ID.AddPointer(Sym);
425*67e74705SXin Li     }
426*67e74705SXin Li 
isAllocated(const RefState * S,const RefState * SPrev,const Stmt * Stmt)427*67e74705SXin Li     inline bool isAllocated(const RefState *S, const RefState *SPrev,
428*67e74705SXin Li                             const Stmt *Stmt) {
429*67e74705SXin Li       // Did not track -> allocated. Other state (released) -> allocated.
430*67e74705SXin Li       return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXNewExpr>(Stmt)) &&
431*67e74705SXin Li               (S && (S->isAllocated() || S->isAllocatedOfSizeZero())) &&
432*67e74705SXin Li               (!SPrev || !(SPrev->isAllocated() ||
433*67e74705SXin Li                            SPrev->isAllocatedOfSizeZero())));
434*67e74705SXin Li     }
435*67e74705SXin Li 
isReleased(const RefState * S,const RefState * SPrev,const Stmt * Stmt)436*67e74705SXin Li     inline bool isReleased(const RefState *S, const RefState *SPrev,
437*67e74705SXin Li                            const Stmt *Stmt) {
438*67e74705SXin Li       // Did not track -> released. Other state (allocated) -> released.
439*67e74705SXin Li       return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXDeleteExpr>(Stmt)) &&
440*67e74705SXin Li               (S && S->isReleased()) && (!SPrev || !SPrev->isReleased()));
441*67e74705SXin Li     }
442*67e74705SXin Li 
isRelinquished(const RefState * S,const RefState * SPrev,const Stmt * Stmt)443*67e74705SXin Li     inline bool isRelinquished(const RefState *S, const RefState *SPrev,
444*67e74705SXin Li                                const Stmt *Stmt) {
445*67e74705SXin Li       // Did not track -> relinquished. Other state (allocated) -> relinquished.
446*67e74705SXin Li       return (Stmt && (isa<CallExpr>(Stmt) || isa<ObjCMessageExpr>(Stmt) ||
447*67e74705SXin Li                                               isa<ObjCPropertyRefExpr>(Stmt)) &&
448*67e74705SXin Li               (S && S->isRelinquished()) &&
449*67e74705SXin Li               (!SPrev || !SPrev->isRelinquished()));
450*67e74705SXin Li     }
451*67e74705SXin Li 
isReallocFailedCheck(const RefState * S,const RefState * SPrev,const Stmt * Stmt)452*67e74705SXin Li     inline bool isReallocFailedCheck(const RefState *S, const RefState *SPrev,
453*67e74705SXin Li                                      const Stmt *Stmt) {
454*67e74705SXin Li       // If the expression is not a call, and the state change is
455*67e74705SXin Li       // released -> allocated, it must be the realloc return value
456*67e74705SXin Li       // check. If we have to handle more cases here, it might be cleaner just
457*67e74705SXin Li       // to track this extra bit in the state itself.
458*67e74705SXin Li       return ((!Stmt || !isa<CallExpr>(Stmt)) &&
459*67e74705SXin Li               (S && (S->isAllocated() || S->isAllocatedOfSizeZero())) &&
460*67e74705SXin Li               (SPrev && !(SPrev->isAllocated() ||
461*67e74705SXin Li                           SPrev->isAllocatedOfSizeZero())));
462*67e74705SXin Li     }
463*67e74705SXin Li 
464*67e74705SXin Li     PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
465*67e74705SXin Li                                    const ExplodedNode *PrevN,
466*67e74705SXin Li                                    BugReporterContext &BRC,
467*67e74705SXin Li                                    BugReport &BR) override;
468*67e74705SXin Li 
469*67e74705SXin Li     std::unique_ptr<PathDiagnosticPiece>
getEndPath(BugReporterContext & BRC,const ExplodedNode * EndPathNode,BugReport & BR)470*67e74705SXin Li     getEndPath(BugReporterContext &BRC, const ExplodedNode *EndPathNode,
471*67e74705SXin Li                BugReport &BR) override {
472*67e74705SXin Li       if (!IsLeak)
473*67e74705SXin Li         return nullptr;
474*67e74705SXin Li 
475*67e74705SXin Li       PathDiagnosticLocation L =
476*67e74705SXin Li         PathDiagnosticLocation::createEndOfPath(EndPathNode,
477*67e74705SXin Li                                                 BRC.getSourceManager());
478*67e74705SXin Li       // Do not add the statement itself as a range in case of leak.
479*67e74705SXin Li       return llvm::make_unique<PathDiagnosticEventPiece>(L, BR.getDescription(),
480*67e74705SXin Li                                                          false);
481*67e74705SXin Li     }
482*67e74705SXin Li 
483*67e74705SXin Li   private:
484*67e74705SXin Li     class StackHintGeneratorForReallocationFailed
485*67e74705SXin Li         : public StackHintGeneratorForSymbol {
486*67e74705SXin Li     public:
StackHintGeneratorForReallocationFailed(SymbolRef S,StringRef M)487*67e74705SXin Li       StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M)
488*67e74705SXin Li         : StackHintGeneratorForSymbol(S, M) {}
489*67e74705SXin Li 
getMessageForArg(const Expr * ArgE,unsigned ArgIndex)490*67e74705SXin Li       std::string getMessageForArg(const Expr *ArgE,
491*67e74705SXin Li                                    unsigned ArgIndex) override {
492*67e74705SXin Li         // Printed parameters start at 1, not 0.
493*67e74705SXin Li         ++ArgIndex;
494*67e74705SXin Li 
495*67e74705SXin Li         SmallString<200> buf;
496*67e74705SXin Li         llvm::raw_svector_ostream os(buf);
497*67e74705SXin Li 
498*67e74705SXin Li         os << "Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex)
499*67e74705SXin Li            << " parameter failed";
500*67e74705SXin Li 
501*67e74705SXin Li         return os.str();
502*67e74705SXin Li       }
503*67e74705SXin Li 
getMessageForReturn(const CallExpr * CallExpr)504*67e74705SXin Li       std::string getMessageForReturn(const CallExpr *CallExpr) override {
505*67e74705SXin Li         return "Reallocation of returned value failed";
506*67e74705SXin Li       }
507*67e74705SXin Li     };
508*67e74705SXin Li   };
509*67e74705SXin Li };
510*67e74705SXin Li } // end anonymous namespace
511*67e74705SXin Li 
512*67e74705SXin Li REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState)
513*67e74705SXin Li REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair)
514*67e74705SXin Li REGISTER_SET_WITH_PROGRAMSTATE(ReallocSizeZeroSymbols, SymbolRef)
515*67e74705SXin Li 
516*67e74705SXin Li // A map from the freed symbol to the symbol representing the return value of
517*67e74705SXin Li // the free function.
518*67e74705SXin Li REGISTER_MAP_WITH_PROGRAMSTATE(FreeReturnValue, SymbolRef, SymbolRef)
519*67e74705SXin Li 
520*67e74705SXin Li namespace {
521*67e74705SXin Li class StopTrackingCallback final : public SymbolVisitor {
522*67e74705SXin Li   ProgramStateRef state;
523*67e74705SXin Li public:
StopTrackingCallback(ProgramStateRef st)524*67e74705SXin Li   StopTrackingCallback(ProgramStateRef st) : state(std::move(st)) {}
getState() const525*67e74705SXin Li   ProgramStateRef getState() const { return state; }
526*67e74705SXin Li 
VisitSymbol(SymbolRef sym)527*67e74705SXin Li   bool VisitSymbol(SymbolRef sym) override {
528*67e74705SXin Li     state = state->remove<RegionState>(sym);
529*67e74705SXin Li     return true;
530*67e74705SXin Li   }
531*67e74705SXin Li };
532*67e74705SXin Li } // end anonymous namespace
533*67e74705SXin Li 
initIdentifierInfo(ASTContext & Ctx) const534*67e74705SXin Li void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const {
535*67e74705SXin Li   if (II_malloc)
536*67e74705SXin Li     return;
537*67e74705SXin Li   II_alloca = &Ctx.Idents.get("alloca");
538*67e74705SXin Li   II_malloc = &Ctx.Idents.get("malloc");
539*67e74705SXin Li   II_free = &Ctx.Idents.get("free");
540*67e74705SXin Li   II_realloc = &Ctx.Idents.get("realloc");
541*67e74705SXin Li   II_reallocf = &Ctx.Idents.get("reallocf");
542*67e74705SXin Li   II_calloc = &Ctx.Idents.get("calloc");
543*67e74705SXin Li   II_valloc = &Ctx.Idents.get("valloc");
544*67e74705SXin Li   II_strdup = &Ctx.Idents.get("strdup");
545*67e74705SXin Li   II_strndup = &Ctx.Idents.get("strndup");
546*67e74705SXin Li   II_wcsdup = &Ctx.Idents.get("wcsdup");
547*67e74705SXin Li   II_kmalloc = &Ctx.Idents.get("kmalloc");
548*67e74705SXin Li   II_if_nameindex = &Ctx.Idents.get("if_nameindex");
549*67e74705SXin Li   II_if_freenameindex = &Ctx.Idents.get("if_freenameindex");
550*67e74705SXin Li 
551*67e74705SXin Li   //MSVC uses `_`-prefixed instead, so we check for them too.
552*67e74705SXin Li   II_win_strdup = &Ctx.Idents.get("_strdup");
553*67e74705SXin Li   II_win_wcsdup = &Ctx.Idents.get("_wcsdup");
554*67e74705SXin Li   II_win_alloca = &Ctx.Idents.get("_alloca");
555*67e74705SXin Li }
556*67e74705SXin Li 
isMemFunction(const FunctionDecl * FD,ASTContext & C) const557*67e74705SXin Li bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const {
558*67e74705SXin Li   if (isCMemFunction(FD, C, AF_Malloc, MemoryOperationKind::MOK_Any))
559*67e74705SXin Li     return true;
560*67e74705SXin Li 
561*67e74705SXin Li   if (isCMemFunction(FD, C, AF_IfNameIndex, MemoryOperationKind::MOK_Any))
562*67e74705SXin Li     return true;
563*67e74705SXin Li 
564*67e74705SXin Li   if (isCMemFunction(FD, C, AF_Alloca, MemoryOperationKind::MOK_Any))
565*67e74705SXin Li     return true;
566*67e74705SXin Li 
567*67e74705SXin Li   if (isStandardNewDelete(FD, C))
568*67e74705SXin Li     return true;
569*67e74705SXin Li 
570*67e74705SXin Li   return false;
571*67e74705SXin Li }
572*67e74705SXin Li 
isCMemFunction(const FunctionDecl * FD,ASTContext & C,AllocationFamily Family,MemoryOperationKind MemKind) const573*67e74705SXin Li bool MallocChecker::isCMemFunction(const FunctionDecl *FD,
574*67e74705SXin Li                                    ASTContext &C,
575*67e74705SXin Li                                    AllocationFamily Family,
576*67e74705SXin Li                                    MemoryOperationKind MemKind) const {
577*67e74705SXin Li   if (!FD)
578*67e74705SXin Li     return false;
579*67e74705SXin Li 
580*67e74705SXin Li   bool CheckFree = (MemKind == MemoryOperationKind::MOK_Any ||
581*67e74705SXin Li                     MemKind == MemoryOperationKind::MOK_Free);
582*67e74705SXin Li   bool CheckAlloc = (MemKind == MemoryOperationKind::MOK_Any ||
583*67e74705SXin Li                      MemKind == MemoryOperationKind::MOK_Allocate);
584*67e74705SXin Li 
585*67e74705SXin Li   if (FD->getKind() == Decl::Function) {
586*67e74705SXin Li     const IdentifierInfo *FunI = FD->getIdentifier();
587*67e74705SXin Li     initIdentifierInfo(C);
588*67e74705SXin Li 
589*67e74705SXin Li     if (Family == AF_Malloc && CheckFree) {
590*67e74705SXin Li       if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf)
591*67e74705SXin Li         return true;
592*67e74705SXin Li     }
593*67e74705SXin Li 
594*67e74705SXin Li     if (Family == AF_Malloc && CheckAlloc) {
595*67e74705SXin Li       if (FunI == II_malloc || FunI == II_realloc || FunI == II_reallocf ||
596*67e74705SXin Li           FunI == II_calloc || FunI == II_valloc || FunI == II_strdup ||
597*67e74705SXin Li           FunI == II_win_strdup || FunI == II_strndup || FunI == II_wcsdup ||
598*67e74705SXin Li           FunI == II_win_wcsdup || FunI == II_kmalloc)
599*67e74705SXin Li         return true;
600*67e74705SXin Li     }
601*67e74705SXin Li 
602*67e74705SXin Li     if (Family == AF_IfNameIndex && CheckFree) {
603*67e74705SXin Li       if (FunI == II_if_freenameindex)
604*67e74705SXin Li         return true;
605*67e74705SXin Li     }
606*67e74705SXin Li 
607*67e74705SXin Li     if (Family == AF_IfNameIndex && CheckAlloc) {
608*67e74705SXin Li       if (FunI == II_if_nameindex)
609*67e74705SXin Li         return true;
610*67e74705SXin Li     }
611*67e74705SXin Li 
612*67e74705SXin Li     if (Family == AF_Alloca && CheckAlloc) {
613*67e74705SXin Li       if (FunI == II_alloca || FunI == II_win_alloca)
614*67e74705SXin Li         return true;
615*67e74705SXin Li     }
616*67e74705SXin Li   }
617*67e74705SXin Li 
618*67e74705SXin Li   if (Family != AF_Malloc)
619*67e74705SXin Li     return false;
620*67e74705SXin Li 
621*67e74705SXin Li   if (IsOptimistic && FD->hasAttrs()) {
622*67e74705SXin Li     for (const auto *I : FD->specific_attrs<OwnershipAttr>()) {
623*67e74705SXin Li       OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind();
624*67e74705SXin Li       if(OwnKind == OwnershipAttr::Takes || OwnKind == OwnershipAttr::Holds) {
625*67e74705SXin Li         if (CheckFree)
626*67e74705SXin Li           return true;
627*67e74705SXin Li       } else if (OwnKind == OwnershipAttr::Returns) {
628*67e74705SXin Li         if (CheckAlloc)
629*67e74705SXin Li           return true;
630*67e74705SXin Li       }
631*67e74705SXin Li     }
632*67e74705SXin Li   }
633*67e74705SXin Li 
634*67e74705SXin Li   return false;
635*67e74705SXin Li }
636*67e74705SXin Li 
637*67e74705SXin Li // Tells if the callee is one of the following:
638*67e74705SXin Li // 1) A global non-placement new/delete operator function.
639*67e74705SXin Li // 2) A global placement operator function with the single placement argument
640*67e74705SXin Li //    of type std::nothrow_t.
isStandardNewDelete(const FunctionDecl * FD,ASTContext & C) const641*67e74705SXin Li bool MallocChecker::isStandardNewDelete(const FunctionDecl *FD,
642*67e74705SXin Li                                         ASTContext &C) const {
643*67e74705SXin Li   if (!FD)
644*67e74705SXin Li     return false;
645*67e74705SXin Li 
646*67e74705SXin Li   OverloadedOperatorKind Kind = FD->getOverloadedOperator();
647*67e74705SXin Li   if (Kind != OO_New && Kind != OO_Array_New &&
648*67e74705SXin Li       Kind != OO_Delete && Kind != OO_Array_Delete)
649*67e74705SXin Li     return false;
650*67e74705SXin Li 
651*67e74705SXin Li   // Skip all operator new/delete methods.
652*67e74705SXin Li   if (isa<CXXMethodDecl>(FD))
653*67e74705SXin Li     return false;
654*67e74705SXin Li 
655*67e74705SXin Li   // Return true if tested operator is a standard placement nothrow operator.
656*67e74705SXin Li   if (FD->getNumParams() == 2) {
657*67e74705SXin Li     QualType T = FD->getParamDecl(1)->getType();
658*67e74705SXin Li     if (const IdentifierInfo *II = T.getBaseTypeIdentifier())
659*67e74705SXin Li       return II->getName().equals("nothrow_t");
660*67e74705SXin Li   }
661*67e74705SXin Li 
662*67e74705SXin Li   // Skip placement operators.
663*67e74705SXin Li   if (FD->getNumParams() != 1 || FD->isVariadic())
664*67e74705SXin Li     return false;
665*67e74705SXin Li 
666*67e74705SXin Li   // One of the standard new/new[]/delete/delete[] non-placement operators.
667*67e74705SXin Li   return true;
668*67e74705SXin Li }
669*67e74705SXin Li 
performKernelMalloc(const CallExpr * CE,CheckerContext & C,const ProgramStateRef & State) const670*67e74705SXin Li llvm::Optional<ProgramStateRef> MallocChecker::performKernelMalloc(
671*67e74705SXin Li   const CallExpr *CE, CheckerContext &C, const ProgramStateRef &State) const {
672*67e74705SXin Li   // 3-argument malloc(), as commonly used in {Free,Net,Open}BSD Kernels:
673*67e74705SXin Li   //
674*67e74705SXin Li   // void *malloc(unsigned long size, struct malloc_type *mtp, int flags);
675*67e74705SXin Li   //
676*67e74705SXin Li   // One of the possible flags is M_ZERO, which means 'give me back an
677*67e74705SXin Li   // allocation which is already zeroed', like calloc.
678*67e74705SXin Li 
679*67e74705SXin Li   // 2-argument kmalloc(), as used in the Linux kernel:
680*67e74705SXin Li   //
681*67e74705SXin Li   // void *kmalloc(size_t size, gfp_t flags);
682*67e74705SXin Li   //
683*67e74705SXin Li   // Has the similar flag value __GFP_ZERO.
684*67e74705SXin Li 
685*67e74705SXin Li   // This logic is largely cloned from O_CREAT in UnixAPIChecker, maybe some
686*67e74705SXin Li   // code could be shared.
687*67e74705SXin Li 
688*67e74705SXin Li   ASTContext &Ctx = C.getASTContext();
689*67e74705SXin Li   llvm::Triple::OSType OS = Ctx.getTargetInfo().getTriple().getOS();
690*67e74705SXin Li 
691*67e74705SXin Li   if (!KernelZeroFlagVal.hasValue()) {
692*67e74705SXin Li     if (OS == llvm::Triple::FreeBSD)
693*67e74705SXin Li       KernelZeroFlagVal = 0x0100;
694*67e74705SXin Li     else if (OS == llvm::Triple::NetBSD)
695*67e74705SXin Li       KernelZeroFlagVal = 0x0002;
696*67e74705SXin Li     else if (OS == llvm::Triple::OpenBSD)
697*67e74705SXin Li       KernelZeroFlagVal = 0x0008;
698*67e74705SXin Li     else if (OS == llvm::Triple::Linux)
699*67e74705SXin Li       // __GFP_ZERO
700*67e74705SXin Li       KernelZeroFlagVal = 0x8000;
701*67e74705SXin Li     else
702*67e74705SXin Li       // FIXME: We need a more general way of getting the M_ZERO value.
703*67e74705SXin Li       // See also: O_CREAT in UnixAPIChecker.cpp.
704*67e74705SXin Li 
705*67e74705SXin Li       // Fall back to normal malloc behavior on platforms where we don't
706*67e74705SXin Li       // know M_ZERO.
707*67e74705SXin Li       return None;
708*67e74705SXin Li   }
709*67e74705SXin Li 
710*67e74705SXin Li   // We treat the last argument as the flags argument, and callers fall-back to
711*67e74705SXin Li   // normal malloc on a None return. This works for the FreeBSD kernel malloc
712*67e74705SXin Li   // as well as Linux kmalloc.
713*67e74705SXin Li   if (CE->getNumArgs() < 2)
714*67e74705SXin Li     return None;
715*67e74705SXin Li 
716*67e74705SXin Li   const Expr *FlagsEx = CE->getArg(CE->getNumArgs() - 1);
717*67e74705SXin Li   const SVal V = State->getSVal(FlagsEx, C.getLocationContext());
718*67e74705SXin Li   if (!V.getAs<NonLoc>()) {
719*67e74705SXin Li     // The case where 'V' can be a location can only be due to a bad header,
720*67e74705SXin Li     // so in this case bail out.
721*67e74705SXin Li     return None;
722*67e74705SXin Li   }
723*67e74705SXin Li 
724*67e74705SXin Li   NonLoc Flags = V.castAs<NonLoc>();
725*67e74705SXin Li   NonLoc ZeroFlag = C.getSValBuilder()
726*67e74705SXin Li       .makeIntVal(KernelZeroFlagVal.getValue(), FlagsEx->getType())
727*67e74705SXin Li       .castAs<NonLoc>();
728*67e74705SXin Li   SVal MaskedFlagsUC = C.getSValBuilder().evalBinOpNN(State, BO_And,
729*67e74705SXin Li                                                       Flags, ZeroFlag,
730*67e74705SXin Li                                                       FlagsEx->getType());
731*67e74705SXin Li   if (MaskedFlagsUC.isUnknownOrUndef())
732*67e74705SXin Li     return None;
733*67e74705SXin Li   DefinedSVal MaskedFlags = MaskedFlagsUC.castAs<DefinedSVal>();
734*67e74705SXin Li 
735*67e74705SXin Li   // Check if maskedFlags is non-zero.
736*67e74705SXin Li   ProgramStateRef TrueState, FalseState;
737*67e74705SXin Li   std::tie(TrueState, FalseState) = State->assume(MaskedFlags);
738*67e74705SXin Li 
739*67e74705SXin Li   // If M_ZERO is set, treat this like calloc (initialized).
740*67e74705SXin Li   if (TrueState && !FalseState) {
741*67e74705SXin Li     SVal ZeroVal = C.getSValBuilder().makeZeroVal(Ctx.CharTy);
742*67e74705SXin Li     return MallocMemAux(C, CE, CE->getArg(0), ZeroVal, TrueState);
743*67e74705SXin Li   }
744*67e74705SXin Li 
745*67e74705SXin Li   return None;
746*67e74705SXin Li }
747*67e74705SXin Li 
checkPostStmt(const CallExpr * CE,CheckerContext & C) const748*67e74705SXin Li void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
749*67e74705SXin Li   if (C.wasInlined)
750*67e74705SXin Li     return;
751*67e74705SXin Li 
752*67e74705SXin Li   const FunctionDecl *FD = C.getCalleeDecl(CE);
753*67e74705SXin Li   if (!FD)
754*67e74705SXin Li     return;
755*67e74705SXin Li 
756*67e74705SXin Li   ProgramStateRef State = C.getState();
757*67e74705SXin Li   bool ReleasedAllocatedMemory = false;
758*67e74705SXin Li 
759*67e74705SXin Li   if (FD->getKind() == Decl::Function) {
760*67e74705SXin Li     initIdentifierInfo(C.getASTContext());
761*67e74705SXin Li     IdentifierInfo *FunI = FD->getIdentifier();
762*67e74705SXin Li 
763*67e74705SXin Li     if (FunI == II_malloc) {
764*67e74705SXin Li       if (CE->getNumArgs() < 1)
765*67e74705SXin Li         return;
766*67e74705SXin Li       if (CE->getNumArgs() < 3) {
767*67e74705SXin Li         State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
768*67e74705SXin Li         if (CE->getNumArgs() == 1)
769*67e74705SXin Li           State = ProcessZeroAllocation(C, CE, 0, State);
770*67e74705SXin Li       } else if (CE->getNumArgs() == 3) {
771*67e74705SXin Li         llvm::Optional<ProgramStateRef> MaybeState =
772*67e74705SXin Li           performKernelMalloc(CE, C, State);
773*67e74705SXin Li         if (MaybeState.hasValue())
774*67e74705SXin Li           State = MaybeState.getValue();
775*67e74705SXin Li         else
776*67e74705SXin Li           State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
777*67e74705SXin Li       }
778*67e74705SXin Li     } else if (FunI == II_kmalloc) {
779*67e74705SXin Li       llvm::Optional<ProgramStateRef> MaybeState =
780*67e74705SXin Li         performKernelMalloc(CE, C, State);
781*67e74705SXin Li       if (MaybeState.hasValue())
782*67e74705SXin Li         State = MaybeState.getValue();
783*67e74705SXin Li       else
784*67e74705SXin Li         State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
785*67e74705SXin Li     } else if (FunI == II_valloc) {
786*67e74705SXin Li       if (CE->getNumArgs() < 1)
787*67e74705SXin Li         return;
788*67e74705SXin Li       State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
789*67e74705SXin Li       State = ProcessZeroAllocation(C, CE, 0, State);
790*67e74705SXin Li     } else if (FunI == II_realloc) {
791*67e74705SXin Li       State = ReallocMem(C, CE, false, State);
792*67e74705SXin Li       State = ProcessZeroAllocation(C, CE, 1, State);
793*67e74705SXin Li     } else if (FunI == II_reallocf) {
794*67e74705SXin Li       State = ReallocMem(C, CE, true, State);
795*67e74705SXin Li       State = ProcessZeroAllocation(C, CE, 1, State);
796*67e74705SXin Li     } else if (FunI == II_calloc) {
797*67e74705SXin Li       State = CallocMem(C, CE, State);
798*67e74705SXin Li       State = ProcessZeroAllocation(C, CE, 0, State);
799*67e74705SXin Li       State = ProcessZeroAllocation(C, CE, 1, State);
800*67e74705SXin Li     } else if (FunI == II_free) {
801*67e74705SXin Li       State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
802*67e74705SXin Li     } else if (FunI == II_strdup || FunI == II_win_strdup ||
803*67e74705SXin Li                FunI == II_wcsdup || FunI == II_win_wcsdup) {
804*67e74705SXin Li       State = MallocUpdateRefState(C, CE, State);
805*67e74705SXin Li     } else if (FunI == II_strndup) {
806*67e74705SXin Li       State = MallocUpdateRefState(C, CE, State);
807*67e74705SXin Li     } else if (FunI == II_alloca || FunI == II_win_alloca) {
808*67e74705SXin Li       State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
809*67e74705SXin Li                            AF_Alloca);
810*67e74705SXin Li       State = ProcessZeroAllocation(C, CE, 0, State);
811*67e74705SXin Li     } else if (isStandardNewDelete(FD, C.getASTContext())) {
812*67e74705SXin Li       // Process direct calls to operator new/new[]/delete/delete[] functions
813*67e74705SXin Li       // as distinct from new/new[]/delete/delete[] expressions that are
814*67e74705SXin Li       // processed by the checkPostStmt callbacks for CXXNewExpr and
815*67e74705SXin Li       // CXXDeleteExpr.
816*67e74705SXin Li       OverloadedOperatorKind K = FD->getOverloadedOperator();
817*67e74705SXin Li       if (K == OO_New) {
818*67e74705SXin Li         State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
819*67e74705SXin Li                              AF_CXXNew);
820*67e74705SXin Li         State = ProcessZeroAllocation(C, CE, 0, State);
821*67e74705SXin Li       }
822*67e74705SXin Li       else if (K == OO_Array_New) {
823*67e74705SXin Li         State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
824*67e74705SXin Li                              AF_CXXNewArray);
825*67e74705SXin Li         State = ProcessZeroAllocation(C, CE, 0, State);
826*67e74705SXin Li       }
827*67e74705SXin Li       else if (K == OO_Delete || K == OO_Array_Delete)
828*67e74705SXin Li         State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
829*67e74705SXin Li       else
830*67e74705SXin Li         llvm_unreachable("not a new/delete operator");
831*67e74705SXin Li     } else if (FunI == II_if_nameindex) {
832*67e74705SXin Li       // Should we model this differently? We can allocate a fixed number of
833*67e74705SXin Li       // elements with zeros in the last one.
834*67e74705SXin Li       State = MallocMemAux(C, CE, UnknownVal(), UnknownVal(), State,
835*67e74705SXin Li                            AF_IfNameIndex);
836*67e74705SXin Li     } else if (FunI == II_if_freenameindex) {
837*67e74705SXin Li       State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
838*67e74705SXin Li     }
839*67e74705SXin Li   }
840*67e74705SXin Li 
841*67e74705SXin Li   if (IsOptimistic || ChecksEnabled[CK_MismatchedDeallocatorChecker]) {
842*67e74705SXin Li     // Check all the attributes, if there are any.
843*67e74705SXin Li     // There can be multiple of these attributes.
844*67e74705SXin Li     if (FD->hasAttrs())
845*67e74705SXin Li       for (const auto *I : FD->specific_attrs<OwnershipAttr>()) {
846*67e74705SXin Li         switch (I->getOwnKind()) {
847*67e74705SXin Li         case OwnershipAttr::Returns:
848*67e74705SXin Li           State = MallocMemReturnsAttr(C, CE, I, State);
849*67e74705SXin Li           break;
850*67e74705SXin Li         case OwnershipAttr::Takes:
851*67e74705SXin Li         case OwnershipAttr::Holds:
852*67e74705SXin Li           State = FreeMemAttr(C, CE, I, State);
853*67e74705SXin Li           break;
854*67e74705SXin Li         }
855*67e74705SXin Li       }
856*67e74705SXin Li   }
857*67e74705SXin Li   C.addTransition(State);
858*67e74705SXin Li }
859*67e74705SXin Li 
860*67e74705SXin Li // Performs a 0-sized allocations check.
ProcessZeroAllocation(CheckerContext & C,const Expr * E,const unsigned AllocationSizeArg,ProgramStateRef State) const861*67e74705SXin Li ProgramStateRef MallocChecker::ProcessZeroAllocation(CheckerContext &C,
862*67e74705SXin Li                                                const Expr *E,
863*67e74705SXin Li                                                const unsigned AllocationSizeArg,
864*67e74705SXin Li                                                ProgramStateRef State) const {
865*67e74705SXin Li   if (!State)
866*67e74705SXin Li     return nullptr;
867*67e74705SXin Li 
868*67e74705SXin Li   const Expr *Arg = nullptr;
869*67e74705SXin Li 
870*67e74705SXin Li   if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
871*67e74705SXin Li     Arg = CE->getArg(AllocationSizeArg);
872*67e74705SXin Li   }
873*67e74705SXin Li   else if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) {
874*67e74705SXin Li     if (NE->isArray())
875*67e74705SXin Li       Arg = NE->getArraySize();
876*67e74705SXin Li     else
877*67e74705SXin Li       return State;
878*67e74705SXin Li   }
879*67e74705SXin Li   else
880*67e74705SXin Li     llvm_unreachable("not a CallExpr or CXXNewExpr");
881*67e74705SXin Li 
882*67e74705SXin Li   assert(Arg);
883*67e74705SXin Li 
884*67e74705SXin Li   Optional<DefinedSVal> DefArgVal =
885*67e74705SXin Li       State->getSVal(Arg, C.getLocationContext()).getAs<DefinedSVal>();
886*67e74705SXin Li 
887*67e74705SXin Li   if (!DefArgVal)
888*67e74705SXin Li     return State;
889*67e74705SXin Li 
890*67e74705SXin Li   // Check if the allocation size is 0.
891*67e74705SXin Li   ProgramStateRef TrueState, FalseState;
892*67e74705SXin Li   SValBuilder &SvalBuilder = C.getSValBuilder();
893*67e74705SXin Li   DefinedSVal Zero =
894*67e74705SXin Li       SvalBuilder.makeZeroVal(Arg->getType()).castAs<DefinedSVal>();
895*67e74705SXin Li 
896*67e74705SXin Li   std::tie(TrueState, FalseState) =
897*67e74705SXin Li       State->assume(SvalBuilder.evalEQ(State, *DefArgVal, Zero));
898*67e74705SXin Li 
899*67e74705SXin Li   if (TrueState && !FalseState) {
900*67e74705SXin Li     SVal retVal = State->getSVal(E, C.getLocationContext());
901*67e74705SXin Li     SymbolRef Sym = retVal.getAsLocSymbol();
902*67e74705SXin Li     if (!Sym)
903*67e74705SXin Li       return State;
904*67e74705SXin Li 
905*67e74705SXin Li     const RefState *RS = State->get<RegionState>(Sym);
906*67e74705SXin Li     if (RS) {
907*67e74705SXin Li       if (RS->isAllocated())
908*67e74705SXin Li         return TrueState->set<RegionState>(Sym,
909*67e74705SXin Li                                           RefState::getAllocatedOfSizeZero(RS));
910*67e74705SXin Li       else
911*67e74705SXin Li         return State;
912*67e74705SXin Li     } else {
913*67e74705SXin Li       // Case of zero-size realloc. Historically 'realloc(ptr, 0)' is treated as
914*67e74705SXin Li       // 'free(ptr)' and the returned value from 'realloc(ptr, 0)' is not
915*67e74705SXin Li       // tracked. Add zero-reallocated Sym to the state to catch references
916*67e74705SXin Li       // to zero-allocated memory.
917*67e74705SXin Li       return TrueState->add<ReallocSizeZeroSymbols>(Sym);
918*67e74705SXin Li     }
919*67e74705SXin Li   }
920*67e74705SXin Li 
921*67e74705SXin Li   // Assume the value is non-zero going forward.
922*67e74705SXin Li   assert(FalseState);
923*67e74705SXin Li   return FalseState;
924*67e74705SXin Li }
925*67e74705SXin Li 
getDeepPointeeType(QualType T)926*67e74705SXin Li static QualType getDeepPointeeType(QualType T) {
927*67e74705SXin Li   QualType Result = T, PointeeType = T->getPointeeType();
928*67e74705SXin Li   while (!PointeeType.isNull()) {
929*67e74705SXin Li     Result = PointeeType;
930*67e74705SXin Li     PointeeType = PointeeType->getPointeeType();
931*67e74705SXin Li   }
932*67e74705SXin Li   return Result;
933*67e74705SXin Li }
934*67e74705SXin Li 
treatUnusedNewEscaped(const CXXNewExpr * NE)935*67e74705SXin Li static bool treatUnusedNewEscaped(const CXXNewExpr *NE) {
936*67e74705SXin Li 
937*67e74705SXin Li   const CXXConstructExpr *ConstructE = NE->getConstructExpr();
938*67e74705SXin Li   if (!ConstructE)
939*67e74705SXin Li     return false;
940*67e74705SXin Li 
941*67e74705SXin Li   if (!NE->getAllocatedType()->getAsCXXRecordDecl())
942*67e74705SXin Li     return false;
943*67e74705SXin Li 
944*67e74705SXin Li   const CXXConstructorDecl *CtorD = ConstructE->getConstructor();
945*67e74705SXin Li 
946*67e74705SXin Li   // Iterate over the constructor parameters.
947*67e74705SXin Li   for (const auto *CtorParam : CtorD->parameters()) {
948*67e74705SXin Li 
949*67e74705SXin Li     QualType CtorParamPointeeT = CtorParam->getType()->getPointeeType();
950*67e74705SXin Li     if (CtorParamPointeeT.isNull())
951*67e74705SXin Li       continue;
952*67e74705SXin Li 
953*67e74705SXin Li     CtorParamPointeeT = getDeepPointeeType(CtorParamPointeeT);
954*67e74705SXin Li 
955*67e74705SXin Li     if (CtorParamPointeeT->getAsCXXRecordDecl())
956*67e74705SXin Li       return true;
957*67e74705SXin Li   }
958*67e74705SXin Li 
959*67e74705SXin Li   return false;
960*67e74705SXin Li }
961*67e74705SXin Li 
checkPostStmt(const CXXNewExpr * NE,CheckerContext & C) const962*67e74705SXin Li void MallocChecker::checkPostStmt(const CXXNewExpr *NE,
963*67e74705SXin Li                                   CheckerContext &C) const {
964*67e74705SXin Li 
965*67e74705SXin Li   if (NE->getNumPlacementArgs())
966*67e74705SXin Li     for (CXXNewExpr::const_arg_iterator I = NE->placement_arg_begin(),
967*67e74705SXin Li          E = NE->placement_arg_end(); I != E; ++I)
968*67e74705SXin Li       if (SymbolRef Sym = C.getSVal(*I).getAsSymbol())
969*67e74705SXin Li         checkUseAfterFree(Sym, C, *I);
970*67e74705SXin Li 
971*67e74705SXin Li   if (!isStandardNewDelete(NE->getOperatorNew(), C.getASTContext()))
972*67e74705SXin Li     return;
973*67e74705SXin Li 
974*67e74705SXin Li   ParentMap &PM = C.getLocationContext()->getParentMap();
975*67e74705SXin Li   if (!PM.isConsumedExpr(NE) && treatUnusedNewEscaped(NE))
976*67e74705SXin Li     return;
977*67e74705SXin Li 
978*67e74705SXin Li   ProgramStateRef State = C.getState();
979*67e74705SXin Li   // The return value from operator new is bound to a specified initialization
980*67e74705SXin Li   // value (if any) and we don't want to loose this value. So we call
981*67e74705SXin Li   // MallocUpdateRefState() instead of MallocMemAux() which breakes the
982*67e74705SXin Li   // existing binding.
983*67e74705SXin Li   State = MallocUpdateRefState(C, NE, State, NE->isArray() ? AF_CXXNewArray
984*67e74705SXin Li                                                            : AF_CXXNew);
985*67e74705SXin Li   State = ProcessZeroAllocation(C, NE, 0, State);
986*67e74705SXin Li   C.addTransition(State);
987*67e74705SXin Li }
988*67e74705SXin Li 
checkPreStmt(const CXXDeleteExpr * DE,CheckerContext & C) const989*67e74705SXin Li void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE,
990*67e74705SXin Li                                  CheckerContext &C) const {
991*67e74705SXin Li 
992*67e74705SXin Li   if (!ChecksEnabled[CK_NewDeleteChecker])
993*67e74705SXin Li     if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol())
994*67e74705SXin Li       checkUseAfterFree(Sym, C, DE->getArgument());
995*67e74705SXin Li 
996*67e74705SXin Li   if (!isStandardNewDelete(DE->getOperatorDelete(), C.getASTContext()))
997*67e74705SXin Li     return;
998*67e74705SXin Li 
999*67e74705SXin Li   ProgramStateRef State = C.getState();
1000*67e74705SXin Li   bool ReleasedAllocated;
1001*67e74705SXin Li   State = FreeMemAux(C, DE->getArgument(), DE, State,
1002*67e74705SXin Li                      /*Hold*/false, ReleasedAllocated);
1003*67e74705SXin Li 
1004*67e74705SXin Li   C.addTransition(State);
1005*67e74705SXin Li }
1006*67e74705SXin Li 
isKnownDeallocObjCMethodName(const ObjCMethodCall & Call)1007*67e74705SXin Li static bool isKnownDeallocObjCMethodName(const ObjCMethodCall &Call) {
1008*67e74705SXin Li   // If the first selector piece is one of the names below, assume that the
1009*67e74705SXin Li   // object takes ownership of the memory, promising to eventually deallocate it
1010*67e74705SXin Li   // with free().
1011*67e74705SXin Li   // Ex:  [NSData dataWithBytesNoCopy:bytes length:10];
1012*67e74705SXin Li   // (...unless a 'freeWhenDone' parameter is false, but that's checked later.)
1013*67e74705SXin Li   StringRef FirstSlot = Call.getSelector().getNameForSlot(0);
1014*67e74705SXin Li   return FirstSlot == "dataWithBytesNoCopy" ||
1015*67e74705SXin Li          FirstSlot == "initWithBytesNoCopy" ||
1016*67e74705SXin Li          FirstSlot == "initWithCharactersNoCopy";
1017*67e74705SXin Li }
1018*67e74705SXin Li 
getFreeWhenDoneArg(const ObjCMethodCall & Call)1019*67e74705SXin Li static Optional<bool> getFreeWhenDoneArg(const ObjCMethodCall &Call) {
1020*67e74705SXin Li   Selector S = Call.getSelector();
1021*67e74705SXin Li 
1022*67e74705SXin Li   // FIXME: We should not rely on fully-constrained symbols being folded.
1023*67e74705SXin Li   for (unsigned i = 1; i < S.getNumArgs(); ++i)
1024*67e74705SXin Li     if (S.getNameForSlot(i).equals("freeWhenDone"))
1025*67e74705SXin Li       return !Call.getArgSVal(i).isZeroConstant();
1026*67e74705SXin Li 
1027*67e74705SXin Li   return None;
1028*67e74705SXin Li }
1029*67e74705SXin Li 
checkPostObjCMessage(const ObjCMethodCall & Call,CheckerContext & C) const1030*67e74705SXin Li void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call,
1031*67e74705SXin Li                                          CheckerContext &C) const {
1032*67e74705SXin Li   if (C.wasInlined)
1033*67e74705SXin Li     return;
1034*67e74705SXin Li 
1035*67e74705SXin Li   if (!isKnownDeallocObjCMethodName(Call))
1036*67e74705SXin Li     return;
1037*67e74705SXin Li 
1038*67e74705SXin Li   if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(Call))
1039*67e74705SXin Li     if (!*FreeWhenDone)
1040*67e74705SXin Li       return;
1041*67e74705SXin Li 
1042*67e74705SXin Li   bool ReleasedAllocatedMemory;
1043*67e74705SXin Li   ProgramStateRef State = FreeMemAux(C, Call.getArgExpr(0),
1044*67e74705SXin Li                                      Call.getOriginExpr(), C.getState(),
1045*67e74705SXin Li                                      /*Hold=*/true, ReleasedAllocatedMemory,
1046*67e74705SXin Li                                      /*RetNullOnFailure=*/true);
1047*67e74705SXin Li 
1048*67e74705SXin Li   C.addTransition(State);
1049*67e74705SXin Li }
1050*67e74705SXin Li 
1051*67e74705SXin Li ProgramStateRef
MallocMemReturnsAttr(CheckerContext & C,const CallExpr * CE,const OwnershipAttr * Att,ProgramStateRef State) const1052*67e74705SXin Li MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
1053*67e74705SXin Li                                     const OwnershipAttr *Att,
1054*67e74705SXin Li                                     ProgramStateRef State) const {
1055*67e74705SXin Li   if (!State)
1056*67e74705SXin Li     return nullptr;
1057*67e74705SXin Li 
1058*67e74705SXin Li   if (Att->getModule() != II_malloc)
1059*67e74705SXin Li     return nullptr;
1060*67e74705SXin Li 
1061*67e74705SXin Li   OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
1062*67e74705SXin Li   if (I != E) {
1063*67e74705SXin Li     return MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), State);
1064*67e74705SXin Li   }
1065*67e74705SXin Li   return MallocMemAux(C, CE, UnknownVal(), UndefinedVal(), State);
1066*67e74705SXin Li }
1067*67e74705SXin Li 
MallocMemAux(CheckerContext & C,const CallExpr * CE,const Expr * SizeEx,SVal Init,ProgramStateRef State,AllocationFamily Family)1068*67e74705SXin Li ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
1069*67e74705SXin Li                                             const CallExpr *CE,
1070*67e74705SXin Li                                             const Expr *SizeEx, SVal Init,
1071*67e74705SXin Li                                             ProgramStateRef State,
1072*67e74705SXin Li                                             AllocationFamily Family) {
1073*67e74705SXin Li   if (!State)
1074*67e74705SXin Li     return nullptr;
1075*67e74705SXin Li 
1076*67e74705SXin Li   return MallocMemAux(C, CE, State->getSVal(SizeEx, C.getLocationContext()),
1077*67e74705SXin Li                       Init, State, Family);
1078*67e74705SXin Li }
1079*67e74705SXin Li 
MallocMemAux(CheckerContext & C,const CallExpr * CE,SVal Size,SVal Init,ProgramStateRef State,AllocationFamily Family)1080*67e74705SXin Li ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
1081*67e74705SXin Li                                            const CallExpr *CE,
1082*67e74705SXin Li                                            SVal Size, SVal Init,
1083*67e74705SXin Li                                            ProgramStateRef State,
1084*67e74705SXin Li                                            AllocationFamily Family) {
1085*67e74705SXin Li   if (!State)
1086*67e74705SXin Li     return nullptr;
1087*67e74705SXin Li 
1088*67e74705SXin Li   // We expect the malloc functions to return a pointer.
1089*67e74705SXin Li   if (!Loc::isLocType(CE->getType()))
1090*67e74705SXin Li     return nullptr;
1091*67e74705SXin Li 
1092*67e74705SXin Li   // Bind the return value to the symbolic value from the heap region.
1093*67e74705SXin Li   // TODO: We could rewrite post visit to eval call; 'malloc' does not have
1094*67e74705SXin Li   // side effects other than what we model here.
1095*67e74705SXin Li   unsigned Count = C.blockCount();
1096*67e74705SXin Li   SValBuilder &svalBuilder = C.getSValBuilder();
1097*67e74705SXin Li   const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
1098*67e74705SXin Li   DefinedSVal RetVal = svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count)
1099*67e74705SXin Li       .castAs<DefinedSVal>();
1100*67e74705SXin Li   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
1101*67e74705SXin Li 
1102*67e74705SXin Li   // Fill the region with the initialization value.
1103*67e74705SXin Li   State = State->bindDefault(RetVal, Init);
1104*67e74705SXin Li 
1105*67e74705SXin Li   // Set the region's extent equal to the Size parameter.
1106*67e74705SXin Li   const SymbolicRegion *R =
1107*67e74705SXin Li       dyn_cast_or_null<SymbolicRegion>(RetVal.getAsRegion());
1108*67e74705SXin Li   if (!R)
1109*67e74705SXin Li     return nullptr;
1110*67e74705SXin Li   if (Optional<DefinedOrUnknownSVal> DefinedSize =
1111*67e74705SXin Li           Size.getAs<DefinedOrUnknownSVal>()) {
1112*67e74705SXin Li     SValBuilder &svalBuilder = C.getSValBuilder();
1113*67e74705SXin Li     DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
1114*67e74705SXin Li     DefinedOrUnknownSVal extentMatchesSize =
1115*67e74705SXin Li         svalBuilder.evalEQ(State, Extent, *DefinedSize);
1116*67e74705SXin Li 
1117*67e74705SXin Li     State = State->assume(extentMatchesSize, true);
1118*67e74705SXin Li     assert(State);
1119*67e74705SXin Li   }
1120*67e74705SXin Li 
1121*67e74705SXin Li   return MallocUpdateRefState(C, CE, State, Family);
1122*67e74705SXin Li }
1123*67e74705SXin Li 
MallocUpdateRefState(CheckerContext & C,const Expr * E,ProgramStateRef State,AllocationFamily Family)1124*67e74705SXin Li ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C,
1125*67e74705SXin Li                                                     const Expr *E,
1126*67e74705SXin Li                                                     ProgramStateRef State,
1127*67e74705SXin Li                                                     AllocationFamily Family) {
1128*67e74705SXin Li   if (!State)
1129*67e74705SXin Li     return nullptr;
1130*67e74705SXin Li 
1131*67e74705SXin Li   // Get the return value.
1132*67e74705SXin Li   SVal retVal = State->getSVal(E, C.getLocationContext());
1133*67e74705SXin Li 
1134*67e74705SXin Li   // We expect the malloc functions to return a pointer.
1135*67e74705SXin Li   if (!retVal.getAs<Loc>())
1136*67e74705SXin Li     return nullptr;
1137*67e74705SXin Li 
1138*67e74705SXin Li   SymbolRef Sym = retVal.getAsLocSymbol();
1139*67e74705SXin Li   assert(Sym);
1140*67e74705SXin Li 
1141*67e74705SXin Li   // Set the symbol's state to Allocated.
1142*67e74705SXin Li   return State->set<RegionState>(Sym, RefState::getAllocated(Family, E));
1143*67e74705SXin Li }
1144*67e74705SXin Li 
FreeMemAttr(CheckerContext & C,const CallExpr * CE,const OwnershipAttr * Att,ProgramStateRef State) const1145*67e74705SXin Li ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C,
1146*67e74705SXin Li                                            const CallExpr *CE,
1147*67e74705SXin Li                                            const OwnershipAttr *Att,
1148*67e74705SXin Li                                            ProgramStateRef State) const {
1149*67e74705SXin Li   if (!State)
1150*67e74705SXin Li     return nullptr;
1151*67e74705SXin Li 
1152*67e74705SXin Li   if (Att->getModule() != II_malloc)
1153*67e74705SXin Li     return nullptr;
1154*67e74705SXin Li 
1155*67e74705SXin Li   bool ReleasedAllocated = false;
1156*67e74705SXin Li 
1157*67e74705SXin Li   for (const auto &Arg : Att->args()) {
1158*67e74705SXin Li     ProgramStateRef StateI = FreeMemAux(C, CE, State, Arg,
1159*67e74705SXin Li                                Att->getOwnKind() == OwnershipAttr::Holds,
1160*67e74705SXin Li                                ReleasedAllocated);
1161*67e74705SXin Li     if (StateI)
1162*67e74705SXin Li       State = StateI;
1163*67e74705SXin Li   }
1164*67e74705SXin Li   return State;
1165*67e74705SXin Li }
1166*67e74705SXin Li 
FreeMemAux(CheckerContext & C,const CallExpr * CE,ProgramStateRef State,unsigned Num,bool Hold,bool & ReleasedAllocated,bool ReturnsNullOnFailure) const1167*67e74705SXin Li ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
1168*67e74705SXin Li                                           const CallExpr *CE,
1169*67e74705SXin Li                                           ProgramStateRef State,
1170*67e74705SXin Li                                           unsigned Num,
1171*67e74705SXin Li                                           bool Hold,
1172*67e74705SXin Li                                           bool &ReleasedAllocated,
1173*67e74705SXin Li                                           bool ReturnsNullOnFailure) const {
1174*67e74705SXin Li   if (!State)
1175*67e74705SXin Li     return nullptr;
1176*67e74705SXin Li 
1177*67e74705SXin Li   if (CE->getNumArgs() < (Num + 1))
1178*67e74705SXin Li     return nullptr;
1179*67e74705SXin Li 
1180*67e74705SXin Li   return FreeMemAux(C, CE->getArg(Num), CE, State, Hold,
1181*67e74705SXin Li                     ReleasedAllocated, ReturnsNullOnFailure);
1182*67e74705SXin Li }
1183*67e74705SXin Li 
1184*67e74705SXin Li /// Checks if the previous call to free on the given symbol failed - if free
1185*67e74705SXin Li /// failed, returns true. Also, returns the corresponding return value symbol.
didPreviousFreeFail(ProgramStateRef State,SymbolRef Sym,SymbolRef & RetStatusSymbol)1186*67e74705SXin Li static bool didPreviousFreeFail(ProgramStateRef State,
1187*67e74705SXin Li                                 SymbolRef Sym, SymbolRef &RetStatusSymbol) {
1188*67e74705SXin Li   const SymbolRef *Ret = State->get<FreeReturnValue>(Sym);
1189*67e74705SXin Li   if (Ret) {
1190*67e74705SXin Li     assert(*Ret && "We should not store the null return symbol");
1191*67e74705SXin Li     ConstraintManager &CMgr = State->getConstraintManager();
1192*67e74705SXin Li     ConditionTruthVal FreeFailed = CMgr.isNull(State, *Ret);
1193*67e74705SXin Li     RetStatusSymbol = *Ret;
1194*67e74705SXin Li     return FreeFailed.isConstrainedTrue();
1195*67e74705SXin Li   }
1196*67e74705SXin Li   return false;
1197*67e74705SXin Li }
1198*67e74705SXin Li 
getAllocationFamily(CheckerContext & C,const Stmt * S) const1199*67e74705SXin Li AllocationFamily MallocChecker::getAllocationFamily(CheckerContext &C,
1200*67e74705SXin Li                                                     const Stmt *S) const {
1201*67e74705SXin Li   if (!S)
1202*67e74705SXin Li     return AF_None;
1203*67e74705SXin Li 
1204*67e74705SXin Li   if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
1205*67e74705SXin Li     const FunctionDecl *FD = C.getCalleeDecl(CE);
1206*67e74705SXin Li 
1207*67e74705SXin Li     if (!FD)
1208*67e74705SXin Li       FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
1209*67e74705SXin Li 
1210*67e74705SXin Li     ASTContext &Ctx = C.getASTContext();
1211*67e74705SXin Li 
1212*67e74705SXin Li     if (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Any))
1213*67e74705SXin Li       return AF_Malloc;
1214*67e74705SXin Li 
1215*67e74705SXin Li     if (isStandardNewDelete(FD, Ctx)) {
1216*67e74705SXin Li       OverloadedOperatorKind Kind = FD->getOverloadedOperator();
1217*67e74705SXin Li       if (Kind == OO_New || Kind == OO_Delete)
1218*67e74705SXin Li         return AF_CXXNew;
1219*67e74705SXin Li       else if (Kind == OO_Array_New || Kind == OO_Array_Delete)
1220*67e74705SXin Li         return AF_CXXNewArray;
1221*67e74705SXin Li     }
1222*67e74705SXin Li 
1223*67e74705SXin Li     if (isCMemFunction(FD, Ctx, AF_IfNameIndex, MemoryOperationKind::MOK_Any))
1224*67e74705SXin Li       return AF_IfNameIndex;
1225*67e74705SXin Li 
1226*67e74705SXin Li     if (isCMemFunction(FD, Ctx, AF_Alloca, MemoryOperationKind::MOK_Any))
1227*67e74705SXin Li       return AF_Alloca;
1228*67e74705SXin Li 
1229*67e74705SXin Li     return AF_None;
1230*67e74705SXin Li   }
1231*67e74705SXin Li 
1232*67e74705SXin Li   if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(S))
1233*67e74705SXin Li     return NE->isArray() ? AF_CXXNewArray : AF_CXXNew;
1234*67e74705SXin Li 
1235*67e74705SXin Li   if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(S))
1236*67e74705SXin Li     return DE->isArrayForm() ? AF_CXXNewArray : AF_CXXNew;
1237*67e74705SXin Li 
1238*67e74705SXin Li   if (isa<ObjCMessageExpr>(S))
1239*67e74705SXin Li     return AF_Malloc;
1240*67e74705SXin Li 
1241*67e74705SXin Li   return AF_None;
1242*67e74705SXin Li }
1243*67e74705SXin Li 
printAllocDeallocName(raw_ostream & os,CheckerContext & C,const Expr * E) const1244*67e74705SXin Li bool MallocChecker::printAllocDeallocName(raw_ostream &os, CheckerContext &C,
1245*67e74705SXin Li                                           const Expr *E) const {
1246*67e74705SXin Li   if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
1247*67e74705SXin Li     // FIXME: This doesn't handle indirect calls.
1248*67e74705SXin Li     const FunctionDecl *FD = CE->getDirectCallee();
1249*67e74705SXin Li     if (!FD)
1250*67e74705SXin Li       return false;
1251*67e74705SXin Li 
1252*67e74705SXin Li     os << *FD;
1253*67e74705SXin Li     if (!FD->isOverloadedOperator())
1254*67e74705SXin Li       os << "()";
1255*67e74705SXin Li     return true;
1256*67e74705SXin Li   }
1257*67e74705SXin Li 
1258*67e74705SXin Li   if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) {
1259*67e74705SXin Li     if (Msg->isInstanceMessage())
1260*67e74705SXin Li       os << "-";
1261*67e74705SXin Li     else
1262*67e74705SXin Li       os << "+";
1263*67e74705SXin Li     Msg->getSelector().print(os);
1264*67e74705SXin Li     return true;
1265*67e74705SXin Li   }
1266*67e74705SXin Li 
1267*67e74705SXin Li   if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) {
1268*67e74705SXin Li     os << "'"
1269*67e74705SXin Li        << getOperatorSpelling(NE->getOperatorNew()->getOverloadedOperator())
1270*67e74705SXin Li        << "'";
1271*67e74705SXin Li     return true;
1272*67e74705SXin Li   }
1273*67e74705SXin Li 
1274*67e74705SXin Li   if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(E)) {
1275*67e74705SXin Li     os << "'"
1276*67e74705SXin Li        << getOperatorSpelling(DE->getOperatorDelete()->getOverloadedOperator())
1277*67e74705SXin Li        << "'";
1278*67e74705SXin Li     return true;
1279*67e74705SXin Li   }
1280*67e74705SXin Li 
1281*67e74705SXin Li   return false;
1282*67e74705SXin Li }
1283*67e74705SXin Li 
printExpectedAllocName(raw_ostream & os,CheckerContext & C,const Expr * E) const1284*67e74705SXin Li void MallocChecker::printExpectedAllocName(raw_ostream &os, CheckerContext &C,
1285*67e74705SXin Li                                            const Expr *E) const {
1286*67e74705SXin Li   AllocationFamily Family = getAllocationFamily(C, E);
1287*67e74705SXin Li 
1288*67e74705SXin Li   switch(Family) {
1289*67e74705SXin Li     case AF_Malloc: os << "malloc()"; return;
1290*67e74705SXin Li     case AF_CXXNew: os << "'new'"; return;
1291*67e74705SXin Li     case AF_CXXNewArray: os << "'new[]'"; return;
1292*67e74705SXin Li     case AF_IfNameIndex: os << "'if_nameindex()'"; return;
1293*67e74705SXin Li     case AF_Alloca:
1294*67e74705SXin Li     case AF_None: llvm_unreachable("not a deallocation expression");
1295*67e74705SXin Li   }
1296*67e74705SXin Li }
1297*67e74705SXin Li 
printExpectedDeallocName(raw_ostream & os,AllocationFamily Family) const1298*67e74705SXin Li void MallocChecker::printExpectedDeallocName(raw_ostream &os,
1299*67e74705SXin Li                                              AllocationFamily Family) const {
1300*67e74705SXin Li   switch(Family) {
1301*67e74705SXin Li     case AF_Malloc: os << "free()"; return;
1302*67e74705SXin Li     case AF_CXXNew: os << "'delete'"; return;
1303*67e74705SXin Li     case AF_CXXNewArray: os << "'delete[]'"; return;
1304*67e74705SXin Li     case AF_IfNameIndex: os << "'if_freenameindex()'"; return;
1305*67e74705SXin Li     case AF_Alloca:
1306*67e74705SXin Li     case AF_None: llvm_unreachable("suspicious argument");
1307*67e74705SXin Li   }
1308*67e74705SXin Li }
1309*67e74705SXin Li 
FreeMemAux(CheckerContext & C,const Expr * ArgExpr,const Expr * ParentExpr,ProgramStateRef State,bool Hold,bool & ReleasedAllocated,bool ReturnsNullOnFailure) const1310*67e74705SXin Li ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
1311*67e74705SXin Li                                           const Expr *ArgExpr,
1312*67e74705SXin Li                                           const Expr *ParentExpr,
1313*67e74705SXin Li                                           ProgramStateRef State,
1314*67e74705SXin Li                                           bool Hold,
1315*67e74705SXin Li                                           bool &ReleasedAllocated,
1316*67e74705SXin Li                                           bool ReturnsNullOnFailure) const {
1317*67e74705SXin Li 
1318*67e74705SXin Li   if (!State)
1319*67e74705SXin Li     return nullptr;
1320*67e74705SXin Li 
1321*67e74705SXin Li   SVal ArgVal = State->getSVal(ArgExpr, C.getLocationContext());
1322*67e74705SXin Li   if (!ArgVal.getAs<DefinedOrUnknownSVal>())
1323*67e74705SXin Li     return nullptr;
1324*67e74705SXin Li   DefinedOrUnknownSVal location = ArgVal.castAs<DefinedOrUnknownSVal>();
1325*67e74705SXin Li 
1326*67e74705SXin Li   // Check for null dereferences.
1327*67e74705SXin Li   if (!location.getAs<Loc>())
1328*67e74705SXin Li     return nullptr;
1329*67e74705SXin Li 
1330*67e74705SXin Li   // The explicit NULL case, no operation is performed.
1331*67e74705SXin Li   ProgramStateRef notNullState, nullState;
1332*67e74705SXin Li   std::tie(notNullState, nullState) = State->assume(location);
1333*67e74705SXin Li   if (nullState && !notNullState)
1334*67e74705SXin Li     return nullptr;
1335*67e74705SXin Li 
1336*67e74705SXin Li   // Unknown values could easily be okay
1337*67e74705SXin Li   // Undefined values are handled elsewhere
1338*67e74705SXin Li   if (ArgVal.isUnknownOrUndef())
1339*67e74705SXin Li     return nullptr;
1340*67e74705SXin Li 
1341*67e74705SXin Li   const MemRegion *R = ArgVal.getAsRegion();
1342*67e74705SXin Li 
1343*67e74705SXin Li   // Nonlocs can't be freed, of course.
1344*67e74705SXin Li   // Non-region locations (labels and fixed addresses) also shouldn't be freed.
1345*67e74705SXin Li   if (!R) {
1346*67e74705SXin Li     ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
1347*67e74705SXin Li     return nullptr;
1348*67e74705SXin Li   }
1349*67e74705SXin Li 
1350*67e74705SXin Li   R = R->StripCasts();
1351*67e74705SXin Li 
1352*67e74705SXin Li   // Blocks might show up as heap data, but should not be free()d
1353*67e74705SXin Li   if (isa<BlockDataRegion>(R)) {
1354*67e74705SXin Li     ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
1355*67e74705SXin Li     return nullptr;
1356*67e74705SXin Li   }
1357*67e74705SXin Li 
1358*67e74705SXin Li   const MemSpaceRegion *MS = R->getMemorySpace();
1359*67e74705SXin Li 
1360*67e74705SXin Li   // Parameters, locals, statics, globals, and memory returned by
1361*67e74705SXin Li   // __builtin_alloca() shouldn't be freed.
1362*67e74705SXin Li   if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
1363*67e74705SXin Li     // FIXME: at the time this code was written, malloc() regions were
1364*67e74705SXin Li     // represented by conjured symbols, which are all in UnknownSpaceRegion.
1365*67e74705SXin Li     // This means that there isn't actually anything from HeapSpaceRegion
1366*67e74705SXin Li     // that should be freed, even though we allow it here.
1367*67e74705SXin Li     // Of course, free() can work on memory allocated outside the current
1368*67e74705SXin Li     // function, so UnknownSpaceRegion is always a possibility.
1369*67e74705SXin Li     // False negatives are better than false positives.
1370*67e74705SXin Li 
1371*67e74705SXin Li     if (isa<AllocaRegion>(R))
1372*67e74705SXin Li       ReportFreeAlloca(C, ArgVal, ArgExpr->getSourceRange());
1373*67e74705SXin Li     else
1374*67e74705SXin Li       ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
1375*67e74705SXin Li 
1376*67e74705SXin Li     return nullptr;
1377*67e74705SXin Li   }
1378*67e74705SXin Li 
1379*67e74705SXin Li   const SymbolicRegion *SrBase = dyn_cast<SymbolicRegion>(R->getBaseRegion());
1380*67e74705SXin Li   // Various cases could lead to non-symbol values here.
1381*67e74705SXin Li   // For now, ignore them.
1382*67e74705SXin Li   if (!SrBase)
1383*67e74705SXin Li     return nullptr;
1384*67e74705SXin Li 
1385*67e74705SXin Li   SymbolRef SymBase = SrBase->getSymbol();
1386*67e74705SXin Li   const RefState *RsBase = State->get<RegionState>(SymBase);
1387*67e74705SXin Li   SymbolRef PreviousRetStatusSymbol = nullptr;
1388*67e74705SXin Li 
1389*67e74705SXin Li   if (RsBase) {
1390*67e74705SXin Li 
1391*67e74705SXin Li     // Memory returned by alloca() shouldn't be freed.
1392*67e74705SXin Li     if (RsBase->getAllocationFamily() == AF_Alloca) {
1393*67e74705SXin Li       ReportFreeAlloca(C, ArgVal, ArgExpr->getSourceRange());
1394*67e74705SXin Li       return nullptr;
1395*67e74705SXin Li     }
1396*67e74705SXin Li 
1397*67e74705SXin Li     // Check for double free first.
1398*67e74705SXin Li     if ((RsBase->isReleased() || RsBase->isRelinquished()) &&
1399*67e74705SXin Li         !didPreviousFreeFail(State, SymBase, PreviousRetStatusSymbol)) {
1400*67e74705SXin Li       ReportDoubleFree(C, ParentExpr->getSourceRange(), RsBase->isReleased(),
1401*67e74705SXin Li                        SymBase, PreviousRetStatusSymbol);
1402*67e74705SXin Li       return nullptr;
1403*67e74705SXin Li 
1404*67e74705SXin Li     // If the pointer is allocated or escaped, but we are now trying to free it,
1405*67e74705SXin Li     // check that the call to free is proper.
1406*67e74705SXin Li     } else if (RsBase->isAllocated() || RsBase->isAllocatedOfSizeZero() ||
1407*67e74705SXin Li                RsBase->isEscaped()) {
1408*67e74705SXin Li 
1409*67e74705SXin Li       // Check if an expected deallocation function matches the real one.
1410*67e74705SXin Li       bool DeallocMatchesAlloc =
1411*67e74705SXin Li         RsBase->getAllocationFamily() == getAllocationFamily(C, ParentExpr);
1412*67e74705SXin Li       if (!DeallocMatchesAlloc) {
1413*67e74705SXin Li         ReportMismatchedDealloc(C, ArgExpr->getSourceRange(),
1414*67e74705SXin Li                                 ParentExpr, RsBase, SymBase, Hold);
1415*67e74705SXin Li         return nullptr;
1416*67e74705SXin Li       }
1417*67e74705SXin Li 
1418*67e74705SXin Li       // Check if the memory location being freed is the actual location
1419*67e74705SXin Li       // allocated, or an offset.
1420*67e74705SXin Li       RegionOffset Offset = R->getAsOffset();
1421*67e74705SXin Li       if (Offset.isValid() &&
1422*67e74705SXin Li           !Offset.hasSymbolicOffset() &&
1423*67e74705SXin Li           Offset.getOffset() != 0) {
1424*67e74705SXin Li         const Expr *AllocExpr = cast<Expr>(RsBase->getStmt());
1425*67e74705SXin Li         ReportOffsetFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
1426*67e74705SXin Li                          AllocExpr);
1427*67e74705SXin Li         return nullptr;
1428*67e74705SXin Li       }
1429*67e74705SXin Li     }
1430*67e74705SXin Li   }
1431*67e74705SXin Li 
1432*67e74705SXin Li   ReleasedAllocated = (RsBase != nullptr) && (RsBase->isAllocated() ||
1433*67e74705SXin Li                                               RsBase->isAllocatedOfSizeZero());
1434*67e74705SXin Li 
1435*67e74705SXin Li   // Clean out the info on previous call to free return info.
1436*67e74705SXin Li   State = State->remove<FreeReturnValue>(SymBase);
1437*67e74705SXin Li 
1438*67e74705SXin Li   // Keep track of the return value. If it is NULL, we will know that free
1439*67e74705SXin Li   // failed.
1440*67e74705SXin Li   if (ReturnsNullOnFailure) {
1441*67e74705SXin Li     SVal RetVal = C.getSVal(ParentExpr);
1442*67e74705SXin Li     SymbolRef RetStatusSymbol = RetVal.getAsSymbol();
1443*67e74705SXin Li     if (RetStatusSymbol) {
1444*67e74705SXin Li       C.getSymbolManager().addSymbolDependency(SymBase, RetStatusSymbol);
1445*67e74705SXin Li       State = State->set<FreeReturnValue>(SymBase, RetStatusSymbol);
1446*67e74705SXin Li     }
1447*67e74705SXin Li   }
1448*67e74705SXin Li 
1449*67e74705SXin Li   AllocationFamily Family = RsBase ? RsBase->getAllocationFamily()
1450*67e74705SXin Li                                    : getAllocationFamily(C, ParentExpr);
1451*67e74705SXin Li   // Normal free.
1452*67e74705SXin Li   if (Hold)
1453*67e74705SXin Li     return State->set<RegionState>(SymBase,
1454*67e74705SXin Li                                    RefState::getRelinquished(Family,
1455*67e74705SXin Li                                                              ParentExpr));
1456*67e74705SXin Li 
1457*67e74705SXin Li   return State->set<RegionState>(SymBase,
1458*67e74705SXin Li                                  RefState::getReleased(Family, ParentExpr));
1459*67e74705SXin Li }
1460*67e74705SXin Li 
1461*67e74705SXin Li Optional<MallocChecker::CheckKind>
getCheckIfTracked(AllocationFamily Family,bool IsALeakCheck) const1462*67e74705SXin Li MallocChecker::getCheckIfTracked(AllocationFamily Family,
1463*67e74705SXin Li                                  bool IsALeakCheck) const {
1464*67e74705SXin Li   switch (Family) {
1465*67e74705SXin Li   case AF_Malloc:
1466*67e74705SXin Li   case AF_Alloca:
1467*67e74705SXin Li   case AF_IfNameIndex: {
1468*67e74705SXin Li     if (ChecksEnabled[CK_MallocChecker])
1469*67e74705SXin Li       return CK_MallocChecker;
1470*67e74705SXin Li 
1471*67e74705SXin Li     return Optional<MallocChecker::CheckKind>();
1472*67e74705SXin Li   }
1473*67e74705SXin Li   case AF_CXXNew:
1474*67e74705SXin Li   case AF_CXXNewArray: {
1475*67e74705SXin Li     if (IsALeakCheck) {
1476*67e74705SXin Li       if (ChecksEnabled[CK_NewDeleteLeaksChecker])
1477*67e74705SXin Li         return CK_NewDeleteLeaksChecker;
1478*67e74705SXin Li     }
1479*67e74705SXin Li     else {
1480*67e74705SXin Li       if (ChecksEnabled[CK_NewDeleteChecker])
1481*67e74705SXin Li         return CK_NewDeleteChecker;
1482*67e74705SXin Li     }
1483*67e74705SXin Li     return Optional<MallocChecker::CheckKind>();
1484*67e74705SXin Li   }
1485*67e74705SXin Li   case AF_None: {
1486*67e74705SXin Li     llvm_unreachable("no family");
1487*67e74705SXin Li   }
1488*67e74705SXin Li   }
1489*67e74705SXin Li   llvm_unreachable("unhandled family");
1490*67e74705SXin Li }
1491*67e74705SXin Li 
1492*67e74705SXin Li Optional<MallocChecker::CheckKind>
getCheckIfTracked(CheckerContext & C,const Stmt * AllocDeallocStmt,bool IsALeakCheck) const1493*67e74705SXin Li MallocChecker::getCheckIfTracked(CheckerContext &C,
1494*67e74705SXin Li                                  const Stmt *AllocDeallocStmt,
1495*67e74705SXin Li                                  bool IsALeakCheck) const {
1496*67e74705SXin Li   return getCheckIfTracked(getAllocationFamily(C, AllocDeallocStmt),
1497*67e74705SXin Li                            IsALeakCheck);
1498*67e74705SXin Li }
1499*67e74705SXin Li 
1500*67e74705SXin Li Optional<MallocChecker::CheckKind>
getCheckIfTracked(CheckerContext & C,SymbolRef Sym,bool IsALeakCheck) const1501*67e74705SXin Li MallocChecker::getCheckIfTracked(CheckerContext &C, SymbolRef Sym,
1502*67e74705SXin Li                                  bool IsALeakCheck) const {
1503*67e74705SXin Li   if (C.getState()->contains<ReallocSizeZeroSymbols>(Sym))
1504*67e74705SXin Li     return CK_MallocChecker;
1505*67e74705SXin Li 
1506*67e74705SXin Li   const RefState *RS = C.getState()->get<RegionState>(Sym);
1507*67e74705SXin Li   assert(RS);
1508*67e74705SXin Li   return getCheckIfTracked(RS->getAllocationFamily(), IsALeakCheck);
1509*67e74705SXin Li }
1510*67e74705SXin Li 
SummarizeValue(raw_ostream & os,SVal V)1511*67e74705SXin Li bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
1512*67e74705SXin Li   if (Optional<nonloc::ConcreteInt> IntVal = V.getAs<nonloc::ConcreteInt>())
1513*67e74705SXin Li     os << "an integer (" << IntVal->getValue() << ")";
1514*67e74705SXin Li   else if (Optional<loc::ConcreteInt> ConstAddr = V.getAs<loc::ConcreteInt>())
1515*67e74705SXin Li     os << "a constant address (" << ConstAddr->getValue() << ")";
1516*67e74705SXin Li   else if (Optional<loc::GotoLabel> Label = V.getAs<loc::GotoLabel>())
1517*67e74705SXin Li     os << "the address of the label '" << Label->getLabel()->getName() << "'";
1518*67e74705SXin Li   else
1519*67e74705SXin Li     return false;
1520*67e74705SXin Li 
1521*67e74705SXin Li   return true;
1522*67e74705SXin Li }
1523*67e74705SXin Li 
SummarizeRegion(raw_ostream & os,const MemRegion * MR)1524*67e74705SXin Li bool MallocChecker::SummarizeRegion(raw_ostream &os,
1525*67e74705SXin Li                                     const MemRegion *MR) {
1526*67e74705SXin Li   switch (MR->getKind()) {
1527*67e74705SXin Li   case MemRegion::FunctionCodeRegionKind: {
1528*67e74705SXin Li     const NamedDecl *FD = cast<FunctionCodeRegion>(MR)->getDecl();
1529*67e74705SXin Li     if (FD)
1530*67e74705SXin Li       os << "the address of the function '" << *FD << '\'';
1531*67e74705SXin Li     else
1532*67e74705SXin Li       os << "the address of a function";
1533*67e74705SXin Li     return true;
1534*67e74705SXin Li   }
1535*67e74705SXin Li   case MemRegion::BlockCodeRegionKind:
1536*67e74705SXin Li     os << "block text";
1537*67e74705SXin Li     return true;
1538*67e74705SXin Li   case MemRegion::BlockDataRegionKind:
1539*67e74705SXin Li     // FIXME: where the block came from?
1540*67e74705SXin Li     os << "a block";
1541*67e74705SXin Li     return true;
1542*67e74705SXin Li   default: {
1543*67e74705SXin Li     const MemSpaceRegion *MS = MR->getMemorySpace();
1544*67e74705SXin Li 
1545*67e74705SXin Li     if (isa<StackLocalsSpaceRegion>(MS)) {
1546*67e74705SXin Li       const VarRegion *VR = dyn_cast<VarRegion>(MR);
1547*67e74705SXin Li       const VarDecl *VD;
1548*67e74705SXin Li       if (VR)
1549*67e74705SXin Li         VD = VR->getDecl();
1550*67e74705SXin Li       else
1551*67e74705SXin Li         VD = nullptr;
1552*67e74705SXin Li 
1553*67e74705SXin Li       if (VD)
1554*67e74705SXin Li         os << "the address of the local variable '" << VD->getName() << "'";
1555*67e74705SXin Li       else
1556*67e74705SXin Li         os << "the address of a local stack variable";
1557*67e74705SXin Li       return true;
1558*67e74705SXin Li     }
1559*67e74705SXin Li 
1560*67e74705SXin Li     if (isa<StackArgumentsSpaceRegion>(MS)) {
1561*67e74705SXin Li       const VarRegion *VR = dyn_cast<VarRegion>(MR);
1562*67e74705SXin Li       const VarDecl *VD;
1563*67e74705SXin Li       if (VR)
1564*67e74705SXin Li         VD = VR->getDecl();
1565*67e74705SXin Li       else
1566*67e74705SXin Li         VD = nullptr;
1567*67e74705SXin Li 
1568*67e74705SXin Li       if (VD)
1569*67e74705SXin Li         os << "the address of the parameter '" << VD->getName() << "'";
1570*67e74705SXin Li       else
1571*67e74705SXin Li         os << "the address of a parameter";
1572*67e74705SXin Li       return true;
1573*67e74705SXin Li     }
1574*67e74705SXin Li 
1575*67e74705SXin Li     if (isa<GlobalsSpaceRegion>(MS)) {
1576*67e74705SXin Li       const VarRegion *VR = dyn_cast<VarRegion>(MR);
1577*67e74705SXin Li       const VarDecl *VD;
1578*67e74705SXin Li       if (VR)
1579*67e74705SXin Li         VD = VR->getDecl();
1580*67e74705SXin Li       else
1581*67e74705SXin Li         VD = nullptr;
1582*67e74705SXin Li 
1583*67e74705SXin Li       if (VD) {
1584*67e74705SXin Li         if (VD->isStaticLocal())
1585*67e74705SXin Li           os << "the address of the static variable '" << VD->getName() << "'";
1586*67e74705SXin Li         else
1587*67e74705SXin Li           os << "the address of the global variable '" << VD->getName() << "'";
1588*67e74705SXin Li       } else
1589*67e74705SXin Li         os << "the address of a global variable";
1590*67e74705SXin Li       return true;
1591*67e74705SXin Li     }
1592*67e74705SXin Li 
1593*67e74705SXin Li     return false;
1594*67e74705SXin Li   }
1595*67e74705SXin Li   }
1596*67e74705SXin Li }
1597*67e74705SXin Li 
ReportBadFree(CheckerContext & C,SVal ArgVal,SourceRange Range,const Expr * DeallocExpr) const1598*67e74705SXin Li void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
1599*67e74705SXin Li                                   SourceRange Range,
1600*67e74705SXin Li                                   const Expr *DeallocExpr) const {
1601*67e74705SXin Li 
1602*67e74705SXin Li   if (!ChecksEnabled[CK_MallocChecker] &&
1603*67e74705SXin Li       !ChecksEnabled[CK_NewDeleteChecker])
1604*67e74705SXin Li     return;
1605*67e74705SXin Li 
1606*67e74705SXin Li   Optional<MallocChecker::CheckKind> CheckKind =
1607*67e74705SXin Li       getCheckIfTracked(C, DeallocExpr);
1608*67e74705SXin Li   if (!CheckKind.hasValue())
1609*67e74705SXin Li     return;
1610*67e74705SXin Li 
1611*67e74705SXin Li   if (ExplodedNode *N = C.generateErrorNode()) {
1612*67e74705SXin Li     if (!BT_BadFree[*CheckKind])
1613*67e74705SXin Li       BT_BadFree[*CheckKind].reset(
1614*67e74705SXin Li           new BugType(CheckNames[*CheckKind], "Bad free", "Memory Error"));
1615*67e74705SXin Li 
1616*67e74705SXin Li     SmallString<100> buf;
1617*67e74705SXin Li     llvm::raw_svector_ostream os(buf);
1618*67e74705SXin Li 
1619*67e74705SXin Li     const MemRegion *MR = ArgVal.getAsRegion();
1620*67e74705SXin Li     while (const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(MR))
1621*67e74705SXin Li       MR = ER->getSuperRegion();
1622*67e74705SXin Li 
1623*67e74705SXin Li     os << "Argument to ";
1624*67e74705SXin Li     if (!printAllocDeallocName(os, C, DeallocExpr))
1625*67e74705SXin Li       os << "deallocator";
1626*67e74705SXin Li 
1627*67e74705SXin Li     os << " is ";
1628*67e74705SXin Li     bool Summarized = MR ? SummarizeRegion(os, MR)
1629*67e74705SXin Li                          : SummarizeValue(os, ArgVal);
1630*67e74705SXin Li     if (Summarized)
1631*67e74705SXin Li       os << ", which is not memory allocated by ";
1632*67e74705SXin Li     else
1633*67e74705SXin Li       os << "not memory allocated by ";
1634*67e74705SXin Li 
1635*67e74705SXin Li     printExpectedAllocName(os, C, DeallocExpr);
1636*67e74705SXin Li 
1637*67e74705SXin Li     auto R = llvm::make_unique<BugReport>(*BT_BadFree[*CheckKind], os.str(), N);
1638*67e74705SXin Li     R->markInteresting(MR);
1639*67e74705SXin Li     R->addRange(Range);
1640*67e74705SXin Li     C.emitReport(std::move(R));
1641*67e74705SXin Li   }
1642*67e74705SXin Li }
1643*67e74705SXin Li 
ReportFreeAlloca(CheckerContext & C,SVal ArgVal,SourceRange Range) const1644*67e74705SXin Li void MallocChecker::ReportFreeAlloca(CheckerContext &C, SVal ArgVal,
1645*67e74705SXin Li                                      SourceRange Range) const {
1646*67e74705SXin Li 
1647*67e74705SXin Li   Optional<MallocChecker::CheckKind> CheckKind;
1648*67e74705SXin Li 
1649*67e74705SXin Li   if (ChecksEnabled[CK_MallocChecker])
1650*67e74705SXin Li     CheckKind = CK_MallocChecker;
1651*67e74705SXin Li   else if (ChecksEnabled[CK_MismatchedDeallocatorChecker])
1652*67e74705SXin Li     CheckKind = CK_MismatchedDeallocatorChecker;
1653*67e74705SXin Li   else
1654*67e74705SXin Li     return;
1655*67e74705SXin Li 
1656*67e74705SXin Li   if (ExplodedNode *N = C.generateErrorNode()) {
1657*67e74705SXin Li     if (!BT_FreeAlloca[*CheckKind])
1658*67e74705SXin Li       BT_FreeAlloca[*CheckKind].reset(
1659*67e74705SXin Li           new BugType(CheckNames[*CheckKind], "Free alloca()", "Memory Error"));
1660*67e74705SXin Li 
1661*67e74705SXin Li     auto R = llvm::make_unique<BugReport>(
1662*67e74705SXin Li         *BT_FreeAlloca[*CheckKind],
1663*67e74705SXin Li         "Memory allocated by alloca() should not be deallocated", N);
1664*67e74705SXin Li     R->markInteresting(ArgVal.getAsRegion());
1665*67e74705SXin Li     R->addRange(Range);
1666*67e74705SXin Li     C.emitReport(std::move(R));
1667*67e74705SXin Li   }
1668*67e74705SXin Li }
1669*67e74705SXin Li 
ReportMismatchedDealloc(CheckerContext & C,SourceRange Range,const Expr * DeallocExpr,const RefState * RS,SymbolRef Sym,bool OwnershipTransferred) const1670*67e74705SXin Li void MallocChecker::ReportMismatchedDealloc(CheckerContext &C,
1671*67e74705SXin Li                                             SourceRange Range,
1672*67e74705SXin Li                                             const Expr *DeallocExpr,
1673*67e74705SXin Li                                             const RefState *RS,
1674*67e74705SXin Li                                             SymbolRef Sym,
1675*67e74705SXin Li                                             bool OwnershipTransferred) const {
1676*67e74705SXin Li 
1677*67e74705SXin Li   if (!ChecksEnabled[CK_MismatchedDeallocatorChecker])
1678*67e74705SXin Li     return;
1679*67e74705SXin Li 
1680*67e74705SXin Li   if (ExplodedNode *N = C.generateErrorNode()) {
1681*67e74705SXin Li     if (!BT_MismatchedDealloc)
1682*67e74705SXin Li       BT_MismatchedDealloc.reset(
1683*67e74705SXin Li           new BugType(CheckNames[CK_MismatchedDeallocatorChecker],
1684*67e74705SXin Li                       "Bad deallocator", "Memory Error"));
1685*67e74705SXin Li 
1686*67e74705SXin Li     SmallString<100> buf;
1687*67e74705SXin Li     llvm::raw_svector_ostream os(buf);
1688*67e74705SXin Li 
1689*67e74705SXin Li     const Expr *AllocExpr = cast<Expr>(RS->getStmt());
1690*67e74705SXin Li     SmallString<20> AllocBuf;
1691*67e74705SXin Li     llvm::raw_svector_ostream AllocOs(AllocBuf);
1692*67e74705SXin Li     SmallString<20> DeallocBuf;
1693*67e74705SXin Li     llvm::raw_svector_ostream DeallocOs(DeallocBuf);
1694*67e74705SXin Li 
1695*67e74705SXin Li     if (OwnershipTransferred) {
1696*67e74705SXin Li       if (printAllocDeallocName(DeallocOs, C, DeallocExpr))
1697*67e74705SXin Li         os << DeallocOs.str() << " cannot";
1698*67e74705SXin Li       else
1699*67e74705SXin Li         os << "Cannot";
1700*67e74705SXin Li 
1701*67e74705SXin Li       os << " take ownership of memory";
1702*67e74705SXin Li 
1703*67e74705SXin Li       if (printAllocDeallocName(AllocOs, C, AllocExpr))
1704*67e74705SXin Li         os << " allocated by " << AllocOs.str();
1705*67e74705SXin Li     } else {
1706*67e74705SXin Li       os << "Memory";
1707*67e74705SXin Li       if (printAllocDeallocName(AllocOs, C, AllocExpr))
1708*67e74705SXin Li         os << " allocated by " << AllocOs.str();
1709*67e74705SXin Li 
1710*67e74705SXin Li       os << " should be deallocated by ";
1711*67e74705SXin Li         printExpectedDeallocName(os, RS->getAllocationFamily());
1712*67e74705SXin Li 
1713*67e74705SXin Li       if (printAllocDeallocName(DeallocOs, C, DeallocExpr))
1714*67e74705SXin Li         os << ", not " << DeallocOs.str();
1715*67e74705SXin Li     }
1716*67e74705SXin Li 
1717*67e74705SXin Li     auto R = llvm::make_unique<BugReport>(*BT_MismatchedDealloc, os.str(), N);
1718*67e74705SXin Li     R->markInteresting(Sym);
1719*67e74705SXin Li     R->addRange(Range);
1720*67e74705SXin Li     R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
1721*67e74705SXin Li     C.emitReport(std::move(R));
1722*67e74705SXin Li   }
1723*67e74705SXin Li }
1724*67e74705SXin Li 
ReportOffsetFree(CheckerContext & C,SVal ArgVal,SourceRange Range,const Expr * DeallocExpr,const Expr * AllocExpr) const1725*67e74705SXin Li void MallocChecker::ReportOffsetFree(CheckerContext &C, SVal ArgVal,
1726*67e74705SXin Li                                      SourceRange Range, const Expr *DeallocExpr,
1727*67e74705SXin Li                                      const Expr *AllocExpr) const {
1728*67e74705SXin Li 
1729*67e74705SXin Li 
1730*67e74705SXin Li   if (!ChecksEnabled[CK_MallocChecker] &&
1731*67e74705SXin Li       !ChecksEnabled[CK_NewDeleteChecker])
1732*67e74705SXin Li     return;
1733*67e74705SXin Li 
1734*67e74705SXin Li   Optional<MallocChecker::CheckKind> CheckKind =
1735*67e74705SXin Li       getCheckIfTracked(C, AllocExpr);
1736*67e74705SXin Li   if (!CheckKind.hasValue())
1737*67e74705SXin Li     return;
1738*67e74705SXin Li 
1739*67e74705SXin Li   ExplodedNode *N = C.generateErrorNode();
1740*67e74705SXin Li   if (!N)
1741*67e74705SXin Li     return;
1742*67e74705SXin Li 
1743*67e74705SXin Li   if (!BT_OffsetFree[*CheckKind])
1744*67e74705SXin Li     BT_OffsetFree[*CheckKind].reset(
1745*67e74705SXin Li         new BugType(CheckNames[*CheckKind], "Offset free", "Memory Error"));
1746*67e74705SXin Li 
1747*67e74705SXin Li   SmallString<100> buf;
1748*67e74705SXin Li   llvm::raw_svector_ostream os(buf);
1749*67e74705SXin Li   SmallString<20> AllocNameBuf;
1750*67e74705SXin Li   llvm::raw_svector_ostream AllocNameOs(AllocNameBuf);
1751*67e74705SXin Li 
1752*67e74705SXin Li   const MemRegion *MR = ArgVal.getAsRegion();
1753*67e74705SXin Li   assert(MR && "Only MemRegion based symbols can have offset free errors");
1754*67e74705SXin Li 
1755*67e74705SXin Li   RegionOffset Offset = MR->getAsOffset();
1756*67e74705SXin Li   assert((Offset.isValid() &&
1757*67e74705SXin Li           !Offset.hasSymbolicOffset() &&
1758*67e74705SXin Li           Offset.getOffset() != 0) &&
1759*67e74705SXin Li          "Only symbols with a valid offset can have offset free errors");
1760*67e74705SXin Li 
1761*67e74705SXin Li   int offsetBytes = Offset.getOffset() / C.getASTContext().getCharWidth();
1762*67e74705SXin Li 
1763*67e74705SXin Li   os << "Argument to ";
1764*67e74705SXin Li   if (!printAllocDeallocName(os, C, DeallocExpr))
1765*67e74705SXin Li     os << "deallocator";
1766*67e74705SXin Li   os << " is offset by "
1767*67e74705SXin Li      << offsetBytes
1768*67e74705SXin Li      << " "
1769*67e74705SXin Li      << ((abs(offsetBytes) > 1) ? "bytes" : "byte")
1770*67e74705SXin Li      << " from the start of ";
1771*67e74705SXin Li   if (AllocExpr && printAllocDeallocName(AllocNameOs, C, AllocExpr))
1772*67e74705SXin Li     os << "memory allocated by " << AllocNameOs.str();
1773*67e74705SXin Li   else
1774*67e74705SXin Li     os << "allocated memory";
1775*67e74705SXin Li 
1776*67e74705SXin Li   auto R = llvm::make_unique<BugReport>(*BT_OffsetFree[*CheckKind], os.str(), N);
1777*67e74705SXin Li   R->markInteresting(MR->getBaseRegion());
1778*67e74705SXin Li   R->addRange(Range);
1779*67e74705SXin Li   C.emitReport(std::move(R));
1780*67e74705SXin Li }
1781*67e74705SXin Li 
ReportUseAfterFree(CheckerContext & C,SourceRange Range,SymbolRef Sym) const1782*67e74705SXin Li void MallocChecker::ReportUseAfterFree(CheckerContext &C, SourceRange Range,
1783*67e74705SXin Li                                        SymbolRef Sym) const {
1784*67e74705SXin Li 
1785*67e74705SXin Li   if (!ChecksEnabled[CK_MallocChecker] &&
1786*67e74705SXin Li       !ChecksEnabled[CK_NewDeleteChecker])
1787*67e74705SXin Li     return;
1788*67e74705SXin Li 
1789*67e74705SXin Li   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
1790*67e74705SXin Li   if (!CheckKind.hasValue())
1791*67e74705SXin Li     return;
1792*67e74705SXin Li 
1793*67e74705SXin Li   if (ExplodedNode *N = C.generateErrorNode()) {
1794*67e74705SXin Li     if (!BT_UseFree[*CheckKind])
1795*67e74705SXin Li       BT_UseFree[*CheckKind].reset(new BugType(
1796*67e74705SXin Li           CheckNames[*CheckKind], "Use-after-free", "Memory Error"));
1797*67e74705SXin Li 
1798*67e74705SXin Li     auto R = llvm::make_unique<BugReport>(*BT_UseFree[*CheckKind],
1799*67e74705SXin Li                                          "Use of memory after it is freed", N);
1800*67e74705SXin Li 
1801*67e74705SXin Li     R->markInteresting(Sym);
1802*67e74705SXin Li     R->addRange(Range);
1803*67e74705SXin Li     R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
1804*67e74705SXin Li     C.emitReport(std::move(R));
1805*67e74705SXin Li   }
1806*67e74705SXin Li }
1807*67e74705SXin Li 
ReportDoubleFree(CheckerContext & C,SourceRange Range,bool Released,SymbolRef Sym,SymbolRef PrevSym) const1808*67e74705SXin Li void MallocChecker::ReportDoubleFree(CheckerContext &C, SourceRange Range,
1809*67e74705SXin Li                                      bool Released, SymbolRef Sym,
1810*67e74705SXin Li                                      SymbolRef PrevSym) const {
1811*67e74705SXin Li 
1812*67e74705SXin Li   if (!ChecksEnabled[CK_MallocChecker] &&
1813*67e74705SXin Li       !ChecksEnabled[CK_NewDeleteChecker])
1814*67e74705SXin Li     return;
1815*67e74705SXin Li 
1816*67e74705SXin Li   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
1817*67e74705SXin Li   if (!CheckKind.hasValue())
1818*67e74705SXin Li     return;
1819*67e74705SXin Li 
1820*67e74705SXin Li   if (ExplodedNode *N = C.generateErrorNode()) {
1821*67e74705SXin Li     if (!BT_DoubleFree[*CheckKind])
1822*67e74705SXin Li       BT_DoubleFree[*CheckKind].reset(
1823*67e74705SXin Li           new BugType(CheckNames[*CheckKind], "Double free", "Memory Error"));
1824*67e74705SXin Li 
1825*67e74705SXin Li     auto R = llvm::make_unique<BugReport>(
1826*67e74705SXin Li         *BT_DoubleFree[*CheckKind],
1827*67e74705SXin Li         (Released ? "Attempt to free released memory"
1828*67e74705SXin Li                   : "Attempt to free non-owned memory"),
1829*67e74705SXin Li         N);
1830*67e74705SXin Li     R->addRange(Range);
1831*67e74705SXin Li     R->markInteresting(Sym);
1832*67e74705SXin Li     if (PrevSym)
1833*67e74705SXin Li       R->markInteresting(PrevSym);
1834*67e74705SXin Li     R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
1835*67e74705SXin Li     C.emitReport(std::move(R));
1836*67e74705SXin Li   }
1837*67e74705SXin Li }
1838*67e74705SXin Li 
ReportDoubleDelete(CheckerContext & C,SymbolRef Sym) const1839*67e74705SXin Li void MallocChecker::ReportDoubleDelete(CheckerContext &C, SymbolRef Sym) const {
1840*67e74705SXin Li 
1841*67e74705SXin Li   if (!ChecksEnabled[CK_NewDeleteChecker])
1842*67e74705SXin Li     return;
1843*67e74705SXin Li 
1844*67e74705SXin Li   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
1845*67e74705SXin Li   if (!CheckKind.hasValue())
1846*67e74705SXin Li     return;
1847*67e74705SXin Li 
1848*67e74705SXin Li   if (ExplodedNode *N = C.generateErrorNode()) {
1849*67e74705SXin Li     if (!BT_DoubleDelete)
1850*67e74705SXin Li       BT_DoubleDelete.reset(new BugType(CheckNames[CK_NewDeleteChecker],
1851*67e74705SXin Li                                         "Double delete", "Memory Error"));
1852*67e74705SXin Li 
1853*67e74705SXin Li     auto R = llvm::make_unique<BugReport>(
1854*67e74705SXin Li         *BT_DoubleDelete, "Attempt to delete released memory", N);
1855*67e74705SXin Li 
1856*67e74705SXin Li     R->markInteresting(Sym);
1857*67e74705SXin Li     R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
1858*67e74705SXin Li     C.emitReport(std::move(R));
1859*67e74705SXin Li   }
1860*67e74705SXin Li }
1861*67e74705SXin Li 
ReportUseZeroAllocated(CheckerContext & C,SourceRange Range,SymbolRef Sym) const1862*67e74705SXin Li void MallocChecker::ReportUseZeroAllocated(CheckerContext &C,
1863*67e74705SXin Li                                            SourceRange Range,
1864*67e74705SXin Li                                            SymbolRef Sym) const {
1865*67e74705SXin Li 
1866*67e74705SXin Li   if (!ChecksEnabled[CK_MallocChecker] &&
1867*67e74705SXin Li       !ChecksEnabled[CK_NewDeleteChecker])
1868*67e74705SXin Li     return;
1869*67e74705SXin Li 
1870*67e74705SXin Li   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
1871*67e74705SXin Li 
1872*67e74705SXin Li   if (!CheckKind.hasValue())
1873*67e74705SXin Li     return;
1874*67e74705SXin Li 
1875*67e74705SXin Li   if (ExplodedNode *N = C.generateErrorNode()) {
1876*67e74705SXin Li     if (!BT_UseZerroAllocated[*CheckKind])
1877*67e74705SXin Li       BT_UseZerroAllocated[*CheckKind].reset(new BugType(
1878*67e74705SXin Li           CheckNames[*CheckKind], "Use of zero allocated", "Memory Error"));
1879*67e74705SXin Li 
1880*67e74705SXin Li     auto R = llvm::make_unique<BugReport>(*BT_UseZerroAllocated[*CheckKind],
1881*67e74705SXin Li                                          "Use of zero-allocated memory", N);
1882*67e74705SXin Li 
1883*67e74705SXin Li     R->addRange(Range);
1884*67e74705SXin Li     if (Sym) {
1885*67e74705SXin Li       R->markInteresting(Sym);
1886*67e74705SXin Li       R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
1887*67e74705SXin Li     }
1888*67e74705SXin Li     C.emitReport(std::move(R));
1889*67e74705SXin Li   }
1890*67e74705SXin Li }
1891*67e74705SXin Li 
ReallocMem(CheckerContext & C,const CallExpr * CE,bool FreesOnFail,ProgramStateRef State) const1892*67e74705SXin Li ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
1893*67e74705SXin Li                                           const CallExpr *CE,
1894*67e74705SXin Li                                           bool FreesOnFail,
1895*67e74705SXin Li                                           ProgramStateRef State) const {
1896*67e74705SXin Li   if (!State)
1897*67e74705SXin Li     return nullptr;
1898*67e74705SXin Li 
1899*67e74705SXin Li   if (CE->getNumArgs() < 2)
1900*67e74705SXin Li     return nullptr;
1901*67e74705SXin Li 
1902*67e74705SXin Li   const Expr *arg0Expr = CE->getArg(0);
1903*67e74705SXin Li   const LocationContext *LCtx = C.getLocationContext();
1904*67e74705SXin Li   SVal Arg0Val = State->getSVal(arg0Expr, LCtx);
1905*67e74705SXin Li   if (!Arg0Val.getAs<DefinedOrUnknownSVal>())
1906*67e74705SXin Li     return nullptr;
1907*67e74705SXin Li   DefinedOrUnknownSVal arg0Val = Arg0Val.castAs<DefinedOrUnknownSVal>();
1908*67e74705SXin Li 
1909*67e74705SXin Li   SValBuilder &svalBuilder = C.getSValBuilder();
1910*67e74705SXin Li 
1911*67e74705SXin Li   DefinedOrUnknownSVal PtrEQ =
1912*67e74705SXin Li     svalBuilder.evalEQ(State, arg0Val, svalBuilder.makeNull());
1913*67e74705SXin Li 
1914*67e74705SXin Li   // Get the size argument. If there is no size arg then give up.
1915*67e74705SXin Li   const Expr *Arg1 = CE->getArg(1);
1916*67e74705SXin Li   if (!Arg1)
1917*67e74705SXin Li     return nullptr;
1918*67e74705SXin Li 
1919*67e74705SXin Li   // Get the value of the size argument.
1920*67e74705SXin Li   SVal Arg1ValG = State->getSVal(Arg1, LCtx);
1921*67e74705SXin Li   if (!Arg1ValG.getAs<DefinedOrUnknownSVal>())
1922*67e74705SXin Li     return nullptr;
1923*67e74705SXin Li   DefinedOrUnknownSVal Arg1Val = Arg1ValG.castAs<DefinedOrUnknownSVal>();
1924*67e74705SXin Li 
1925*67e74705SXin Li   // Compare the size argument to 0.
1926*67e74705SXin Li   DefinedOrUnknownSVal SizeZero =
1927*67e74705SXin Li     svalBuilder.evalEQ(State, Arg1Val,
1928*67e74705SXin Li                        svalBuilder.makeIntValWithPtrWidth(0, false));
1929*67e74705SXin Li 
1930*67e74705SXin Li   ProgramStateRef StatePtrIsNull, StatePtrNotNull;
1931*67e74705SXin Li   std::tie(StatePtrIsNull, StatePtrNotNull) = State->assume(PtrEQ);
1932*67e74705SXin Li   ProgramStateRef StateSizeIsZero, StateSizeNotZero;
1933*67e74705SXin Li   std::tie(StateSizeIsZero, StateSizeNotZero) = State->assume(SizeZero);
1934*67e74705SXin Li   // We only assume exceptional states if they are definitely true; if the
1935*67e74705SXin Li   // state is under-constrained, assume regular realloc behavior.
1936*67e74705SXin Li   bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull;
1937*67e74705SXin Li   bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero;
1938*67e74705SXin Li 
1939*67e74705SXin Li   // If the ptr is NULL and the size is not 0, the call is equivalent to
1940*67e74705SXin Li   // malloc(size).
1941*67e74705SXin Li   if ( PrtIsNull && !SizeIsZero) {
1942*67e74705SXin Li     ProgramStateRef stateMalloc = MallocMemAux(C, CE, CE->getArg(1),
1943*67e74705SXin Li                                                UndefinedVal(), StatePtrIsNull);
1944*67e74705SXin Li     return stateMalloc;
1945*67e74705SXin Li   }
1946*67e74705SXin Li 
1947*67e74705SXin Li   if (PrtIsNull && SizeIsZero)
1948*67e74705SXin Li     return State;
1949*67e74705SXin Li 
1950*67e74705SXin Li   // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size).
1951*67e74705SXin Li   assert(!PrtIsNull);
1952*67e74705SXin Li   SymbolRef FromPtr = arg0Val.getAsSymbol();
1953*67e74705SXin Li   SVal RetVal = State->getSVal(CE, LCtx);
1954*67e74705SXin Li   SymbolRef ToPtr = RetVal.getAsSymbol();
1955*67e74705SXin Li   if (!FromPtr || !ToPtr)
1956*67e74705SXin Li     return nullptr;
1957*67e74705SXin Li 
1958*67e74705SXin Li   bool ReleasedAllocated = false;
1959*67e74705SXin Li 
1960*67e74705SXin Li   // If the size is 0, free the memory.
1961*67e74705SXin Li   if (SizeIsZero)
1962*67e74705SXin Li     if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero, 0,
1963*67e74705SXin Li                                                false, ReleasedAllocated)){
1964*67e74705SXin Li       // The semantics of the return value are:
1965*67e74705SXin Li       // If size was equal to 0, either NULL or a pointer suitable to be passed
1966*67e74705SXin Li       // to free() is returned. We just free the input pointer and do not add
1967*67e74705SXin Li       // any constrains on the output pointer.
1968*67e74705SXin Li       return stateFree;
1969*67e74705SXin Li     }
1970*67e74705SXin Li 
1971*67e74705SXin Li   // Default behavior.
1972*67e74705SXin Li   if (ProgramStateRef stateFree =
1973*67e74705SXin Li         FreeMemAux(C, CE, State, 0, false, ReleasedAllocated)) {
1974*67e74705SXin Li 
1975*67e74705SXin Li     ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
1976*67e74705SXin Li                                                 UnknownVal(), stateFree);
1977*67e74705SXin Li     if (!stateRealloc)
1978*67e74705SXin Li       return nullptr;
1979*67e74705SXin Li 
1980*67e74705SXin Li     ReallocPairKind Kind = RPToBeFreedAfterFailure;
1981*67e74705SXin Li     if (FreesOnFail)
1982*67e74705SXin Li       Kind = RPIsFreeOnFailure;
1983*67e74705SXin Li     else if (!ReleasedAllocated)
1984*67e74705SXin Li       Kind = RPDoNotTrackAfterFailure;
1985*67e74705SXin Li 
1986*67e74705SXin Li     // Record the info about the reallocated symbol so that we could properly
1987*67e74705SXin Li     // process failed reallocation.
1988*67e74705SXin Li     stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr,
1989*67e74705SXin Li                                                    ReallocPair(FromPtr, Kind));
1990*67e74705SXin Li     // The reallocated symbol should stay alive for as long as the new symbol.
1991*67e74705SXin Li     C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
1992*67e74705SXin Li     return stateRealloc;
1993*67e74705SXin Li   }
1994*67e74705SXin Li   return nullptr;
1995*67e74705SXin Li }
1996*67e74705SXin Li 
CallocMem(CheckerContext & C,const CallExpr * CE,ProgramStateRef State)1997*67e74705SXin Li ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE,
1998*67e74705SXin Li                                          ProgramStateRef State) {
1999*67e74705SXin Li   if (!State)
2000*67e74705SXin Li     return nullptr;
2001*67e74705SXin Li 
2002*67e74705SXin Li   if (CE->getNumArgs() < 2)
2003*67e74705SXin Li     return nullptr;
2004*67e74705SXin Li 
2005*67e74705SXin Li   SValBuilder &svalBuilder = C.getSValBuilder();
2006*67e74705SXin Li   const LocationContext *LCtx = C.getLocationContext();
2007*67e74705SXin Li   SVal count = State->getSVal(CE->getArg(0), LCtx);
2008*67e74705SXin Li   SVal elementSize = State->getSVal(CE->getArg(1), LCtx);
2009*67e74705SXin Li   SVal TotalSize = svalBuilder.evalBinOp(State, BO_Mul, count, elementSize,
2010*67e74705SXin Li                                         svalBuilder.getContext().getSizeType());
2011*67e74705SXin Li   SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
2012*67e74705SXin Li 
2013*67e74705SXin Li   return MallocMemAux(C, CE, TotalSize, zeroVal, State);
2014*67e74705SXin Li }
2015*67e74705SXin Li 
2016*67e74705SXin Li LeakInfo
getAllocationSite(const ExplodedNode * N,SymbolRef Sym,CheckerContext & C) const2017*67e74705SXin Li MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
2018*67e74705SXin Li                                  CheckerContext &C) const {
2019*67e74705SXin Li   const LocationContext *LeakContext = N->getLocationContext();
2020*67e74705SXin Li   // Walk the ExplodedGraph backwards and find the first node that referred to
2021*67e74705SXin Li   // the tracked symbol.
2022*67e74705SXin Li   const ExplodedNode *AllocNode = N;
2023*67e74705SXin Li   const MemRegion *ReferenceRegion = nullptr;
2024*67e74705SXin Li 
2025*67e74705SXin Li   while (N) {
2026*67e74705SXin Li     ProgramStateRef State = N->getState();
2027*67e74705SXin Li     if (!State->get<RegionState>(Sym))
2028*67e74705SXin Li       break;
2029*67e74705SXin Li 
2030*67e74705SXin Li     // Find the most recent expression bound to the symbol in the current
2031*67e74705SXin Li     // context.
2032*67e74705SXin Li       if (!ReferenceRegion) {
2033*67e74705SXin Li         if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) {
2034*67e74705SXin Li           SVal Val = State->getSVal(MR);
2035*67e74705SXin Li           if (Val.getAsLocSymbol() == Sym) {
2036*67e74705SXin Li             const VarRegion* VR = MR->getBaseRegion()->getAs<VarRegion>();
2037*67e74705SXin Li             // Do not show local variables belonging to a function other than
2038*67e74705SXin Li             // where the error is reported.
2039*67e74705SXin Li             if (!VR ||
2040*67e74705SXin Li                 (VR->getStackFrame() == LeakContext->getCurrentStackFrame()))
2041*67e74705SXin Li               ReferenceRegion = MR;
2042*67e74705SXin Li           }
2043*67e74705SXin Li         }
2044*67e74705SXin Li       }
2045*67e74705SXin Li 
2046*67e74705SXin Li     // Allocation node, is the last node in the current or parent context in
2047*67e74705SXin Li     // which the symbol was tracked.
2048*67e74705SXin Li     const LocationContext *NContext = N->getLocationContext();
2049*67e74705SXin Li     if (NContext == LeakContext ||
2050*67e74705SXin Li         NContext->isParentOf(LeakContext))
2051*67e74705SXin Li       AllocNode = N;
2052*67e74705SXin Li     N = N->pred_empty() ? nullptr : *(N->pred_begin());
2053*67e74705SXin Li   }
2054*67e74705SXin Li 
2055*67e74705SXin Li   return LeakInfo(AllocNode, ReferenceRegion);
2056*67e74705SXin Li }
2057*67e74705SXin Li 
reportLeak(SymbolRef Sym,ExplodedNode * N,CheckerContext & C) const2058*67e74705SXin Li void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
2059*67e74705SXin Li                                CheckerContext &C) const {
2060*67e74705SXin Li 
2061*67e74705SXin Li   if (!ChecksEnabled[CK_MallocChecker] &&
2062*67e74705SXin Li       !ChecksEnabled[CK_NewDeleteLeaksChecker])
2063*67e74705SXin Li     return;
2064*67e74705SXin Li 
2065*67e74705SXin Li   const RefState *RS = C.getState()->get<RegionState>(Sym);
2066*67e74705SXin Li   assert(RS && "cannot leak an untracked symbol");
2067*67e74705SXin Li   AllocationFamily Family = RS->getAllocationFamily();
2068*67e74705SXin Li 
2069*67e74705SXin Li   if (Family == AF_Alloca)
2070*67e74705SXin Li     return;
2071*67e74705SXin Li 
2072*67e74705SXin Li   Optional<MallocChecker::CheckKind>
2073*67e74705SXin Li       CheckKind = getCheckIfTracked(Family, true);
2074*67e74705SXin Li 
2075*67e74705SXin Li   if (!CheckKind.hasValue())
2076*67e74705SXin Li     return;
2077*67e74705SXin Li 
2078*67e74705SXin Li   assert(N);
2079*67e74705SXin Li   if (!BT_Leak[*CheckKind]) {
2080*67e74705SXin Li     BT_Leak[*CheckKind].reset(
2081*67e74705SXin Li         new BugType(CheckNames[*CheckKind], "Memory leak", "Memory Error"));
2082*67e74705SXin Li     // Leaks should not be reported if they are post-dominated by a sink:
2083*67e74705SXin Li     // (1) Sinks are higher importance bugs.
2084*67e74705SXin Li     // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
2085*67e74705SXin Li     //     with __noreturn functions such as assert() or exit(). We choose not
2086*67e74705SXin Li     //     to report leaks on such paths.
2087*67e74705SXin Li     BT_Leak[*CheckKind]->setSuppressOnSink(true);
2088*67e74705SXin Li   }
2089*67e74705SXin Li 
2090*67e74705SXin Li   // Most bug reports are cached at the location where they occurred.
2091*67e74705SXin Li   // With leaks, we want to unique them by the location where they were
2092*67e74705SXin Li   // allocated, and only report a single path.
2093*67e74705SXin Li   PathDiagnosticLocation LocUsedForUniqueing;
2094*67e74705SXin Li   const ExplodedNode *AllocNode = nullptr;
2095*67e74705SXin Li   const MemRegion *Region = nullptr;
2096*67e74705SXin Li   std::tie(AllocNode, Region) = getAllocationSite(N, Sym, C);
2097*67e74705SXin Li 
2098*67e74705SXin Li   ProgramPoint P = AllocNode->getLocation();
2099*67e74705SXin Li   const Stmt *AllocationStmt = nullptr;
2100*67e74705SXin Li   if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
2101*67e74705SXin Li     AllocationStmt = Exit->getCalleeContext()->getCallSite();
2102*67e74705SXin Li   else if (Optional<StmtPoint> SP = P.getAs<StmtPoint>())
2103*67e74705SXin Li     AllocationStmt = SP->getStmt();
2104*67e74705SXin Li   if (AllocationStmt)
2105*67e74705SXin Li     LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocationStmt,
2106*67e74705SXin Li                                               C.getSourceManager(),
2107*67e74705SXin Li                                               AllocNode->getLocationContext());
2108*67e74705SXin Li 
2109*67e74705SXin Li   SmallString<200> buf;
2110*67e74705SXin Li   llvm::raw_svector_ostream os(buf);
2111*67e74705SXin Li   if (Region && Region->canPrintPretty()) {
2112*67e74705SXin Li     os << "Potential leak of memory pointed to by ";
2113*67e74705SXin Li     Region->printPretty(os);
2114*67e74705SXin Li   } else {
2115*67e74705SXin Li     os << "Potential memory leak";
2116*67e74705SXin Li   }
2117*67e74705SXin Li 
2118*67e74705SXin Li   auto R = llvm::make_unique<BugReport>(
2119*67e74705SXin Li       *BT_Leak[*CheckKind], os.str(), N, LocUsedForUniqueing,
2120*67e74705SXin Li       AllocNode->getLocationContext()->getDecl());
2121*67e74705SXin Li   R->markInteresting(Sym);
2122*67e74705SXin Li   R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym, true));
2123*67e74705SXin Li   C.emitReport(std::move(R));
2124*67e74705SXin Li }
2125*67e74705SXin Li 
checkDeadSymbols(SymbolReaper & SymReaper,CheckerContext & C) const2126*67e74705SXin Li void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
2127*67e74705SXin Li                                      CheckerContext &C) const
2128*67e74705SXin Li {
2129*67e74705SXin Li   if (!SymReaper.hasDeadSymbols())
2130*67e74705SXin Li     return;
2131*67e74705SXin Li 
2132*67e74705SXin Li   ProgramStateRef state = C.getState();
2133*67e74705SXin Li   RegionStateTy RS = state->get<RegionState>();
2134*67e74705SXin Li   RegionStateTy::Factory &F = state->get_context<RegionState>();
2135*67e74705SXin Li 
2136*67e74705SXin Li   SmallVector<SymbolRef, 2> Errors;
2137*67e74705SXin Li   for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
2138*67e74705SXin Li     if (SymReaper.isDead(I->first)) {
2139*67e74705SXin Li       if (I->second.isAllocated() || I->second.isAllocatedOfSizeZero())
2140*67e74705SXin Li         Errors.push_back(I->first);
2141*67e74705SXin Li       // Remove the dead symbol from the map.
2142*67e74705SXin Li       RS = F.remove(RS, I->first);
2143*67e74705SXin Li 
2144*67e74705SXin Li     }
2145*67e74705SXin Li   }
2146*67e74705SXin Li 
2147*67e74705SXin Li   // Cleanup the Realloc Pairs Map.
2148*67e74705SXin Li   ReallocPairsTy RP = state->get<ReallocPairs>();
2149*67e74705SXin Li   for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
2150*67e74705SXin Li     if (SymReaper.isDead(I->first) ||
2151*67e74705SXin Li         SymReaper.isDead(I->second.ReallocatedSym)) {
2152*67e74705SXin Li       state = state->remove<ReallocPairs>(I->first);
2153*67e74705SXin Li     }
2154*67e74705SXin Li   }
2155*67e74705SXin Li 
2156*67e74705SXin Li   // Cleanup the FreeReturnValue Map.
2157*67e74705SXin Li   FreeReturnValueTy FR = state->get<FreeReturnValue>();
2158*67e74705SXin Li   for (FreeReturnValueTy::iterator I = FR.begin(), E = FR.end(); I != E; ++I) {
2159*67e74705SXin Li     if (SymReaper.isDead(I->first) ||
2160*67e74705SXin Li         SymReaper.isDead(I->second)) {
2161*67e74705SXin Li       state = state->remove<FreeReturnValue>(I->first);
2162*67e74705SXin Li     }
2163*67e74705SXin Li   }
2164*67e74705SXin Li 
2165*67e74705SXin Li   // Generate leak node.
2166*67e74705SXin Li   ExplodedNode *N = C.getPredecessor();
2167*67e74705SXin Li   if (!Errors.empty()) {
2168*67e74705SXin Li     static CheckerProgramPointTag Tag("MallocChecker", "DeadSymbolsLeak");
2169*67e74705SXin Li     N = C.generateNonFatalErrorNode(C.getState(), &Tag);
2170*67e74705SXin Li     if (N) {
2171*67e74705SXin Li       for (SmallVectorImpl<SymbolRef>::iterator
2172*67e74705SXin Li            I = Errors.begin(), E = Errors.end(); I != E; ++I) {
2173*67e74705SXin Li         reportLeak(*I, N, C);
2174*67e74705SXin Li       }
2175*67e74705SXin Li     }
2176*67e74705SXin Li   }
2177*67e74705SXin Li 
2178*67e74705SXin Li   C.addTransition(state->set<RegionState>(RS), N);
2179*67e74705SXin Li }
2180*67e74705SXin Li 
checkPreCall(const CallEvent & Call,CheckerContext & C) const2181*67e74705SXin Li void MallocChecker::checkPreCall(const CallEvent &Call,
2182*67e74705SXin Li                                  CheckerContext &C) const {
2183*67e74705SXin Li 
2184*67e74705SXin Li   if (const CXXDestructorCall *DC = dyn_cast<CXXDestructorCall>(&Call)) {
2185*67e74705SXin Li     SymbolRef Sym = DC->getCXXThisVal().getAsSymbol();
2186*67e74705SXin Li     if (!Sym || checkDoubleDelete(Sym, C))
2187*67e74705SXin Li       return;
2188*67e74705SXin Li   }
2189*67e74705SXin Li 
2190*67e74705SXin Li   // We will check for double free in the post visit.
2191*67e74705SXin Li   if (const AnyFunctionCall *FC = dyn_cast<AnyFunctionCall>(&Call)) {
2192*67e74705SXin Li     const FunctionDecl *FD = FC->getDecl();
2193*67e74705SXin Li     if (!FD)
2194*67e74705SXin Li       return;
2195*67e74705SXin Li 
2196*67e74705SXin Li     ASTContext &Ctx = C.getASTContext();
2197*67e74705SXin Li     if (ChecksEnabled[CK_MallocChecker] &&
2198*67e74705SXin Li         (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Free) ||
2199*67e74705SXin Li          isCMemFunction(FD, Ctx, AF_IfNameIndex,
2200*67e74705SXin Li                         MemoryOperationKind::MOK_Free)))
2201*67e74705SXin Li       return;
2202*67e74705SXin Li 
2203*67e74705SXin Li     if (ChecksEnabled[CK_NewDeleteChecker] &&
2204*67e74705SXin Li         isStandardNewDelete(FD, Ctx))
2205*67e74705SXin Li       return;
2206*67e74705SXin Li   }
2207*67e74705SXin Li 
2208*67e74705SXin Li   // Check if the callee of a method is deleted.
2209*67e74705SXin Li   if (const CXXInstanceCall *CC = dyn_cast<CXXInstanceCall>(&Call)) {
2210*67e74705SXin Li     SymbolRef Sym = CC->getCXXThisVal().getAsSymbol();
2211*67e74705SXin Li     if (!Sym || checkUseAfterFree(Sym, C, CC->getCXXThisExpr()))
2212*67e74705SXin Li       return;
2213*67e74705SXin Li   }
2214*67e74705SXin Li 
2215*67e74705SXin Li   // Check arguments for being used after free.
2216*67e74705SXin Li   for (unsigned I = 0, E = Call.getNumArgs(); I != E; ++I) {
2217*67e74705SXin Li     SVal ArgSVal = Call.getArgSVal(I);
2218*67e74705SXin Li     if (ArgSVal.getAs<Loc>()) {
2219*67e74705SXin Li       SymbolRef Sym = ArgSVal.getAsSymbol();
2220*67e74705SXin Li       if (!Sym)
2221*67e74705SXin Li         continue;
2222*67e74705SXin Li       if (checkUseAfterFree(Sym, C, Call.getArgExpr(I)))
2223*67e74705SXin Li         return;
2224*67e74705SXin Li     }
2225*67e74705SXin Li   }
2226*67e74705SXin Li }
2227*67e74705SXin Li 
checkPreStmt(const ReturnStmt * S,CheckerContext & C) const2228*67e74705SXin Li void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
2229*67e74705SXin Li   const Expr *E = S->getRetValue();
2230*67e74705SXin Li   if (!E)
2231*67e74705SXin Li     return;
2232*67e74705SXin Li 
2233*67e74705SXin Li   // Check if we are returning a symbol.
2234*67e74705SXin Li   ProgramStateRef State = C.getState();
2235*67e74705SXin Li   SVal RetVal = State->getSVal(E, C.getLocationContext());
2236*67e74705SXin Li   SymbolRef Sym = RetVal.getAsSymbol();
2237*67e74705SXin Li   if (!Sym)
2238*67e74705SXin Li     // If we are returning a field of the allocated struct or an array element,
2239*67e74705SXin Li     // the callee could still free the memory.
2240*67e74705SXin Li     // TODO: This logic should be a part of generic symbol escape callback.
2241*67e74705SXin Li     if (const MemRegion *MR = RetVal.getAsRegion())
2242*67e74705SXin Li       if (isa<FieldRegion>(MR) || isa<ElementRegion>(MR))
2243*67e74705SXin Li         if (const SymbolicRegion *BMR =
2244*67e74705SXin Li               dyn_cast<SymbolicRegion>(MR->getBaseRegion()))
2245*67e74705SXin Li           Sym = BMR->getSymbol();
2246*67e74705SXin Li 
2247*67e74705SXin Li   // Check if we are returning freed memory.
2248*67e74705SXin Li   if (Sym)
2249*67e74705SXin Li     checkUseAfterFree(Sym, C, E);
2250*67e74705SXin Li }
2251*67e74705SXin Li 
2252*67e74705SXin Li // TODO: Blocks should be either inlined or should call invalidate regions
2253*67e74705SXin Li // upon invocation. After that's in place, special casing here will not be
2254*67e74705SXin Li // needed.
checkPostStmt(const BlockExpr * BE,CheckerContext & C) const2255*67e74705SXin Li void MallocChecker::checkPostStmt(const BlockExpr *BE,
2256*67e74705SXin Li                                   CheckerContext &C) const {
2257*67e74705SXin Li 
2258*67e74705SXin Li   // Scan the BlockDecRefExprs for any object the retain count checker
2259*67e74705SXin Li   // may be tracking.
2260*67e74705SXin Li   if (!BE->getBlockDecl()->hasCaptures())
2261*67e74705SXin Li     return;
2262*67e74705SXin Li 
2263*67e74705SXin Li   ProgramStateRef state = C.getState();
2264*67e74705SXin Li   const BlockDataRegion *R =
2265*67e74705SXin Li     cast<BlockDataRegion>(state->getSVal(BE,
2266*67e74705SXin Li                                          C.getLocationContext()).getAsRegion());
2267*67e74705SXin Li 
2268*67e74705SXin Li   BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
2269*67e74705SXin Li                                             E = R->referenced_vars_end();
2270*67e74705SXin Li 
2271*67e74705SXin Li   if (I == E)
2272*67e74705SXin Li     return;
2273*67e74705SXin Li 
2274*67e74705SXin Li   SmallVector<const MemRegion*, 10> Regions;
2275*67e74705SXin Li   const LocationContext *LC = C.getLocationContext();
2276*67e74705SXin Li   MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager();
2277*67e74705SXin Li 
2278*67e74705SXin Li   for ( ; I != E; ++I) {
2279*67e74705SXin Li     const VarRegion *VR = I.getCapturedRegion();
2280*67e74705SXin Li     if (VR->getSuperRegion() == R) {
2281*67e74705SXin Li       VR = MemMgr.getVarRegion(VR->getDecl(), LC);
2282*67e74705SXin Li     }
2283*67e74705SXin Li     Regions.push_back(VR);
2284*67e74705SXin Li   }
2285*67e74705SXin Li 
2286*67e74705SXin Li   state =
2287*67e74705SXin Li     state->scanReachableSymbols<StopTrackingCallback>(Regions.data(),
2288*67e74705SXin Li                                     Regions.data() + Regions.size()).getState();
2289*67e74705SXin Li   C.addTransition(state);
2290*67e74705SXin Li }
2291*67e74705SXin Li 
isReleased(SymbolRef Sym,CheckerContext & C) const2292*67e74705SXin Li bool MallocChecker::isReleased(SymbolRef Sym, CheckerContext &C) const {
2293*67e74705SXin Li   assert(Sym);
2294*67e74705SXin Li   const RefState *RS = C.getState()->get<RegionState>(Sym);
2295*67e74705SXin Li   return (RS && RS->isReleased());
2296*67e74705SXin Li }
2297*67e74705SXin Li 
checkUseAfterFree(SymbolRef Sym,CheckerContext & C,const Stmt * S) const2298*67e74705SXin Li bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
2299*67e74705SXin Li                                       const Stmt *S) const {
2300*67e74705SXin Li 
2301*67e74705SXin Li   if (isReleased(Sym, C)) {
2302*67e74705SXin Li     ReportUseAfterFree(C, S->getSourceRange(), Sym);
2303*67e74705SXin Li     return true;
2304*67e74705SXin Li   }
2305*67e74705SXin Li 
2306*67e74705SXin Li   return false;
2307*67e74705SXin Li }
2308*67e74705SXin Li 
checkUseZeroAllocated(SymbolRef Sym,CheckerContext & C,const Stmt * S) const2309*67e74705SXin Li void MallocChecker::checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C,
2310*67e74705SXin Li                                           const Stmt *S) const {
2311*67e74705SXin Li   assert(Sym);
2312*67e74705SXin Li 
2313*67e74705SXin Li   if (const RefState *RS = C.getState()->get<RegionState>(Sym)) {
2314*67e74705SXin Li     if (RS->isAllocatedOfSizeZero())
2315*67e74705SXin Li       ReportUseZeroAllocated(C, RS->getStmt()->getSourceRange(), Sym);
2316*67e74705SXin Li   }
2317*67e74705SXin Li   else if (C.getState()->contains<ReallocSizeZeroSymbols>(Sym)) {
2318*67e74705SXin Li     ReportUseZeroAllocated(C, S->getSourceRange(), Sym);
2319*67e74705SXin Li   }
2320*67e74705SXin Li }
2321*67e74705SXin Li 
checkDoubleDelete(SymbolRef Sym,CheckerContext & C) const2322*67e74705SXin Li bool MallocChecker::checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const {
2323*67e74705SXin Li 
2324*67e74705SXin Li   if (isReleased(Sym, C)) {
2325*67e74705SXin Li     ReportDoubleDelete(C, Sym);
2326*67e74705SXin Li     return true;
2327*67e74705SXin Li   }
2328*67e74705SXin Li   return false;
2329*67e74705SXin Li }
2330*67e74705SXin Li 
2331*67e74705SXin Li // Check if the location is a freed symbolic region.
checkLocation(SVal l,bool isLoad,const Stmt * S,CheckerContext & C) const2332*67e74705SXin Li void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
2333*67e74705SXin Li                                   CheckerContext &C) const {
2334*67e74705SXin Li   SymbolRef Sym = l.getLocSymbolInBase();
2335*67e74705SXin Li   if (Sym) {
2336*67e74705SXin Li     checkUseAfterFree(Sym, C, S);
2337*67e74705SXin Li     checkUseZeroAllocated(Sym, C, S);
2338*67e74705SXin Li   }
2339*67e74705SXin Li }
2340*67e74705SXin Li 
2341*67e74705SXin Li // If a symbolic region is assumed to NULL (or another constant), stop tracking
2342*67e74705SXin Li // it - assuming that allocation failed on this path.
evalAssume(ProgramStateRef state,SVal Cond,bool Assumption) const2343*67e74705SXin Li ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state,
2344*67e74705SXin Li                                               SVal Cond,
2345*67e74705SXin Li                                               bool Assumption) const {
2346*67e74705SXin Li   RegionStateTy RS = state->get<RegionState>();
2347*67e74705SXin Li   for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
2348*67e74705SXin Li     // If the symbol is assumed to be NULL, remove it from consideration.
2349*67e74705SXin Li     ConstraintManager &CMgr = state->getConstraintManager();
2350*67e74705SXin Li     ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
2351*67e74705SXin Li     if (AllocFailed.isConstrainedTrue())
2352*67e74705SXin Li       state = state->remove<RegionState>(I.getKey());
2353*67e74705SXin Li   }
2354*67e74705SXin Li 
2355*67e74705SXin Li   // Realloc returns 0 when reallocation fails, which means that we should
2356*67e74705SXin Li   // restore the state of the pointer being reallocated.
2357*67e74705SXin Li   ReallocPairsTy RP = state->get<ReallocPairs>();
2358*67e74705SXin Li   for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
2359*67e74705SXin Li     // If the symbol is assumed to be NULL, remove it from consideration.
2360*67e74705SXin Li     ConstraintManager &CMgr = state->getConstraintManager();
2361*67e74705SXin Li     ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
2362*67e74705SXin Li     if (!AllocFailed.isConstrainedTrue())
2363*67e74705SXin Li       continue;
2364*67e74705SXin Li 
2365*67e74705SXin Li     SymbolRef ReallocSym = I.getData().ReallocatedSym;
2366*67e74705SXin Li     if (const RefState *RS = state->get<RegionState>(ReallocSym)) {
2367*67e74705SXin Li       if (RS->isReleased()) {
2368*67e74705SXin Li         if (I.getData().Kind == RPToBeFreedAfterFailure)
2369*67e74705SXin Li           state = state->set<RegionState>(ReallocSym,
2370*67e74705SXin Li               RefState::getAllocated(RS->getAllocationFamily(), RS->getStmt()));
2371*67e74705SXin Li         else if (I.getData().Kind == RPDoNotTrackAfterFailure)
2372*67e74705SXin Li           state = state->remove<RegionState>(ReallocSym);
2373*67e74705SXin Li         else
2374*67e74705SXin Li           assert(I.getData().Kind == RPIsFreeOnFailure);
2375*67e74705SXin Li       }
2376*67e74705SXin Li     }
2377*67e74705SXin Li     state = state->remove<ReallocPairs>(I.getKey());
2378*67e74705SXin Li   }
2379*67e74705SXin Li 
2380*67e74705SXin Li   return state;
2381*67e74705SXin Li }
2382*67e74705SXin Li 
mayFreeAnyEscapedMemoryOrIsModeledExplicitly(const CallEvent * Call,ProgramStateRef State,SymbolRef & EscapingSymbol) const2383*67e74705SXin Li bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
2384*67e74705SXin Li                                               const CallEvent *Call,
2385*67e74705SXin Li                                               ProgramStateRef State,
2386*67e74705SXin Li                                               SymbolRef &EscapingSymbol) const {
2387*67e74705SXin Li   assert(Call);
2388*67e74705SXin Li   EscapingSymbol = nullptr;
2389*67e74705SXin Li 
2390*67e74705SXin Li   // For now, assume that any C++ or block call can free memory.
2391*67e74705SXin Li   // TODO: If we want to be more optimistic here, we'll need to make sure that
2392*67e74705SXin Li   // regions escape to C++ containers. They seem to do that even now, but for
2393*67e74705SXin Li   // mysterious reasons.
2394*67e74705SXin Li   if (!(isa<SimpleFunctionCall>(Call) || isa<ObjCMethodCall>(Call)))
2395*67e74705SXin Li     return true;
2396*67e74705SXin Li 
2397*67e74705SXin Li   // Check Objective-C messages by selector name.
2398*67e74705SXin Li   if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) {
2399*67e74705SXin Li     // If it's not a framework call, or if it takes a callback, assume it
2400*67e74705SXin Li     // can free memory.
2401*67e74705SXin Li     if (!Call->isInSystemHeader() || Call->argumentsMayEscape())
2402*67e74705SXin Li       return true;
2403*67e74705SXin Li 
2404*67e74705SXin Li     // If it's a method we know about, handle it explicitly post-call.
2405*67e74705SXin Li     // This should happen before the "freeWhenDone" check below.
2406*67e74705SXin Li     if (isKnownDeallocObjCMethodName(*Msg))
2407*67e74705SXin Li       return false;
2408*67e74705SXin Li 
2409*67e74705SXin Li     // If there's a "freeWhenDone" parameter, but the method isn't one we know
2410*67e74705SXin Li     // about, we can't be sure that the object will use free() to deallocate the
2411*67e74705SXin Li     // memory, so we can't model it explicitly. The best we can do is use it to
2412*67e74705SXin Li     // decide whether the pointer escapes.
2413*67e74705SXin Li     if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(*Msg))
2414*67e74705SXin Li       return *FreeWhenDone;
2415*67e74705SXin Li 
2416*67e74705SXin Li     // If the first selector piece ends with "NoCopy", and there is no
2417*67e74705SXin Li     // "freeWhenDone" parameter set to zero, we know ownership is being
2418*67e74705SXin Li     // transferred. Again, though, we can't be sure that the object will use
2419*67e74705SXin Li     // free() to deallocate the memory, so we can't model it explicitly.
2420*67e74705SXin Li     StringRef FirstSlot = Msg->getSelector().getNameForSlot(0);
2421*67e74705SXin Li     if (FirstSlot.endswith("NoCopy"))
2422*67e74705SXin Li       return true;
2423*67e74705SXin Li 
2424*67e74705SXin Li     // If the first selector starts with addPointer, insertPointer,
2425*67e74705SXin Li     // or replacePointer, assume we are dealing with NSPointerArray or similar.
2426*67e74705SXin Li     // This is similar to C++ containers (vector); we still might want to check
2427*67e74705SXin Li     // that the pointers get freed by following the container itself.
2428*67e74705SXin Li     if (FirstSlot.startswith("addPointer") ||
2429*67e74705SXin Li         FirstSlot.startswith("insertPointer") ||
2430*67e74705SXin Li         FirstSlot.startswith("replacePointer") ||
2431*67e74705SXin Li         FirstSlot.equals("valueWithPointer")) {
2432*67e74705SXin Li       return true;
2433*67e74705SXin Li     }
2434*67e74705SXin Li 
2435*67e74705SXin Li     // We should escape receiver on call to 'init'. This is especially relevant
2436*67e74705SXin Li     // to the receiver, as the corresponding symbol is usually not referenced
2437*67e74705SXin Li     // after the call.
2438*67e74705SXin Li     if (Msg->getMethodFamily() == OMF_init) {
2439*67e74705SXin Li       EscapingSymbol = Msg->getReceiverSVal().getAsSymbol();
2440*67e74705SXin Li       return true;
2441*67e74705SXin Li     }
2442*67e74705SXin Li 
2443*67e74705SXin Li     // Otherwise, assume that the method does not free memory.
2444*67e74705SXin Li     // Most framework methods do not free memory.
2445*67e74705SXin Li     return false;
2446*67e74705SXin Li   }
2447*67e74705SXin Li 
2448*67e74705SXin Li   // At this point the only thing left to handle is straight function calls.
2449*67e74705SXin Li   const FunctionDecl *FD = cast<SimpleFunctionCall>(Call)->getDecl();
2450*67e74705SXin Li   if (!FD)
2451*67e74705SXin Li     return true;
2452*67e74705SXin Li 
2453*67e74705SXin Li   ASTContext &ASTC = State->getStateManager().getContext();
2454*67e74705SXin Li 
2455*67e74705SXin Li   // If it's one of the allocation functions we can reason about, we model
2456*67e74705SXin Li   // its behavior explicitly.
2457*67e74705SXin Li   if (isMemFunction(FD, ASTC))
2458*67e74705SXin Li     return false;
2459*67e74705SXin Li 
2460*67e74705SXin Li   // If it's not a system call, assume it frees memory.
2461*67e74705SXin Li   if (!Call->isInSystemHeader())
2462*67e74705SXin Li     return true;
2463*67e74705SXin Li 
2464*67e74705SXin Li   // White list the system functions whose arguments escape.
2465*67e74705SXin Li   const IdentifierInfo *II = FD->getIdentifier();
2466*67e74705SXin Li   if (!II)
2467*67e74705SXin Li     return true;
2468*67e74705SXin Li   StringRef FName = II->getName();
2469*67e74705SXin Li 
2470*67e74705SXin Li   // White list the 'XXXNoCopy' CoreFoundation functions.
2471*67e74705SXin Li   // We specifically check these before
2472*67e74705SXin Li   if (FName.endswith("NoCopy")) {
2473*67e74705SXin Li     // Look for the deallocator argument. We know that the memory ownership
2474*67e74705SXin Li     // is not transferred only if the deallocator argument is
2475*67e74705SXin Li     // 'kCFAllocatorNull'.
2476*67e74705SXin Li     for (unsigned i = 1; i < Call->getNumArgs(); ++i) {
2477*67e74705SXin Li       const Expr *ArgE = Call->getArgExpr(i)->IgnoreParenCasts();
2478*67e74705SXin Li       if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) {
2479*67e74705SXin Li         StringRef DeallocatorName = DE->getFoundDecl()->getName();
2480*67e74705SXin Li         if (DeallocatorName == "kCFAllocatorNull")
2481*67e74705SXin Li           return false;
2482*67e74705SXin Li       }
2483*67e74705SXin Li     }
2484*67e74705SXin Li     return true;
2485*67e74705SXin Li   }
2486*67e74705SXin Li 
2487*67e74705SXin Li   // Associating streams with malloced buffers. The pointer can escape if
2488*67e74705SXin Li   // 'closefn' is specified (and if that function does free memory),
2489*67e74705SXin Li   // but it will not if closefn is not specified.
2490*67e74705SXin Li   // Currently, we do not inspect the 'closefn' function (PR12101).
2491*67e74705SXin Li   if (FName == "funopen")
2492*67e74705SXin Li     if (Call->getNumArgs() >= 4 && Call->getArgSVal(4).isConstant(0))
2493*67e74705SXin Li       return false;
2494*67e74705SXin Li 
2495*67e74705SXin Li   // Do not warn on pointers passed to 'setbuf' when used with std streams,
2496*67e74705SXin Li   // these leaks might be intentional when setting the buffer for stdio.
2497*67e74705SXin Li   // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer
2498*67e74705SXin Li   if (FName == "setbuf" || FName =="setbuffer" ||
2499*67e74705SXin Li       FName == "setlinebuf" || FName == "setvbuf") {
2500*67e74705SXin Li     if (Call->getNumArgs() >= 1) {
2501*67e74705SXin Li       const Expr *ArgE = Call->getArgExpr(0)->IgnoreParenCasts();
2502*67e74705SXin Li       if (const DeclRefExpr *ArgDRE = dyn_cast<DeclRefExpr>(ArgE))
2503*67e74705SXin Li         if (const VarDecl *D = dyn_cast<VarDecl>(ArgDRE->getDecl()))
2504*67e74705SXin Li           if (D->getCanonicalDecl()->getName().find("std") != StringRef::npos)
2505*67e74705SXin Li             return true;
2506*67e74705SXin Li     }
2507*67e74705SXin Li   }
2508*67e74705SXin Li 
2509*67e74705SXin Li   // A bunch of other functions which either take ownership of a pointer or
2510*67e74705SXin Li   // wrap the result up in a struct or object, meaning it can be freed later.
2511*67e74705SXin Li   // (See RetainCountChecker.) Not all the parameters here are invalidated,
2512*67e74705SXin Li   // but the Malloc checker cannot differentiate between them. The right way
2513*67e74705SXin Li   // of doing this would be to implement a pointer escapes callback.
2514*67e74705SXin Li   if (FName == "CGBitmapContextCreate" ||
2515*67e74705SXin Li       FName == "CGBitmapContextCreateWithData" ||
2516*67e74705SXin Li       FName == "CVPixelBufferCreateWithBytes" ||
2517*67e74705SXin Li       FName == "CVPixelBufferCreateWithPlanarBytes" ||
2518*67e74705SXin Li       FName == "OSAtomicEnqueue") {
2519*67e74705SXin Li     return true;
2520*67e74705SXin Li   }
2521*67e74705SXin Li 
2522*67e74705SXin Li   if (FName == "postEvent" &&
2523*67e74705SXin Li       FD->getQualifiedNameAsString() == "QCoreApplication::postEvent") {
2524*67e74705SXin Li     return true;
2525*67e74705SXin Li   }
2526*67e74705SXin Li 
2527*67e74705SXin Li   if (FName == "postEvent" &&
2528*67e74705SXin Li       FD->getQualifiedNameAsString() == "QCoreApplication::postEvent") {
2529*67e74705SXin Li     return true;
2530*67e74705SXin Li   }
2531*67e74705SXin Li 
2532*67e74705SXin Li   // Handle cases where we know a buffer's /address/ can escape.
2533*67e74705SXin Li   // Note that the above checks handle some special cases where we know that
2534*67e74705SXin Li   // even though the address escapes, it's still our responsibility to free the
2535*67e74705SXin Li   // buffer.
2536*67e74705SXin Li   if (Call->argumentsMayEscape())
2537*67e74705SXin Li     return true;
2538*67e74705SXin Li 
2539*67e74705SXin Li   // Otherwise, assume that the function does not free memory.
2540*67e74705SXin Li   // Most system calls do not free the memory.
2541*67e74705SXin Li   return false;
2542*67e74705SXin Li }
2543*67e74705SXin Li 
retTrue(const RefState * RS)2544*67e74705SXin Li static bool retTrue(const RefState *RS) {
2545*67e74705SXin Li   return true;
2546*67e74705SXin Li }
2547*67e74705SXin Li 
checkIfNewOrNewArrayFamily(const RefState * RS)2548*67e74705SXin Li static bool checkIfNewOrNewArrayFamily(const RefState *RS) {
2549*67e74705SXin Li   return (RS->getAllocationFamily() == AF_CXXNewArray ||
2550*67e74705SXin Li           RS->getAllocationFamily() == AF_CXXNew);
2551*67e74705SXin Li }
2552*67e74705SXin Li 
checkPointerEscape(ProgramStateRef State,const InvalidatedSymbols & Escaped,const CallEvent * Call,PointerEscapeKind Kind) const2553*67e74705SXin Li ProgramStateRef MallocChecker::checkPointerEscape(ProgramStateRef State,
2554*67e74705SXin Li                                              const InvalidatedSymbols &Escaped,
2555*67e74705SXin Li                                              const CallEvent *Call,
2556*67e74705SXin Li                                              PointerEscapeKind Kind) const {
2557*67e74705SXin Li   return checkPointerEscapeAux(State, Escaped, Call, Kind, &retTrue);
2558*67e74705SXin Li }
2559*67e74705SXin Li 
checkConstPointerEscape(ProgramStateRef State,const InvalidatedSymbols & Escaped,const CallEvent * Call,PointerEscapeKind Kind) const2560*67e74705SXin Li ProgramStateRef MallocChecker::checkConstPointerEscape(ProgramStateRef State,
2561*67e74705SXin Li                                               const InvalidatedSymbols &Escaped,
2562*67e74705SXin Li                                               const CallEvent *Call,
2563*67e74705SXin Li                                               PointerEscapeKind Kind) const {
2564*67e74705SXin Li   return checkPointerEscapeAux(State, Escaped, Call, Kind,
2565*67e74705SXin Li                                &checkIfNewOrNewArrayFamily);
2566*67e74705SXin Li }
2567*67e74705SXin Li 
checkPointerEscapeAux(ProgramStateRef State,const InvalidatedSymbols & Escaped,const CallEvent * Call,PointerEscapeKind Kind,bool (* CheckRefState)(const RefState *)) const2568*67e74705SXin Li ProgramStateRef MallocChecker::checkPointerEscapeAux(ProgramStateRef State,
2569*67e74705SXin Li                                               const InvalidatedSymbols &Escaped,
2570*67e74705SXin Li                                               const CallEvent *Call,
2571*67e74705SXin Li                                               PointerEscapeKind Kind,
2572*67e74705SXin Li                                   bool(*CheckRefState)(const RefState*)) const {
2573*67e74705SXin Li   // If we know that the call does not free memory, or we want to process the
2574*67e74705SXin Li   // call later, keep tracking the top level arguments.
2575*67e74705SXin Li   SymbolRef EscapingSymbol = nullptr;
2576*67e74705SXin Li   if (Kind == PSK_DirectEscapeOnCall &&
2577*67e74705SXin Li       !mayFreeAnyEscapedMemoryOrIsModeledExplicitly(Call, State,
2578*67e74705SXin Li                                                     EscapingSymbol) &&
2579*67e74705SXin Li       !EscapingSymbol) {
2580*67e74705SXin Li     return State;
2581*67e74705SXin Li   }
2582*67e74705SXin Li 
2583*67e74705SXin Li   for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
2584*67e74705SXin Li        E = Escaped.end();
2585*67e74705SXin Li        I != E; ++I) {
2586*67e74705SXin Li     SymbolRef sym = *I;
2587*67e74705SXin Li 
2588*67e74705SXin Li     if (EscapingSymbol && EscapingSymbol != sym)
2589*67e74705SXin Li       continue;
2590*67e74705SXin Li 
2591*67e74705SXin Li     if (const RefState *RS = State->get<RegionState>(sym)) {
2592*67e74705SXin Li       if ((RS->isAllocated() || RS->isAllocatedOfSizeZero()) &&
2593*67e74705SXin Li           CheckRefState(RS)) {
2594*67e74705SXin Li         State = State->remove<RegionState>(sym);
2595*67e74705SXin Li         State = State->set<RegionState>(sym, RefState::getEscaped(RS));
2596*67e74705SXin Li       }
2597*67e74705SXin Li     }
2598*67e74705SXin Li   }
2599*67e74705SXin Li   return State;
2600*67e74705SXin Li }
2601*67e74705SXin Li 
findFailedReallocSymbol(ProgramStateRef currState,ProgramStateRef prevState)2602*67e74705SXin Li static SymbolRef findFailedReallocSymbol(ProgramStateRef currState,
2603*67e74705SXin Li                                          ProgramStateRef prevState) {
2604*67e74705SXin Li   ReallocPairsTy currMap = currState->get<ReallocPairs>();
2605*67e74705SXin Li   ReallocPairsTy prevMap = prevState->get<ReallocPairs>();
2606*67e74705SXin Li 
2607*67e74705SXin Li   for (ReallocPairsTy::iterator I = prevMap.begin(), E = prevMap.end();
2608*67e74705SXin Li        I != E; ++I) {
2609*67e74705SXin Li     SymbolRef sym = I.getKey();
2610*67e74705SXin Li     if (!currMap.lookup(sym))
2611*67e74705SXin Li       return sym;
2612*67e74705SXin Li   }
2613*67e74705SXin Li 
2614*67e74705SXin Li   return nullptr;
2615*67e74705SXin Li }
2616*67e74705SXin Li 
2617*67e74705SXin Li PathDiagnosticPiece *
VisitNode(const ExplodedNode * N,const ExplodedNode * PrevN,BugReporterContext & BRC,BugReport & BR)2618*67e74705SXin Li MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N,
2619*67e74705SXin Li                                            const ExplodedNode *PrevN,
2620*67e74705SXin Li                                            BugReporterContext &BRC,
2621*67e74705SXin Li                                            BugReport &BR) {
2622*67e74705SXin Li   ProgramStateRef state = N->getState();
2623*67e74705SXin Li   ProgramStateRef statePrev = PrevN->getState();
2624*67e74705SXin Li 
2625*67e74705SXin Li   const RefState *RS = state->get<RegionState>(Sym);
2626*67e74705SXin Li   const RefState *RSPrev = statePrev->get<RegionState>(Sym);
2627*67e74705SXin Li   if (!RS)
2628*67e74705SXin Li     return nullptr;
2629*67e74705SXin Li 
2630*67e74705SXin Li   const Stmt *S = nullptr;
2631*67e74705SXin Li   const char *Msg = nullptr;
2632*67e74705SXin Li   StackHintGeneratorForSymbol *StackHint = nullptr;
2633*67e74705SXin Li 
2634*67e74705SXin Li   // Retrieve the associated statement.
2635*67e74705SXin Li   ProgramPoint ProgLoc = N->getLocation();
2636*67e74705SXin Li   if (Optional<StmtPoint> SP = ProgLoc.getAs<StmtPoint>()) {
2637*67e74705SXin Li     S = SP->getStmt();
2638*67e74705SXin Li   } else if (Optional<CallExitEnd> Exit = ProgLoc.getAs<CallExitEnd>()) {
2639*67e74705SXin Li     S = Exit->getCalleeContext()->getCallSite();
2640*67e74705SXin Li   } else if (Optional<BlockEdge> Edge = ProgLoc.getAs<BlockEdge>()) {
2641*67e74705SXin Li     // If an assumption was made on a branch, it should be caught
2642*67e74705SXin Li     // here by looking at the state transition.
2643*67e74705SXin Li     S = Edge->getSrc()->getTerminator();
2644*67e74705SXin Li   }
2645*67e74705SXin Li 
2646*67e74705SXin Li   if (!S)
2647*67e74705SXin Li     return nullptr;
2648*67e74705SXin Li 
2649*67e74705SXin Li   // FIXME: We will eventually need to handle non-statement-based events
2650*67e74705SXin Li   // (__attribute__((cleanup))).
2651*67e74705SXin Li 
2652*67e74705SXin Li   // Find out if this is an interesting point and what is the kind.
2653*67e74705SXin Li   if (Mode == Normal) {
2654*67e74705SXin Li     if (isAllocated(RS, RSPrev, S)) {
2655*67e74705SXin Li       Msg = "Memory is allocated";
2656*67e74705SXin Li       StackHint = new StackHintGeneratorForSymbol(Sym,
2657*67e74705SXin Li                                                   "Returned allocated memory");
2658*67e74705SXin Li     } else if (isReleased(RS, RSPrev, S)) {
2659*67e74705SXin Li       Msg = "Memory is released";
2660*67e74705SXin Li       StackHint = new StackHintGeneratorForSymbol(Sym,
2661*67e74705SXin Li                                              "Returning; memory was released");
2662*67e74705SXin Li     } else if (isRelinquished(RS, RSPrev, S)) {
2663*67e74705SXin Li       Msg = "Memory ownership is transferred";
2664*67e74705SXin Li       StackHint = new StackHintGeneratorForSymbol(Sym, "");
2665*67e74705SXin Li     } else if (isReallocFailedCheck(RS, RSPrev, S)) {
2666*67e74705SXin Li       Mode = ReallocationFailed;
2667*67e74705SXin Li       Msg = "Reallocation failed";
2668*67e74705SXin Li       StackHint = new StackHintGeneratorForReallocationFailed(Sym,
2669*67e74705SXin Li                                                        "Reallocation failed");
2670*67e74705SXin Li 
2671*67e74705SXin Li       if (SymbolRef sym = findFailedReallocSymbol(state, statePrev)) {
2672*67e74705SXin Li         // Is it possible to fail two reallocs WITHOUT testing in between?
2673*67e74705SXin Li         assert((!FailedReallocSymbol || FailedReallocSymbol == sym) &&
2674*67e74705SXin Li           "We only support one failed realloc at a time.");
2675*67e74705SXin Li         BR.markInteresting(sym);
2676*67e74705SXin Li         FailedReallocSymbol = sym;
2677*67e74705SXin Li       }
2678*67e74705SXin Li     }
2679*67e74705SXin Li 
2680*67e74705SXin Li   // We are in a special mode if a reallocation failed later in the path.
2681*67e74705SXin Li   } else if (Mode == ReallocationFailed) {
2682*67e74705SXin Li     assert(FailedReallocSymbol && "No symbol to look for.");
2683*67e74705SXin Li 
2684*67e74705SXin Li     // Is this is the first appearance of the reallocated symbol?
2685*67e74705SXin Li     if (!statePrev->get<RegionState>(FailedReallocSymbol)) {
2686*67e74705SXin Li       // We're at the reallocation point.
2687*67e74705SXin Li       Msg = "Attempt to reallocate memory";
2688*67e74705SXin Li       StackHint = new StackHintGeneratorForSymbol(Sym,
2689*67e74705SXin Li                                                  "Returned reallocated memory");
2690*67e74705SXin Li       FailedReallocSymbol = nullptr;
2691*67e74705SXin Li       Mode = Normal;
2692*67e74705SXin Li     }
2693*67e74705SXin Li   }
2694*67e74705SXin Li 
2695*67e74705SXin Li   if (!Msg)
2696*67e74705SXin Li     return nullptr;
2697*67e74705SXin Li   assert(StackHint);
2698*67e74705SXin Li 
2699*67e74705SXin Li   // Generate the extra diagnostic.
2700*67e74705SXin Li   PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
2701*67e74705SXin Li                              N->getLocationContext());
2702*67e74705SXin Li   return new PathDiagnosticEventPiece(Pos, Msg, true, StackHint);
2703*67e74705SXin Li }
2704*67e74705SXin Li 
printState(raw_ostream & Out,ProgramStateRef State,const char * NL,const char * Sep) const2705*67e74705SXin Li void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State,
2706*67e74705SXin Li                                const char *NL, const char *Sep) const {
2707*67e74705SXin Li 
2708*67e74705SXin Li   RegionStateTy RS = State->get<RegionState>();
2709*67e74705SXin Li 
2710*67e74705SXin Li   if (!RS.isEmpty()) {
2711*67e74705SXin Li     Out << Sep << "MallocChecker :" << NL;
2712*67e74705SXin Li     for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
2713*67e74705SXin Li       const RefState *RefS = State->get<RegionState>(I.getKey());
2714*67e74705SXin Li       AllocationFamily Family = RefS->getAllocationFamily();
2715*67e74705SXin Li       Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
2716*67e74705SXin Li       if (!CheckKind.hasValue())
2717*67e74705SXin Li          CheckKind = getCheckIfTracked(Family, true);
2718*67e74705SXin Li 
2719*67e74705SXin Li       I.getKey()->dumpToStream(Out);
2720*67e74705SXin Li       Out << " : ";
2721*67e74705SXin Li       I.getData().dump(Out);
2722*67e74705SXin Li       if (CheckKind.hasValue())
2723*67e74705SXin Li         Out << " (" << CheckNames[*CheckKind].getName() << ")";
2724*67e74705SXin Li       Out << NL;
2725*67e74705SXin Li     }
2726*67e74705SXin Li   }
2727*67e74705SXin Li }
2728*67e74705SXin Li 
registerNewDeleteLeaksChecker(CheckerManager & mgr)2729*67e74705SXin Li void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) {
2730*67e74705SXin Li   registerCStringCheckerBasic(mgr);
2731*67e74705SXin Li   MallocChecker *checker = mgr.registerChecker<MallocChecker>();
2732*67e74705SXin Li   checker->IsOptimistic = mgr.getAnalyzerOptions().getBooleanOption(
2733*67e74705SXin Li       "Optimistic", false, checker);
2734*67e74705SXin Li   checker->ChecksEnabled[MallocChecker::CK_NewDeleteLeaksChecker] = true;
2735*67e74705SXin Li   checker->CheckNames[MallocChecker::CK_NewDeleteLeaksChecker] =
2736*67e74705SXin Li       mgr.getCurrentCheckName();
2737*67e74705SXin Li   // We currently treat NewDeleteLeaks checker as a subchecker of NewDelete
2738*67e74705SXin Li   // checker.
2739*67e74705SXin Li   if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker])
2740*67e74705SXin Li     checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker] = true;
2741*67e74705SXin Li }
2742*67e74705SXin Li 
2743*67e74705SXin Li #define REGISTER_CHECKER(name)                                                 \
2744*67e74705SXin Li   void ento::register##name(CheckerManager &mgr) {                             \
2745*67e74705SXin Li     registerCStringCheckerBasic(mgr);                                          \
2746*67e74705SXin Li     MallocChecker *checker = mgr.registerChecker<MallocChecker>();             \
2747*67e74705SXin Li     checker->IsOptimistic = mgr.getAnalyzerOptions().getBooleanOption(         \
2748*67e74705SXin Li         "Optimistic", false, checker);                                         \
2749*67e74705SXin Li     checker->ChecksEnabled[MallocChecker::CK_##name] = true;                   \
2750*67e74705SXin Li     checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \
2751*67e74705SXin Li   }
2752*67e74705SXin Li 
2753*67e74705SXin Li REGISTER_CHECKER(MallocChecker)
2754*67e74705SXin Li REGISTER_CHECKER(NewDeleteChecker)
2755*67e74705SXin Li REGISTER_CHECKER(MismatchedDeallocatorChecker)
2756