xref: /aosp_15_r20/external/llvm/lib/Analysis/MemoryBuiltins.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===------ MemoryBuiltins.cpp - Identify calls to memory builtins --------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This family of functions identifies calls to builtin functions that allocate
11*9880d681SAndroid Build Coastguard Worker // or free memory.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/MemoryBuiltins.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/TargetLibraryInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ValueTracking.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalVariable.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Intrinsics.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Metadata.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MathExtras.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/Local.h"
30*9880d681SAndroid Build Coastguard Worker using namespace llvm;
31*9880d681SAndroid Build Coastguard Worker 
32*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "memory-builtins"
33*9880d681SAndroid Build Coastguard Worker 
34*9880d681SAndroid Build Coastguard Worker enum AllocType : uint8_t {
35*9880d681SAndroid Build Coastguard Worker   OpNewLike          = 1<<0, // allocates; never returns null
36*9880d681SAndroid Build Coastguard Worker   MallocLike         = 1<<1 | OpNewLike, // allocates; may return null
37*9880d681SAndroid Build Coastguard Worker   CallocLike         = 1<<2, // allocates + bzero
38*9880d681SAndroid Build Coastguard Worker   ReallocLike        = 1<<3, // reallocates
39*9880d681SAndroid Build Coastguard Worker   StrDupLike         = 1<<4,
40*9880d681SAndroid Build Coastguard Worker   AllocLike          = MallocLike | CallocLike | StrDupLike,
41*9880d681SAndroid Build Coastguard Worker   AnyAlloc           = AllocLike | ReallocLike
42*9880d681SAndroid Build Coastguard Worker };
43*9880d681SAndroid Build Coastguard Worker 
44*9880d681SAndroid Build Coastguard Worker struct AllocFnsTy {
45*9880d681SAndroid Build Coastguard Worker   AllocType AllocTy;
46*9880d681SAndroid Build Coastguard Worker   unsigned NumParams;
47*9880d681SAndroid Build Coastguard Worker   // First and Second size parameters (or -1 if unused)
48*9880d681SAndroid Build Coastguard Worker   int FstParam, SndParam;
49*9880d681SAndroid Build Coastguard Worker };
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker // FIXME: certain users need more information. E.g., SimplifyLibCalls needs to
52*9880d681SAndroid Build Coastguard Worker // know which functions are nounwind, noalias, nocapture parameters, etc.
53*9880d681SAndroid Build Coastguard Worker static const std::pair<LibFunc::Func, AllocFnsTy> AllocationFnData[] = {
54*9880d681SAndroid Build Coastguard Worker   {LibFunc::malloc,              {MallocLike,  1, 0,  -1}},
55*9880d681SAndroid Build Coastguard Worker   {LibFunc::valloc,              {MallocLike,  1, 0,  -1}},
56*9880d681SAndroid Build Coastguard Worker   {LibFunc::Znwj,                {OpNewLike,   1, 0,  -1}}, // new(unsigned int)
57*9880d681SAndroid Build Coastguard Worker   {LibFunc::ZnwjRKSt9nothrow_t,  {MallocLike,  2, 0,  -1}}, // new(unsigned int, nothrow)
58*9880d681SAndroid Build Coastguard Worker   {LibFunc::Znwm,                {OpNewLike,   1, 0,  -1}}, // new(unsigned long)
59*9880d681SAndroid Build Coastguard Worker   {LibFunc::ZnwmRKSt9nothrow_t,  {MallocLike,  2, 0,  -1}}, // new(unsigned long, nothrow)
60*9880d681SAndroid Build Coastguard Worker   {LibFunc::Znaj,                {OpNewLike,   1, 0,  -1}}, // new[](unsigned int)
61*9880d681SAndroid Build Coastguard Worker   {LibFunc::ZnajRKSt9nothrow_t,  {MallocLike,  2, 0,  -1}}, // new[](unsigned int, nothrow)
62*9880d681SAndroid Build Coastguard Worker   {LibFunc::Znam,                {OpNewLike,   1, 0,  -1}}, // new[](unsigned long)
63*9880d681SAndroid Build Coastguard Worker   {LibFunc::ZnamRKSt9nothrow_t,  {MallocLike,  2, 0,  -1}}, // new[](unsigned long, nothrow)
64*9880d681SAndroid Build Coastguard Worker   {LibFunc::msvc_new_int,         {OpNewLike,   1, 0,  -1}}, // new(unsigned int)
65*9880d681SAndroid Build Coastguard Worker   {LibFunc::msvc_new_int_nothrow, {MallocLike,  2, 0,  -1}}, // new(unsigned int, nothrow)
66*9880d681SAndroid Build Coastguard Worker   {LibFunc::msvc_new_longlong,         {OpNewLike,   1, 0,  -1}}, // new(unsigned long long)
67*9880d681SAndroid Build Coastguard Worker   {LibFunc::msvc_new_longlong_nothrow, {MallocLike,  2, 0,  -1}}, // new(unsigned long long, nothrow)
68*9880d681SAndroid Build Coastguard Worker   {LibFunc::msvc_new_array_int,         {OpNewLike,   1, 0,  -1}}, // new[](unsigned int)
69*9880d681SAndroid Build Coastguard Worker   {LibFunc::msvc_new_array_int_nothrow, {MallocLike,  2, 0,  -1}}, // new[](unsigned int, nothrow)
70*9880d681SAndroid Build Coastguard Worker   {LibFunc::msvc_new_array_longlong,         {OpNewLike,   1, 0,  -1}}, // new[](unsigned long long)
71*9880d681SAndroid Build Coastguard Worker   {LibFunc::msvc_new_array_longlong_nothrow, {MallocLike,  2, 0,  -1}}, // new[](unsigned long long, nothrow)
72*9880d681SAndroid Build Coastguard Worker   {LibFunc::calloc,              {CallocLike,  2, 0,   1}},
73*9880d681SAndroid Build Coastguard Worker   {LibFunc::realloc,             {ReallocLike, 2, 1,  -1}},
74*9880d681SAndroid Build Coastguard Worker   {LibFunc::reallocf,            {ReallocLike, 2, 1,  -1}},
75*9880d681SAndroid Build Coastguard Worker   {LibFunc::strdup,              {StrDupLike,  1, -1, -1}},
76*9880d681SAndroid Build Coastguard Worker   {LibFunc::strndup,             {StrDupLike,  2, 1,  -1}}
77*9880d681SAndroid Build Coastguard Worker   // TODO: Handle "int posix_memalign(void **, size_t, size_t)"
78*9880d681SAndroid Build Coastguard Worker };
79*9880d681SAndroid Build Coastguard Worker 
80*9880d681SAndroid Build Coastguard Worker 
getCalledFunction(const Value * V,bool LookThroughBitCast)81*9880d681SAndroid Build Coastguard Worker static Function *getCalledFunction(const Value *V, bool LookThroughBitCast) {
82*9880d681SAndroid Build Coastguard Worker   if (LookThroughBitCast)
83*9880d681SAndroid Build Coastguard Worker     V = V->stripPointerCasts();
84*9880d681SAndroid Build Coastguard Worker 
85*9880d681SAndroid Build Coastguard Worker   CallSite CS(const_cast<Value*>(V));
86*9880d681SAndroid Build Coastguard Worker   if (!CS.getInstruction())
87*9880d681SAndroid Build Coastguard Worker     return nullptr;
88*9880d681SAndroid Build Coastguard Worker 
89*9880d681SAndroid Build Coastguard Worker   if (CS.isNoBuiltin())
90*9880d681SAndroid Build Coastguard Worker     return nullptr;
91*9880d681SAndroid Build Coastguard Worker 
92*9880d681SAndroid Build Coastguard Worker   Function *Callee = CS.getCalledFunction();
93*9880d681SAndroid Build Coastguard Worker   if (!Callee || !Callee->isDeclaration())
94*9880d681SAndroid Build Coastguard Worker     return nullptr;
95*9880d681SAndroid Build Coastguard Worker   return Callee;
96*9880d681SAndroid Build Coastguard Worker }
97*9880d681SAndroid Build Coastguard Worker 
98*9880d681SAndroid Build Coastguard Worker /// Returns the allocation data for the given value if it's either a call to a
99*9880d681SAndroid Build Coastguard Worker /// known allocation function, or a call to a function with the allocsize
100*9880d681SAndroid Build Coastguard Worker /// attribute.
getAllocationData(const Value * V,AllocType AllocTy,const TargetLibraryInfo * TLI,bool LookThroughBitCast=false)101*9880d681SAndroid Build Coastguard Worker static Optional<AllocFnsTy> getAllocationData(const Value *V, AllocType AllocTy,
102*9880d681SAndroid Build Coastguard Worker                                               const TargetLibraryInfo *TLI,
103*9880d681SAndroid Build Coastguard Worker                                               bool LookThroughBitCast = false) {
104*9880d681SAndroid Build Coastguard Worker   // Skip intrinsics
105*9880d681SAndroid Build Coastguard Worker   if (isa<IntrinsicInst>(V))
106*9880d681SAndroid Build Coastguard Worker     return None;
107*9880d681SAndroid Build Coastguard Worker 
108*9880d681SAndroid Build Coastguard Worker   const Function *Callee = getCalledFunction(V, LookThroughBitCast);
109*9880d681SAndroid Build Coastguard Worker   if (!Callee)
110*9880d681SAndroid Build Coastguard Worker     return None;
111*9880d681SAndroid Build Coastguard Worker 
112*9880d681SAndroid Build Coastguard Worker   // If it has allocsize, we can skip checking if it's a known function.
113*9880d681SAndroid Build Coastguard Worker   //
114*9880d681SAndroid Build Coastguard Worker   // MallocLike is chosen here because allocsize makes no guarantees about the
115*9880d681SAndroid Build Coastguard Worker   // nullness of the result of the function, nor does it deal with strings, nor
116*9880d681SAndroid Build Coastguard Worker   // does it require that the memory returned is zeroed out.
117*9880d681SAndroid Build Coastguard Worker   LLVM_CONSTEXPR auto AllocSizeAllocTy = MallocLike;
118*9880d681SAndroid Build Coastguard Worker   if ((AllocTy & AllocSizeAllocTy) == AllocSizeAllocTy &&
119*9880d681SAndroid Build Coastguard Worker       Callee->hasFnAttribute(Attribute::AllocSize)) {
120*9880d681SAndroid Build Coastguard Worker     Attribute Attr = Callee->getFnAttribute(Attribute::AllocSize);
121*9880d681SAndroid Build Coastguard Worker     std::pair<unsigned, Optional<unsigned>> Args = Attr.getAllocSizeArgs();
122*9880d681SAndroid Build Coastguard Worker 
123*9880d681SAndroid Build Coastguard Worker     AllocFnsTy Result;
124*9880d681SAndroid Build Coastguard Worker     Result.AllocTy = AllocSizeAllocTy;
125*9880d681SAndroid Build Coastguard Worker     Result.NumParams = Callee->getNumOperands();
126*9880d681SAndroid Build Coastguard Worker     Result.FstParam = Args.first;
127*9880d681SAndroid Build Coastguard Worker     Result.SndParam = Args.second.getValueOr(-1);
128*9880d681SAndroid Build Coastguard Worker     return Result;
129*9880d681SAndroid Build Coastguard Worker   }
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker   // Make sure that the function is available.
132*9880d681SAndroid Build Coastguard Worker   StringRef FnName = Callee->getName();
133*9880d681SAndroid Build Coastguard Worker   LibFunc::Func TLIFn;
134*9880d681SAndroid Build Coastguard Worker   if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn))
135*9880d681SAndroid Build Coastguard Worker     return None;
136*9880d681SAndroid Build Coastguard Worker 
137*9880d681SAndroid Build Coastguard Worker   const auto *Iter =
138*9880d681SAndroid Build Coastguard Worker       std::find_if(std::begin(AllocationFnData), std::end(AllocationFnData),
139*9880d681SAndroid Build Coastguard Worker                    [TLIFn](const std::pair<LibFunc::Func, AllocFnsTy> &P) {
140*9880d681SAndroid Build Coastguard Worker                      return P.first == TLIFn;
141*9880d681SAndroid Build Coastguard Worker                    });
142*9880d681SAndroid Build Coastguard Worker 
143*9880d681SAndroid Build Coastguard Worker   if (Iter == std::end(AllocationFnData))
144*9880d681SAndroid Build Coastguard Worker     return None;
145*9880d681SAndroid Build Coastguard Worker 
146*9880d681SAndroid Build Coastguard Worker   const AllocFnsTy *FnData = &Iter->second;
147*9880d681SAndroid Build Coastguard Worker   if ((FnData->AllocTy & AllocTy) != FnData->AllocTy)
148*9880d681SAndroid Build Coastguard Worker     return None;
149*9880d681SAndroid Build Coastguard Worker 
150*9880d681SAndroid Build Coastguard Worker   // Check function prototype.
151*9880d681SAndroid Build Coastguard Worker   int FstParam = FnData->FstParam;
152*9880d681SAndroid Build Coastguard Worker   int SndParam = FnData->SndParam;
153*9880d681SAndroid Build Coastguard Worker   FunctionType *FTy = Callee->getFunctionType();
154*9880d681SAndroid Build Coastguard Worker 
155*9880d681SAndroid Build Coastguard Worker   if (FTy->getReturnType() == Type::getInt8PtrTy(FTy->getContext()) &&
156*9880d681SAndroid Build Coastguard Worker       FTy->getNumParams() == FnData->NumParams &&
157*9880d681SAndroid Build Coastguard Worker       (FstParam < 0 ||
158*9880d681SAndroid Build Coastguard Worker        (FTy->getParamType(FstParam)->isIntegerTy(32) ||
159*9880d681SAndroid Build Coastguard Worker         FTy->getParamType(FstParam)->isIntegerTy(64))) &&
160*9880d681SAndroid Build Coastguard Worker       (SndParam < 0 ||
161*9880d681SAndroid Build Coastguard Worker        FTy->getParamType(SndParam)->isIntegerTy(32) ||
162*9880d681SAndroid Build Coastguard Worker        FTy->getParamType(SndParam)->isIntegerTy(64)))
163*9880d681SAndroid Build Coastguard Worker     return *FnData;
164*9880d681SAndroid Build Coastguard Worker   return None;
165*9880d681SAndroid Build Coastguard Worker }
166*9880d681SAndroid Build Coastguard Worker 
hasNoAliasAttr(const Value * V,bool LookThroughBitCast)167*9880d681SAndroid Build Coastguard Worker static bool hasNoAliasAttr(const Value *V, bool LookThroughBitCast) {
168*9880d681SAndroid Build Coastguard Worker   ImmutableCallSite CS(LookThroughBitCast ? V->stripPointerCasts() : V);
169*9880d681SAndroid Build Coastguard Worker   return CS && CS.paramHasAttr(AttributeSet::ReturnIndex, Attribute::NoAlias);
170*9880d681SAndroid Build Coastguard Worker }
171*9880d681SAndroid Build Coastguard Worker 
172*9880d681SAndroid Build Coastguard Worker 
173*9880d681SAndroid Build Coastguard Worker /// \brief Tests if a value is a call or invoke to a library function that
174*9880d681SAndroid Build Coastguard Worker /// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
175*9880d681SAndroid Build Coastguard Worker /// like).
isAllocationFn(const Value * V,const TargetLibraryInfo * TLI,bool LookThroughBitCast)176*9880d681SAndroid Build Coastguard Worker bool llvm::isAllocationFn(const Value *V, const TargetLibraryInfo *TLI,
177*9880d681SAndroid Build Coastguard Worker                           bool LookThroughBitCast) {
178*9880d681SAndroid Build Coastguard Worker   return getAllocationData(V, AnyAlloc, TLI, LookThroughBitCast).hasValue();
179*9880d681SAndroid Build Coastguard Worker }
180*9880d681SAndroid Build Coastguard Worker 
181*9880d681SAndroid Build Coastguard Worker /// \brief Tests if a value is a call or invoke to a function that returns a
182*9880d681SAndroid Build Coastguard Worker /// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
isNoAliasFn(const Value * V,const TargetLibraryInfo * TLI,bool LookThroughBitCast)183*9880d681SAndroid Build Coastguard Worker bool llvm::isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI,
184*9880d681SAndroid Build Coastguard Worker                        bool LookThroughBitCast) {
185*9880d681SAndroid Build Coastguard Worker   // it's safe to consider realloc as noalias since accessing the original
186*9880d681SAndroid Build Coastguard Worker   // pointer is undefined behavior
187*9880d681SAndroid Build Coastguard Worker   return isAllocationFn(V, TLI, LookThroughBitCast) ||
188*9880d681SAndroid Build Coastguard Worker          hasNoAliasAttr(V, LookThroughBitCast);
189*9880d681SAndroid Build Coastguard Worker }
190*9880d681SAndroid Build Coastguard Worker 
191*9880d681SAndroid Build Coastguard Worker /// \brief Tests if a value is a call or invoke to a library function that
192*9880d681SAndroid Build Coastguard Worker /// allocates uninitialized memory (such as malloc).
isMallocLikeFn(const Value * V,const TargetLibraryInfo * TLI,bool LookThroughBitCast)193*9880d681SAndroid Build Coastguard Worker bool llvm::isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
194*9880d681SAndroid Build Coastguard Worker                           bool LookThroughBitCast) {
195*9880d681SAndroid Build Coastguard Worker   return getAllocationData(V, MallocLike, TLI, LookThroughBitCast).hasValue();
196*9880d681SAndroid Build Coastguard Worker }
197*9880d681SAndroid Build Coastguard Worker 
198*9880d681SAndroid Build Coastguard Worker /// \brief Tests if a value is a call or invoke to a library function that
199*9880d681SAndroid Build Coastguard Worker /// allocates zero-filled memory (such as calloc).
isCallocLikeFn(const Value * V,const TargetLibraryInfo * TLI,bool LookThroughBitCast)200*9880d681SAndroid Build Coastguard Worker bool llvm::isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
201*9880d681SAndroid Build Coastguard Worker                           bool LookThroughBitCast) {
202*9880d681SAndroid Build Coastguard Worker   return getAllocationData(V, CallocLike, TLI, LookThroughBitCast).hasValue();
203*9880d681SAndroid Build Coastguard Worker }
204*9880d681SAndroid Build Coastguard Worker 
205*9880d681SAndroid Build Coastguard Worker /// \brief Tests if a value is a call or invoke to a library function that
206*9880d681SAndroid Build Coastguard Worker /// allocates memory (either malloc, calloc, or strdup like).
isAllocLikeFn(const Value * V,const TargetLibraryInfo * TLI,bool LookThroughBitCast)207*9880d681SAndroid Build Coastguard Worker bool llvm::isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
208*9880d681SAndroid Build Coastguard Worker                          bool LookThroughBitCast) {
209*9880d681SAndroid Build Coastguard Worker   return getAllocationData(V, AllocLike, TLI, LookThroughBitCast).hasValue();
210*9880d681SAndroid Build Coastguard Worker }
211*9880d681SAndroid Build Coastguard Worker 
212*9880d681SAndroid Build Coastguard Worker /// extractMallocCall - Returns the corresponding CallInst if the instruction
213*9880d681SAndroid Build Coastguard Worker /// is a malloc call.  Since CallInst::CreateMalloc() only creates calls, we
214*9880d681SAndroid Build Coastguard Worker /// ignore InvokeInst here.
extractMallocCall(const Value * I,const TargetLibraryInfo * TLI)215*9880d681SAndroid Build Coastguard Worker const CallInst *llvm::extractMallocCall(const Value *I,
216*9880d681SAndroid Build Coastguard Worker                                         const TargetLibraryInfo *TLI) {
217*9880d681SAndroid Build Coastguard Worker   return isMallocLikeFn(I, TLI) ? dyn_cast<CallInst>(I) : nullptr;
218*9880d681SAndroid Build Coastguard Worker }
219*9880d681SAndroid Build Coastguard Worker 
computeArraySize(const CallInst * CI,const DataLayout & DL,const TargetLibraryInfo * TLI,bool LookThroughSExt=false)220*9880d681SAndroid Build Coastguard Worker static Value *computeArraySize(const CallInst *CI, const DataLayout &DL,
221*9880d681SAndroid Build Coastguard Worker                                const TargetLibraryInfo *TLI,
222*9880d681SAndroid Build Coastguard Worker                                bool LookThroughSExt = false) {
223*9880d681SAndroid Build Coastguard Worker   if (!CI)
224*9880d681SAndroid Build Coastguard Worker     return nullptr;
225*9880d681SAndroid Build Coastguard Worker 
226*9880d681SAndroid Build Coastguard Worker   // The size of the malloc's result type must be known to determine array size.
227*9880d681SAndroid Build Coastguard Worker   Type *T = getMallocAllocatedType(CI, TLI);
228*9880d681SAndroid Build Coastguard Worker   if (!T || !T->isSized())
229*9880d681SAndroid Build Coastguard Worker     return nullptr;
230*9880d681SAndroid Build Coastguard Worker 
231*9880d681SAndroid Build Coastguard Worker   unsigned ElementSize = DL.getTypeAllocSize(T);
232*9880d681SAndroid Build Coastguard Worker   if (StructType *ST = dyn_cast<StructType>(T))
233*9880d681SAndroid Build Coastguard Worker     ElementSize = DL.getStructLayout(ST)->getSizeInBytes();
234*9880d681SAndroid Build Coastguard Worker 
235*9880d681SAndroid Build Coastguard Worker   // If malloc call's arg can be determined to be a multiple of ElementSize,
236*9880d681SAndroid Build Coastguard Worker   // return the multiple.  Otherwise, return NULL.
237*9880d681SAndroid Build Coastguard Worker   Value *MallocArg = CI->getArgOperand(0);
238*9880d681SAndroid Build Coastguard Worker   Value *Multiple = nullptr;
239*9880d681SAndroid Build Coastguard Worker   if (ComputeMultiple(MallocArg, ElementSize, Multiple, LookThroughSExt))
240*9880d681SAndroid Build Coastguard Worker     return Multiple;
241*9880d681SAndroid Build Coastguard Worker 
242*9880d681SAndroid Build Coastguard Worker   return nullptr;
243*9880d681SAndroid Build Coastguard Worker }
244*9880d681SAndroid Build Coastguard Worker 
245*9880d681SAndroid Build Coastguard Worker /// getMallocType - Returns the PointerType resulting from the malloc call.
246*9880d681SAndroid Build Coastguard Worker /// The PointerType depends on the number of bitcast uses of the malloc call:
247*9880d681SAndroid Build Coastguard Worker ///   0: PointerType is the calls' return type.
248*9880d681SAndroid Build Coastguard Worker ///   1: PointerType is the bitcast's result type.
249*9880d681SAndroid Build Coastguard Worker ///  >1: Unique PointerType cannot be determined, return NULL.
getMallocType(const CallInst * CI,const TargetLibraryInfo * TLI)250*9880d681SAndroid Build Coastguard Worker PointerType *llvm::getMallocType(const CallInst *CI,
251*9880d681SAndroid Build Coastguard Worker                                  const TargetLibraryInfo *TLI) {
252*9880d681SAndroid Build Coastguard Worker   assert(isMallocLikeFn(CI, TLI) && "getMallocType and not malloc call");
253*9880d681SAndroid Build Coastguard Worker 
254*9880d681SAndroid Build Coastguard Worker   PointerType *MallocType = nullptr;
255*9880d681SAndroid Build Coastguard Worker   unsigned NumOfBitCastUses = 0;
256*9880d681SAndroid Build Coastguard Worker 
257*9880d681SAndroid Build Coastguard Worker   // Determine if CallInst has a bitcast use.
258*9880d681SAndroid Build Coastguard Worker   for (Value::const_user_iterator UI = CI->user_begin(), E = CI->user_end();
259*9880d681SAndroid Build Coastguard Worker        UI != E;)
260*9880d681SAndroid Build Coastguard Worker     if (const BitCastInst *BCI = dyn_cast<BitCastInst>(*UI++)) {
261*9880d681SAndroid Build Coastguard Worker       MallocType = cast<PointerType>(BCI->getDestTy());
262*9880d681SAndroid Build Coastguard Worker       NumOfBitCastUses++;
263*9880d681SAndroid Build Coastguard Worker     }
264*9880d681SAndroid Build Coastguard Worker 
265*9880d681SAndroid Build Coastguard Worker   // Malloc call has 1 bitcast use, so type is the bitcast's destination type.
266*9880d681SAndroid Build Coastguard Worker   if (NumOfBitCastUses == 1)
267*9880d681SAndroid Build Coastguard Worker     return MallocType;
268*9880d681SAndroid Build Coastguard Worker 
269*9880d681SAndroid Build Coastguard Worker   // Malloc call was not bitcast, so type is the malloc function's return type.
270*9880d681SAndroid Build Coastguard Worker   if (NumOfBitCastUses == 0)
271*9880d681SAndroid Build Coastguard Worker     return cast<PointerType>(CI->getType());
272*9880d681SAndroid Build Coastguard Worker 
273*9880d681SAndroid Build Coastguard Worker   // Type could not be determined.
274*9880d681SAndroid Build Coastguard Worker   return nullptr;
275*9880d681SAndroid Build Coastguard Worker }
276*9880d681SAndroid Build Coastguard Worker 
277*9880d681SAndroid Build Coastguard Worker /// getMallocAllocatedType - Returns the Type allocated by malloc call.
278*9880d681SAndroid Build Coastguard Worker /// The Type depends on the number of bitcast uses of the malloc call:
279*9880d681SAndroid Build Coastguard Worker ///   0: PointerType is the malloc calls' return type.
280*9880d681SAndroid Build Coastguard Worker ///   1: PointerType is the bitcast's result type.
281*9880d681SAndroid Build Coastguard Worker ///  >1: Unique PointerType cannot be determined, return NULL.
getMallocAllocatedType(const CallInst * CI,const TargetLibraryInfo * TLI)282*9880d681SAndroid Build Coastguard Worker Type *llvm::getMallocAllocatedType(const CallInst *CI,
283*9880d681SAndroid Build Coastguard Worker                                    const TargetLibraryInfo *TLI) {
284*9880d681SAndroid Build Coastguard Worker   PointerType *PT = getMallocType(CI, TLI);
285*9880d681SAndroid Build Coastguard Worker   return PT ? PT->getElementType() : nullptr;
286*9880d681SAndroid Build Coastguard Worker }
287*9880d681SAndroid Build Coastguard Worker 
288*9880d681SAndroid Build Coastguard Worker /// getMallocArraySize - Returns the array size of a malloc call.  If the
289*9880d681SAndroid Build Coastguard Worker /// argument passed to malloc is a multiple of the size of the malloced type,
290*9880d681SAndroid Build Coastguard Worker /// then return that multiple.  For non-array mallocs, the multiple is
291*9880d681SAndroid Build Coastguard Worker /// constant 1.  Otherwise, return NULL for mallocs whose array size cannot be
292*9880d681SAndroid Build Coastguard Worker /// determined.
getMallocArraySize(CallInst * CI,const DataLayout & DL,const TargetLibraryInfo * TLI,bool LookThroughSExt)293*9880d681SAndroid Build Coastguard Worker Value *llvm::getMallocArraySize(CallInst *CI, const DataLayout &DL,
294*9880d681SAndroid Build Coastguard Worker                                 const TargetLibraryInfo *TLI,
295*9880d681SAndroid Build Coastguard Worker                                 bool LookThroughSExt) {
296*9880d681SAndroid Build Coastguard Worker   assert(isMallocLikeFn(CI, TLI) && "getMallocArraySize and not malloc call");
297*9880d681SAndroid Build Coastguard Worker   return computeArraySize(CI, DL, TLI, LookThroughSExt);
298*9880d681SAndroid Build Coastguard Worker }
299*9880d681SAndroid Build Coastguard Worker 
300*9880d681SAndroid Build Coastguard Worker 
301*9880d681SAndroid Build Coastguard Worker /// extractCallocCall - Returns the corresponding CallInst if the instruction
302*9880d681SAndroid Build Coastguard Worker /// is a calloc call.
extractCallocCall(const Value * I,const TargetLibraryInfo * TLI)303*9880d681SAndroid Build Coastguard Worker const CallInst *llvm::extractCallocCall(const Value *I,
304*9880d681SAndroid Build Coastguard Worker                                         const TargetLibraryInfo *TLI) {
305*9880d681SAndroid Build Coastguard Worker   return isCallocLikeFn(I, TLI) ? cast<CallInst>(I) : nullptr;
306*9880d681SAndroid Build Coastguard Worker }
307*9880d681SAndroid Build Coastguard Worker 
308*9880d681SAndroid Build Coastguard Worker 
309*9880d681SAndroid Build Coastguard Worker /// isFreeCall - Returns non-null if the value is a call to the builtin free()
isFreeCall(const Value * I,const TargetLibraryInfo * TLI)310*9880d681SAndroid Build Coastguard Worker const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
311*9880d681SAndroid Build Coastguard Worker   const CallInst *CI = dyn_cast<CallInst>(I);
312*9880d681SAndroid Build Coastguard Worker   if (!CI || isa<IntrinsicInst>(CI))
313*9880d681SAndroid Build Coastguard Worker     return nullptr;
314*9880d681SAndroid Build Coastguard Worker   Function *Callee = CI->getCalledFunction();
315*9880d681SAndroid Build Coastguard Worker   if (Callee == nullptr)
316*9880d681SAndroid Build Coastguard Worker     return nullptr;
317*9880d681SAndroid Build Coastguard Worker 
318*9880d681SAndroid Build Coastguard Worker   StringRef FnName = Callee->getName();
319*9880d681SAndroid Build Coastguard Worker   LibFunc::Func TLIFn;
320*9880d681SAndroid Build Coastguard Worker   if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn))
321*9880d681SAndroid Build Coastguard Worker     return nullptr;
322*9880d681SAndroid Build Coastguard Worker 
323*9880d681SAndroid Build Coastguard Worker   unsigned ExpectedNumParams;
324*9880d681SAndroid Build Coastguard Worker   if (TLIFn == LibFunc::free ||
325*9880d681SAndroid Build Coastguard Worker       TLIFn == LibFunc::ZdlPv || // operator delete(void*)
326*9880d681SAndroid Build Coastguard Worker       TLIFn == LibFunc::ZdaPv || // operator delete[](void*)
327*9880d681SAndroid Build Coastguard Worker       TLIFn == LibFunc::msvc_delete_ptr32 || // operator delete(void*)
328*9880d681SAndroid Build Coastguard Worker       TLIFn == LibFunc::msvc_delete_ptr64 || // operator delete(void*)
329*9880d681SAndroid Build Coastguard Worker       TLIFn == LibFunc::msvc_delete_array_ptr32 || // operator delete[](void*)
330*9880d681SAndroid Build Coastguard Worker       TLIFn == LibFunc::msvc_delete_array_ptr64)   // operator delete[](void*)
331*9880d681SAndroid Build Coastguard Worker     ExpectedNumParams = 1;
332*9880d681SAndroid Build Coastguard Worker   else if (TLIFn == LibFunc::ZdlPvj ||              // delete(void*, uint)
333*9880d681SAndroid Build Coastguard Worker            TLIFn == LibFunc::ZdlPvm ||              // delete(void*, ulong)
334*9880d681SAndroid Build Coastguard Worker            TLIFn == LibFunc::ZdlPvRKSt9nothrow_t || // delete(void*, nothrow)
335*9880d681SAndroid Build Coastguard Worker            TLIFn == LibFunc::ZdaPvj ||              // delete[](void*, uint)
336*9880d681SAndroid Build Coastguard Worker            TLIFn == LibFunc::ZdaPvm ||              // delete[](void*, ulong)
337*9880d681SAndroid Build Coastguard Worker            TLIFn == LibFunc::ZdaPvRKSt9nothrow_t || // delete[](void*, nothrow)
338*9880d681SAndroid Build Coastguard Worker            TLIFn == LibFunc::msvc_delete_ptr32_int ||      // delete(void*, uint)
339*9880d681SAndroid Build Coastguard Worker            TLIFn == LibFunc::msvc_delete_ptr64_longlong || // delete(void*, ulonglong)
340*9880d681SAndroid Build Coastguard Worker            TLIFn == LibFunc::msvc_delete_ptr32_nothrow || // delete(void*, nothrow)
341*9880d681SAndroid Build Coastguard Worker            TLIFn == LibFunc::msvc_delete_ptr64_nothrow || // delete(void*, nothrow)
342*9880d681SAndroid Build Coastguard Worker            TLIFn == LibFunc::msvc_delete_array_ptr32_int ||      // delete[](void*, uint)
343*9880d681SAndroid Build Coastguard Worker            TLIFn == LibFunc::msvc_delete_array_ptr64_longlong || // delete[](void*, ulonglong)
344*9880d681SAndroid Build Coastguard Worker            TLIFn == LibFunc::msvc_delete_array_ptr32_nothrow || // delete[](void*, nothrow)
345*9880d681SAndroid Build Coastguard Worker            TLIFn == LibFunc::msvc_delete_array_ptr64_nothrow)   // delete[](void*, nothrow)
346*9880d681SAndroid Build Coastguard Worker     ExpectedNumParams = 2;
347*9880d681SAndroid Build Coastguard Worker   else
348*9880d681SAndroid Build Coastguard Worker     return nullptr;
349*9880d681SAndroid Build Coastguard Worker 
350*9880d681SAndroid Build Coastguard Worker   // Check free prototype.
351*9880d681SAndroid Build Coastguard Worker   // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin
352*9880d681SAndroid Build Coastguard Worker   // attribute will exist.
353*9880d681SAndroid Build Coastguard Worker   FunctionType *FTy = Callee->getFunctionType();
354*9880d681SAndroid Build Coastguard Worker   if (!FTy->getReturnType()->isVoidTy())
355*9880d681SAndroid Build Coastguard Worker     return nullptr;
356*9880d681SAndroid Build Coastguard Worker   if (FTy->getNumParams() != ExpectedNumParams)
357*9880d681SAndroid Build Coastguard Worker     return nullptr;
358*9880d681SAndroid Build Coastguard Worker   if (FTy->getParamType(0) != Type::getInt8PtrTy(Callee->getContext()))
359*9880d681SAndroid Build Coastguard Worker     return nullptr;
360*9880d681SAndroid Build Coastguard Worker 
361*9880d681SAndroid Build Coastguard Worker   return CI;
362*9880d681SAndroid Build Coastguard Worker }
363*9880d681SAndroid Build Coastguard Worker 
364*9880d681SAndroid Build Coastguard Worker 
365*9880d681SAndroid Build Coastguard Worker 
366*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
367*9880d681SAndroid Build Coastguard Worker //  Utility functions to compute size of objects.
368*9880d681SAndroid Build Coastguard Worker //
getSizeWithOverflow(const SizeOffsetType & Data)369*9880d681SAndroid Build Coastguard Worker static APInt getSizeWithOverflow(const SizeOffsetType &Data) {
370*9880d681SAndroid Build Coastguard Worker   if (Data.second.isNegative() || Data.first.ult(Data.second))
371*9880d681SAndroid Build Coastguard Worker     return APInt(Data.first.getBitWidth(), 0);
372*9880d681SAndroid Build Coastguard Worker   return Data.first - Data.second;
373*9880d681SAndroid Build Coastguard Worker }
374*9880d681SAndroid Build Coastguard Worker 
375*9880d681SAndroid Build Coastguard Worker /// \brief Compute the size of the object pointed by Ptr. Returns true and the
376*9880d681SAndroid Build Coastguard Worker /// object size in Size if successful, and false otherwise.
377*9880d681SAndroid Build Coastguard Worker /// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
378*9880d681SAndroid Build Coastguard Worker /// byval arguments, and global variables.
getObjectSize(const Value * Ptr,uint64_t & Size,const DataLayout & DL,const TargetLibraryInfo * TLI,bool RoundToAlign,llvm::ObjSizeMode Mode)379*9880d681SAndroid Build Coastguard Worker bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
380*9880d681SAndroid Build Coastguard Worker                          const TargetLibraryInfo *TLI, bool RoundToAlign,
381*9880d681SAndroid Build Coastguard Worker                          llvm::ObjSizeMode Mode) {
382*9880d681SAndroid Build Coastguard Worker   ObjectSizeOffsetVisitor Visitor(DL, TLI, Ptr->getContext(),
383*9880d681SAndroid Build Coastguard Worker                                   RoundToAlign, Mode);
384*9880d681SAndroid Build Coastguard Worker   SizeOffsetType Data = Visitor.compute(const_cast<Value*>(Ptr));
385*9880d681SAndroid Build Coastguard Worker   if (!Visitor.bothKnown(Data))
386*9880d681SAndroid Build Coastguard Worker     return false;
387*9880d681SAndroid Build Coastguard Worker 
388*9880d681SAndroid Build Coastguard Worker   Size = getSizeWithOverflow(Data).getZExtValue();
389*9880d681SAndroid Build Coastguard Worker   return true;
390*9880d681SAndroid Build Coastguard Worker }
391*9880d681SAndroid Build Coastguard Worker 
392*9880d681SAndroid Build Coastguard Worker STATISTIC(ObjectVisitorArgument,
393*9880d681SAndroid Build Coastguard Worker           "Number of arguments with unsolved size and offset");
394*9880d681SAndroid Build Coastguard Worker STATISTIC(ObjectVisitorLoad,
395*9880d681SAndroid Build Coastguard Worker           "Number of load instructions with unsolved size and offset");
396*9880d681SAndroid Build Coastguard Worker 
397*9880d681SAndroid Build Coastguard Worker 
align(APInt Size,uint64_t Align)398*9880d681SAndroid Build Coastguard Worker APInt ObjectSizeOffsetVisitor::align(APInt Size, uint64_t Align) {
399*9880d681SAndroid Build Coastguard Worker   if (RoundToAlign && Align)
400*9880d681SAndroid Build Coastguard Worker     return APInt(IntTyBits, alignTo(Size.getZExtValue(), Align));
401*9880d681SAndroid Build Coastguard Worker   return Size;
402*9880d681SAndroid Build Coastguard Worker }
403*9880d681SAndroid Build Coastguard Worker 
ObjectSizeOffsetVisitor(const DataLayout & DL,const TargetLibraryInfo * TLI,LLVMContext & Context,bool RoundToAlign,ObjSizeMode Mode)404*9880d681SAndroid Build Coastguard Worker ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const DataLayout &DL,
405*9880d681SAndroid Build Coastguard Worker                                                  const TargetLibraryInfo *TLI,
406*9880d681SAndroid Build Coastguard Worker                                                  LLVMContext &Context,
407*9880d681SAndroid Build Coastguard Worker                                                  bool RoundToAlign,
408*9880d681SAndroid Build Coastguard Worker                                                  ObjSizeMode Mode)
409*9880d681SAndroid Build Coastguard Worker     : DL(DL), TLI(TLI), RoundToAlign(RoundToAlign), Mode(Mode) {
410*9880d681SAndroid Build Coastguard Worker   // Pointer size must be rechecked for each object visited since it could have
411*9880d681SAndroid Build Coastguard Worker   // a different address space.
412*9880d681SAndroid Build Coastguard Worker }
413*9880d681SAndroid Build Coastguard Worker 
compute(Value * V)414*9880d681SAndroid Build Coastguard Worker SizeOffsetType ObjectSizeOffsetVisitor::compute(Value *V) {
415*9880d681SAndroid Build Coastguard Worker   IntTyBits = DL.getPointerTypeSizeInBits(V->getType());
416*9880d681SAndroid Build Coastguard Worker   Zero = APInt::getNullValue(IntTyBits);
417*9880d681SAndroid Build Coastguard Worker 
418*9880d681SAndroid Build Coastguard Worker   V = V->stripPointerCasts();
419*9880d681SAndroid Build Coastguard Worker   if (Instruction *I = dyn_cast<Instruction>(V)) {
420*9880d681SAndroid Build Coastguard Worker     // If we have already seen this instruction, bail out. Cycles can happen in
421*9880d681SAndroid Build Coastguard Worker     // unreachable code after constant propagation.
422*9880d681SAndroid Build Coastguard Worker     if (!SeenInsts.insert(I).second)
423*9880d681SAndroid Build Coastguard Worker       return unknown();
424*9880d681SAndroid Build Coastguard Worker 
425*9880d681SAndroid Build Coastguard Worker     if (GEPOperator *GEP = dyn_cast<GEPOperator>(V))
426*9880d681SAndroid Build Coastguard Worker       return visitGEPOperator(*GEP);
427*9880d681SAndroid Build Coastguard Worker     return visit(*I);
428*9880d681SAndroid Build Coastguard Worker   }
429*9880d681SAndroid Build Coastguard Worker   if (Argument *A = dyn_cast<Argument>(V))
430*9880d681SAndroid Build Coastguard Worker     return visitArgument(*A);
431*9880d681SAndroid Build Coastguard Worker   if (ConstantPointerNull *P = dyn_cast<ConstantPointerNull>(V))
432*9880d681SAndroid Build Coastguard Worker     return visitConstantPointerNull(*P);
433*9880d681SAndroid Build Coastguard Worker   if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
434*9880d681SAndroid Build Coastguard Worker     return visitGlobalAlias(*GA);
435*9880d681SAndroid Build Coastguard Worker   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
436*9880d681SAndroid Build Coastguard Worker     return visitGlobalVariable(*GV);
437*9880d681SAndroid Build Coastguard Worker   if (UndefValue *UV = dyn_cast<UndefValue>(V))
438*9880d681SAndroid Build Coastguard Worker     return visitUndefValue(*UV);
439*9880d681SAndroid Build Coastguard Worker   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
440*9880d681SAndroid Build Coastguard Worker     if (CE->getOpcode() == Instruction::IntToPtr)
441*9880d681SAndroid Build Coastguard Worker       return unknown(); // clueless
442*9880d681SAndroid Build Coastguard Worker     if (CE->getOpcode() == Instruction::GetElementPtr)
443*9880d681SAndroid Build Coastguard Worker       return visitGEPOperator(cast<GEPOperator>(*CE));
444*9880d681SAndroid Build Coastguard Worker   }
445*9880d681SAndroid Build Coastguard Worker 
446*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "ObjectSizeOffsetVisitor::compute() unhandled value: " << *V
447*9880d681SAndroid Build Coastguard Worker         << '\n');
448*9880d681SAndroid Build Coastguard Worker   return unknown();
449*9880d681SAndroid Build Coastguard Worker }
450*9880d681SAndroid Build Coastguard Worker 
visitAllocaInst(AllocaInst & I)451*9880d681SAndroid Build Coastguard Worker SizeOffsetType ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
452*9880d681SAndroid Build Coastguard Worker   if (!I.getAllocatedType()->isSized())
453*9880d681SAndroid Build Coastguard Worker     return unknown();
454*9880d681SAndroid Build Coastguard Worker 
455*9880d681SAndroid Build Coastguard Worker   APInt Size(IntTyBits, DL.getTypeAllocSize(I.getAllocatedType()));
456*9880d681SAndroid Build Coastguard Worker   if (!I.isArrayAllocation())
457*9880d681SAndroid Build Coastguard Worker     return std::make_pair(align(Size, I.getAlignment()), Zero);
458*9880d681SAndroid Build Coastguard Worker 
459*9880d681SAndroid Build Coastguard Worker   Value *ArraySize = I.getArraySize();
460*9880d681SAndroid Build Coastguard Worker   if (const ConstantInt *C = dyn_cast<ConstantInt>(ArraySize)) {
461*9880d681SAndroid Build Coastguard Worker     Size *= C->getValue().zextOrSelf(IntTyBits);
462*9880d681SAndroid Build Coastguard Worker     return std::make_pair(align(Size, I.getAlignment()), Zero);
463*9880d681SAndroid Build Coastguard Worker   }
464*9880d681SAndroid Build Coastguard Worker   return unknown();
465*9880d681SAndroid Build Coastguard Worker }
466*9880d681SAndroid Build Coastguard Worker 
visitArgument(Argument & A)467*9880d681SAndroid Build Coastguard Worker SizeOffsetType ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
468*9880d681SAndroid Build Coastguard Worker   // No interprocedural analysis is done at the moment.
469*9880d681SAndroid Build Coastguard Worker   if (!A.hasByValOrInAllocaAttr()) {
470*9880d681SAndroid Build Coastguard Worker     ++ObjectVisitorArgument;
471*9880d681SAndroid Build Coastguard Worker     return unknown();
472*9880d681SAndroid Build Coastguard Worker   }
473*9880d681SAndroid Build Coastguard Worker   PointerType *PT = cast<PointerType>(A.getType());
474*9880d681SAndroid Build Coastguard Worker   APInt Size(IntTyBits, DL.getTypeAllocSize(PT->getElementType()));
475*9880d681SAndroid Build Coastguard Worker   return std::make_pair(align(Size, A.getParamAlignment()), Zero);
476*9880d681SAndroid Build Coastguard Worker }
477*9880d681SAndroid Build Coastguard Worker 
visitCallSite(CallSite CS)478*9880d681SAndroid Build Coastguard Worker SizeOffsetType ObjectSizeOffsetVisitor::visitCallSite(CallSite CS) {
479*9880d681SAndroid Build Coastguard Worker   Optional<AllocFnsTy> FnData =
480*9880d681SAndroid Build Coastguard Worker       getAllocationData(CS.getInstruction(), AnyAlloc, TLI);
481*9880d681SAndroid Build Coastguard Worker   if (!FnData)
482*9880d681SAndroid Build Coastguard Worker     return unknown();
483*9880d681SAndroid Build Coastguard Worker 
484*9880d681SAndroid Build Coastguard Worker   // Handle strdup-like functions separately.
485*9880d681SAndroid Build Coastguard Worker   if (FnData->AllocTy == StrDupLike) {
486*9880d681SAndroid Build Coastguard Worker     APInt Size(IntTyBits, GetStringLength(CS.getArgument(0)));
487*9880d681SAndroid Build Coastguard Worker     if (!Size)
488*9880d681SAndroid Build Coastguard Worker       return unknown();
489*9880d681SAndroid Build Coastguard Worker 
490*9880d681SAndroid Build Coastguard Worker     // Strndup limits strlen.
491*9880d681SAndroid Build Coastguard Worker     if (FnData->FstParam > 0) {
492*9880d681SAndroid Build Coastguard Worker       ConstantInt *Arg =
493*9880d681SAndroid Build Coastguard Worker           dyn_cast<ConstantInt>(CS.getArgument(FnData->FstParam));
494*9880d681SAndroid Build Coastguard Worker       if (!Arg)
495*9880d681SAndroid Build Coastguard Worker         return unknown();
496*9880d681SAndroid Build Coastguard Worker 
497*9880d681SAndroid Build Coastguard Worker       APInt MaxSize = Arg->getValue().zextOrSelf(IntTyBits);
498*9880d681SAndroid Build Coastguard Worker       if (Size.ugt(MaxSize))
499*9880d681SAndroid Build Coastguard Worker         Size = MaxSize + 1;
500*9880d681SAndroid Build Coastguard Worker     }
501*9880d681SAndroid Build Coastguard Worker     return std::make_pair(Size, Zero);
502*9880d681SAndroid Build Coastguard Worker   }
503*9880d681SAndroid Build Coastguard Worker 
504*9880d681SAndroid Build Coastguard Worker   ConstantInt *Arg = dyn_cast<ConstantInt>(CS.getArgument(FnData->FstParam));
505*9880d681SAndroid Build Coastguard Worker   if (!Arg)
506*9880d681SAndroid Build Coastguard Worker     return unknown();
507*9880d681SAndroid Build Coastguard Worker 
508*9880d681SAndroid Build Coastguard Worker   // When we're compiling N-bit code, and the user uses parameters that are
509*9880d681SAndroid Build Coastguard Worker   // greater than N bits (e.g. uint64_t on a 32-bit build), we can run into
510*9880d681SAndroid Build Coastguard Worker   // trouble with APInt size issues. This function handles resizing + overflow
511*9880d681SAndroid Build Coastguard Worker   // checks for us.
512*9880d681SAndroid Build Coastguard Worker   auto CheckedZextOrTrunc = [&](APInt &I) {
513*9880d681SAndroid Build Coastguard Worker     // More bits than we can handle. Checking the bit width isn't necessary, but
514*9880d681SAndroid Build Coastguard Worker     // it's faster than checking active bits, and should give `false` in the
515*9880d681SAndroid Build Coastguard Worker     // vast majority of cases.
516*9880d681SAndroid Build Coastguard Worker     if (I.getBitWidth() > IntTyBits && I.getActiveBits() > IntTyBits)
517*9880d681SAndroid Build Coastguard Worker       return false;
518*9880d681SAndroid Build Coastguard Worker     if (I.getBitWidth() != IntTyBits)
519*9880d681SAndroid Build Coastguard Worker       I = I.zextOrTrunc(IntTyBits);
520*9880d681SAndroid Build Coastguard Worker     return true;
521*9880d681SAndroid Build Coastguard Worker   };
522*9880d681SAndroid Build Coastguard Worker 
523*9880d681SAndroid Build Coastguard Worker   APInt Size = Arg->getValue();
524*9880d681SAndroid Build Coastguard Worker   if (!CheckedZextOrTrunc(Size))
525*9880d681SAndroid Build Coastguard Worker     return unknown();
526*9880d681SAndroid Build Coastguard Worker 
527*9880d681SAndroid Build Coastguard Worker   // Size is determined by just 1 parameter.
528*9880d681SAndroid Build Coastguard Worker   if (FnData->SndParam < 0)
529*9880d681SAndroid Build Coastguard Worker     return std::make_pair(Size, Zero);
530*9880d681SAndroid Build Coastguard Worker 
531*9880d681SAndroid Build Coastguard Worker   Arg = dyn_cast<ConstantInt>(CS.getArgument(FnData->SndParam));
532*9880d681SAndroid Build Coastguard Worker   if (!Arg)
533*9880d681SAndroid Build Coastguard Worker     return unknown();
534*9880d681SAndroid Build Coastguard Worker 
535*9880d681SAndroid Build Coastguard Worker   APInt NumElems = Arg->getValue();
536*9880d681SAndroid Build Coastguard Worker   if (!CheckedZextOrTrunc(NumElems))
537*9880d681SAndroid Build Coastguard Worker     return unknown();
538*9880d681SAndroid Build Coastguard Worker 
539*9880d681SAndroid Build Coastguard Worker   bool Overflow;
540*9880d681SAndroid Build Coastguard Worker   Size = Size.umul_ov(NumElems, Overflow);
541*9880d681SAndroid Build Coastguard Worker   return Overflow ? unknown() : std::make_pair(Size, Zero);
542*9880d681SAndroid Build Coastguard Worker 
543*9880d681SAndroid Build Coastguard Worker   // TODO: handle more standard functions (+ wchar cousins):
544*9880d681SAndroid Build Coastguard Worker   // - strdup / strndup
545*9880d681SAndroid Build Coastguard Worker   // - strcpy / strncpy
546*9880d681SAndroid Build Coastguard Worker   // - strcat / strncat
547*9880d681SAndroid Build Coastguard Worker   // - memcpy / memmove
548*9880d681SAndroid Build Coastguard Worker   // - strcat / strncat
549*9880d681SAndroid Build Coastguard Worker   // - memset
550*9880d681SAndroid Build Coastguard Worker }
551*9880d681SAndroid Build Coastguard Worker 
552*9880d681SAndroid Build Coastguard Worker SizeOffsetType
visitConstantPointerNull(ConstantPointerNull &)553*9880d681SAndroid Build Coastguard Worker ObjectSizeOffsetVisitor::visitConstantPointerNull(ConstantPointerNull&) {
554*9880d681SAndroid Build Coastguard Worker   return std::make_pair(Zero, Zero);
555*9880d681SAndroid Build Coastguard Worker }
556*9880d681SAndroid Build Coastguard Worker 
557*9880d681SAndroid Build Coastguard Worker SizeOffsetType
visitExtractElementInst(ExtractElementInst &)558*9880d681SAndroid Build Coastguard Worker ObjectSizeOffsetVisitor::visitExtractElementInst(ExtractElementInst&) {
559*9880d681SAndroid Build Coastguard Worker   return unknown();
560*9880d681SAndroid Build Coastguard Worker }
561*9880d681SAndroid Build Coastguard Worker 
562*9880d681SAndroid Build Coastguard Worker SizeOffsetType
visitExtractValueInst(ExtractValueInst &)563*9880d681SAndroid Build Coastguard Worker ObjectSizeOffsetVisitor::visitExtractValueInst(ExtractValueInst&) {
564*9880d681SAndroid Build Coastguard Worker   // Easy cases were already folded by previous passes.
565*9880d681SAndroid Build Coastguard Worker   return unknown();
566*9880d681SAndroid Build Coastguard Worker }
567*9880d681SAndroid Build Coastguard Worker 
visitGEPOperator(GEPOperator & GEP)568*9880d681SAndroid Build Coastguard Worker SizeOffsetType ObjectSizeOffsetVisitor::visitGEPOperator(GEPOperator &GEP) {
569*9880d681SAndroid Build Coastguard Worker   SizeOffsetType PtrData = compute(GEP.getPointerOperand());
570*9880d681SAndroid Build Coastguard Worker   APInt Offset(IntTyBits, 0);
571*9880d681SAndroid Build Coastguard Worker   if (!bothKnown(PtrData) || !GEP.accumulateConstantOffset(DL, Offset))
572*9880d681SAndroid Build Coastguard Worker     return unknown();
573*9880d681SAndroid Build Coastguard Worker 
574*9880d681SAndroid Build Coastguard Worker   return std::make_pair(PtrData.first, PtrData.second + Offset);
575*9880d681SAndroid Build Coastguard Worker }
576*9880d681SAndroid Build Coastguard Worker 
visitGlobalAlias(GlobalAlias & GA)577*9880d681SAndroid Build Coastguard Worker SizeOffsetType ObjectSizeOffsetVisitor::visitGlobalAlias(GlobalAlias &GA) {
578*9880d681SAndroid Build Coastguard Worker   if (GA.isInterposable())
579*9880d681SAndroid Build Coastguard Worker     return unknown();
580*9880d681SAndroid Build Coastguard Worker   return compute(GA.getAliasee());
581*9880d681SAndroid Build Coastguard Worker }
582*9880d681SAndroid Build Coastguard Worker 
visitGlobalVariable(GlobalVariable & GV)583*9880d681SAndroid Build Coastguard Worker SizeOffsetType ObjectSizeOffsetVisitor::visitGlobalVariable(GlobalVariable &GV){
584*9880d681SAndroid Build Coastguard Worker   if (!GV.hasDefinitiveInitializer())
585*9880d681SAndroid Build Coastguard Worker     return unknown();
586*9880d681SAndroid Build Coastguard Worker 
587*9880d681SAndroid Build Coastguard Worker   APInt Size(IntTyBits, DL.getTypeAllocSize(GV.getType()->getElementType()));
588*9880d681SAndroid Build Coastguard Worker   return std::make_pair(align(Size, GV.getAlignment()), Zero);
589*9880d681SAndroid Build Coastguard Worker }
590*9880d681SAndroid Build Coastguard Worker 
visitIntToPtrInst(IntToPtrInst &)591*9880d681SAndroid Build Coastguard Worker SizeOffsetType ObjectSizeOffsetVisitor::visitIntToPtrInst(IntToPtrInst&) {
592*9880d681SAndroid Build Coastguard Worker   // clueless
593*9880d681SAndroid Build Coastguard Worker   return unknown();
594*9880d681SAndroid Build Coastguard Worker }
595*9880d681SAndroid Build Coastguard Worker 
visitLoadInst(LoadInst &)596*9880d681SAndroid Build Coastguard Worker SizeOffsetType ObjectSizeOffsetVisitor::visitLoadInst(LoadInst&) {
597*9880d681SAndroid Build Coastguard Worker   ++ObjectVisitorLoad;
598*9880d681SAndroid Build Coastguard Worker   return unknown();
599*9880d681SAndroid Build Coastguard Worker }
600*9880d681SAndroid Build Coastguard Worker 
visitPHINode(PHINode &)601*9880d681SAndroid Build Coastguard Worker SizeOffsetType ObjectSizeOffsetVisitor::visitPHINode(PHINode&) {
602*9880d681SAndroid Build Coastguard Worker   // too complex to analyze statically.
603*9880d681SAndroid Build Coastguard Worker   return unknown();
604*9880d681SAndroid Build Coastguard Worker }
605*9880d681SAndroid Build Coastguard Worker 
visitSelectInst(SelectInst & I)606*9880d681SAndroid Build Coastguard Worker SizeOffsetType ObjectSizeOffsetVisitor::visitSelectInst(SelectInst &I) {
607*9880d681SAndroid Build Coastguard Worker   SizeOffsetType TrueSide  = compute(I.getTrueValue());
608*9880d681SAndroid Build Coastguard Worker   SizeOffsetType FalseSide = compute(I.getFalseValue());
609*9880d681SAndroid Build Coastguard Worker   if (bothKnown(TrueSide) && bothKnown(FalseSide)) {
610*9880d681SAndroid Build Coastguard Worker     if (TrueSide == FalseSide) {
611*9880d681SAndroid Build Coastguard Worker         return TrueSide;
612*9880d681SAndroid Build Coastguard Worker     }
613*9880d681SAndroid Build Coastguard Worker 
614*9880d681SAndroid Build Coastguard Worker     APInt TrueResult = getSizeWithOverflow(TrueSide);
615*9880d681SAndroid Build Coastguard Worker     APInt FalseResult = getSizeWithOverflow(FalseSide);
616*9880d681SAndroid Build Coastguard Worker 
617*9880d681SAndroid Build Coastguard Worker     if (TrueResult == FalseResult) {
618*9880d681SAndroid Build Coastguard Worker       return TrueSide;
619*9880d681SAndroid Build Coastguard Worker     }
620*9880d681SAndroid Build Coastguard Worker     if (Mode == ObjSizeMode::Min) {
621*9880d681SAndroid Build Coastguard Worker       if (TrueResult.slt(FalseResult))
622*9880d681SAndroid Build Coastguard Worker         return TrueSide;
623*9880d681SAndroid Build Coastguard Worker       return FalseSide;
624*9880d681SAndroid Build Coastguard Worker     }
625*9880d681SAndroid Build Coastguard Worker     if (Mode == ObjSizeMode::Max) {
626*9880d681SAndroid Build Coastguard Worker       if (TrueResult.sgt(FalseResult))
627*9880d681SAndroid Build Coastguard Worker         return TrueSide;
628*9880d681SAndroid Build Coastguard Worker       return FalseSide;
629*9880d681SAndroid Build Coastguard Worker     }
630*9880d681SAndroid Build Coastguard Worker   }
631*9880d681SAndroid Build Coastguard Worker   return unknown();
632*9880d681SAndroid Build Coastguard Worker }
633*9880d681SAndroid Build Coastguard Worker 
visitUndefValue(UndefValue &)634*9880d681SAndroid Build Coastguard Worker SizeOffsetType ObjectSizeOffsetVisitor::visitUndefValue(UndefValue&) {
635*9880d681SAndroid Build Coastguard Worker   return std::make_pair(Zero, Zero);
636*9880d681SAndroid Build Coastguard Worker }
637*9880d681SAndroid Build Coastguard Worker 
visitInstruction(Instruction & I)638*9880d681SAndroid Build Coastguard Worker SizeOffsetType ObjectSizeOffsetVisitor::visitInstruction(Instruction &I) {
639*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "ObjectSizeOffsetVisitor unknown instruction:" << I << '\n');
640*9880d681SAndroid Build Coastguard Worker   return unknown();
641*9880d681SAndroid Build Coastguard Worker }
642*9880d681SAndroid Build Coastguard Worker 
ObjectSizeOffsetEvaluator(const DataLayout & DL,const TargetLibraryInfo * TLI,LLVMContext & Context,bool RoundToAlign)643*9880d681SAndroid Build Coastguard Worker ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(
644*9880d681SAndroid Build Coastguard Worker     const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context,
645*9880d681SAndroid Build Coastguard Worker     bool RoundToAlign)
646*9880d681SAndroid Build Coastguard Worker     : DL(DL), TLI(TLI), Context(Context), Builder(Context, TargetFolder(DL)),
647*9880d681SAndroid Build Coastguard Worker       RoundToAlign(RoundToAlign) {
648*9880d681SAndroid Build Coastguard Worker   // IntTy and Zero must be set for each compute() since the address space may
649*9880d681SAndroid Build Coastguard Worker   // be different for later objects.
650*9880d681SAndroid Build Coastguard Worker }
651*9880d681SAndroid Build Coastguard Worker 
compute(Value * V)652*9880d681SAndroid Build Coastguard Worker SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute(Value *V) {
653*9880d681SAndroid Build Coastguard Worker   // XXX - Are vectors of pointers possible here?
654*9880d681SAndroid Build Coastguard Worker   IntTy = cast<IntegerType>(DL.getIntPtrType(V->getType()));
655*9880d681SAndroid Build Coastguard Worker   Zero = ConstantInt::get(IntTy, 0);
656*9880d681SAndroid Build Coastguard Worker 
657*9880d681SAndroid Build Coastguard Worker   SizeOffsetEvalType Result = compute_(V);
658*9880d681SAndroid Build Coastguard Worker 
659*9880d681SAndroid Build Coastguard Worker   if (!bothKnown(Result)) {
660*9880d681SAndroid Build Coastguard Worker     // Erase everything that was computed in this iteration from the cache, so
661*9880d681SAndroid Build Coastguard Worker     // that no dangling references are left behind. We could be a bit smarter if
662*9880d681SAndroid Build Coastguard Worker     // we kept a dependency graph. It's probably not worth the complexity.
663*9880d681SAndroid Build Coastguard Worker     for (const Value *SeenVal : SeenVals) {
664*9880d681SAndroid Build Coastguard Worker       CacheMapTy::iterator CacheIt = CacheMap.find(SeenVal);
665*9880d681SAndroid Build Coastguard Worker       // non-computable results can be safely cached
666*9880d681SAndroid Build Coastguard Worker       if (CacheIt != CacheMap.end() && anyKnown(CacheIt->second))
667*9880d681SAndroid Build Coastguard Worker         CacheMap.erase(CacheIt);
668*9880d681SAndroid Build Coastguard Worker     }
669*9880d681SAndroid Build Coastguard Worker   }
670*9880d681SAndroid Build Coastguard Worker 
671*9880d681SAndroid Build Coastguard Worker   SeenVals.clear();
672*9880d681SAndroid Build Coastguard Worker   return Result;
673*9880d681SAndroid Build Coastguard Worker }
674*9880d681SAndroid Build Coastguard Worker 
compute_(Value * V)675*9880d681SAndroid Build Coastguard Worker SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute_(Value *V) {
676*9880d681SAndroid Build Coastguard Worker   ObjectSizeOffsetVisitor Visitor(DL, TLI, Context, RoundToAlign);
677*9880d681SAndroid Build Coastguard Worker   SizeOffsetType Const = Visitor.compute(V);
678*9880d681SAndroid Build Coastguard Worker   if (Visitor.bothKnown(Const))
679*9880d681SAndroid Build Coastguard Worker     return std::make_pair(ConstantInt::get(Context, Const.first),
680*9880d681SAndroid Build Coastguard Worker                           ConstantInt::get(Context, Const.second));
681*9880d681SAndroid Build Coastguard Worker 
682*9880d681SAndroid Build Coastguard Worker   V = V->stripPointerCasts();
683*9880d681SAndroid Build Coastguard Worker 
684*9880d681SAndroid Build Coastguard Worker   // Check cache.
685*9880d681SAndroid Build Coastguard Worker   CacheMapTy::iterator CacheIt = CacheMap.find(V);
686*9880d681SAndroid Build Coastguard Worker   if (CacheIt != CacheMap.end())
687*9880d681SAndroid Build Coastguard Worker     return CacheIt->second;
688*9880d681SAndroid Build Coastguard Worker 
689*9880d681SAndroid Build Coastguard Worker   // Always generate code immediately before the instruction being
690*9880d681SAndroid Build Coastguard Worker   // processed, so that the generated code dominates the same BBs.
691*9880d681SAndroid Build Coastguard Worker   BuilderTy::InsertPointGuard Guard(Builder);
692*9880d681SAndroid Build Coastguard Worker   if (Instruction *I = dyn_cast<Instruction>(V))
693*9880d681SAndroid Build Coastguard Worker     Builder.SetInsertPoint(I);
694*9880d681SAndroid Build Coastguard Worker 
695*9880d681SAndroid Build Coastguard Worker   // Now compute the size and offset.
696*9880d681SAndroid Build Coastguard Worker   SizeOffsetEvalType Result;
697*9880d681SAndroid Build Coastguard Worker 
698*9880d681SAndroid Build Coastguard Worker   // Record the pointers that were handled in this run, so that they can be
699*9880d681SAndroid Build Coastguard Worker   // cleaned later if something fails. We also use this set to break cycles that
700*9880d681SAndroid Build Coastguard Worker   // can occur in dead code.
701*9880d681SAndroid Build Coastguard Worker   if (!SeenVals.insert(V).second) {
702*9880d681SAndroid Build Coastguard Worker     Result = unknown();
703*9880d681SAndroid Build Coastguard Worker   } else if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
704*9880d681SAndroid Build Coastguard Worker     Result = visitGEPOperator(*GEP);
705*9880d681SAndroid Build Coastguard Worker   } else if (Instruction *I = dyn_cast<Instruction>(V)) {
706*9880d681SAndroid Build Coastguard Worker     Result = visit(*I);
707*9880d681SAndroid Build Coastguard Worker   } else if (isa<Argument>(V) ||
708*9880d681SAndroid Build Coastguard Worker              (isa<ConstantExpr>(V) &&
709*9880d681SAndroid Build Coastguard Worker               cast<ConstantExpr>(V)->getOpcode() == Instruction::IntToPtr) ||
710*9880d681SAndroid Build Coastguard Worker              isa<GlobalAlias>(V) ||
711*9880d681SAndroid Build Coastguard Worker              isa<GlobalVariable>(V)) {
712*9880d681SAndroid Build Coastguard Worker     // Ignore values where we cannot do more than ObjectSizeVisitor.
713*9880d681SAndroid Build Coastguard Worker     Result = unknown();
714*9880d681SAndroid Build Coastguard Worker   } else {
715*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "ObjectSizeOffsetEvaluator::compute() unhandled value: "
716*9880d681SAndroid Build Coastguard Worker           << *V << '\n');
717*9880d681SAndroid Build Coastguard Worker     Result = unknown();
718*9880d681SAndroid Build Coastguard Worker   }
719*9880d681SAndroid Build Coastguard Worker 
720*9880d681SAndroid Build Coastguard Worker   // Don't reuse CacheIt since it may be invalid at this point.
721*9880d681SAndroid Build Coastguard Worker   CacheMap[V] = Result;
722*9880d681SAndroid Build Coastguard Worker   return Result;
723*9880d681SAndroid Build Coastguard Worker }
724*9880d681SAndroid Build Coastguard Worker 
visitAllocaInst(AllocaInst & I)725*9880d681SAndroid Build Coastguard Worker SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitAllocaInst(AllocaInst &I) {
726*9880d681SAndroid Build Coastguard Worker   if (!I.getAllocatedType()->isSized())
727*9880d681SAndroid Build Coastguard Worker     return unknown();
728*9880d681SAndroid Build Coastguard Worker 
729*9880d681SAndroid Build Coastguard Worker   // must be a VLA
730*9880d681SAndroid Build Coastguard Worker   assert(I.isArrayAllocation());
731*9880d681SAndroid Build Coastguard Worker   Value *ArraySize = I.getArraySize();
732*9880d681SAndroid Build Coastguard Worker   Value *Size = ConstantInt::get(ArraySize->getType(),
733*9880d681SAndroid Build Coastguard Worker                                  DL.getTypeAllocSize(I.getAllocatedType()));
734*9880d681SAndroid Build Coastguard Worker   Size = Builder.CreateMul(Size, ArraySize);
735*9880d681SAndroid Build Coastguard Worker   return std::make_pair(Size, Zero);
736*9880d681SAndroid Build Coastguard Worker }
737*9880d681SAndroid Build Coastguard Worker 
visitCallSite(CallSite CS)738*9880d681SAndroid Build Coastguard Worker SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitCallSite(CallSite CS) {
739*9880d681SAndroid Build Coastguard Worker   Optional<AllocFnsTy> FnData =
740*9880d681SAndroid Build Coastguard Worker       getAllocationData(CS.getInstruction(), AnyAlloc, TLI);
741*9880d681SAndroid Build Coastguard Worker   if (!FnData)
742*9880d681SAndroid Build Coastguard Worker     return unknown();
743*9880d681SAndroid Build Coastguard Worker 
744*9880d681SAndroid Build Coastguard Worker   // Handle strdup-like functions separately.
745*9880d681SAndroid Build Coastguard Worker   if (FnData->AllocTy == StrDupLike) {
746*9880d681SAndroid Build Coastguard Worker     // TODO
747*9880d681SAndroid Build Coastguard Worker     return unknown();
748*9880d681SAndroid Build Coastguard Worker   }
749*9880d681SAndroid Build Coastguard Worker 
750*9880d681SAndroid Build Coastguard Worker   Value *FirstArg = CS.getArgument(FnData->FstParam);
751*9880d681SAndroid Build Coastguard Worker   FirstArg = Builder.CreateZExt(FirstArg, IntTy);
752*9880d681SAndroid Build Coastguard Worker   if (FnData->SndParam < 0)
753*9880d681SAndroid Build Coastguard Worker     return std::make_pair(FirstArg, Zero);
754*9880d681SAndroid Build Coastguard Worker 
755*9880d681SAndroid Build Coastguard Worker   Value *SecondArg = CS.getArgument(FnData->SndParam);
756*9880d681SAndroid Build Coastguard Worker   SecondArg = Builder.CreateZExt(SecondArg, IntTy);
757*9880d681SAndroid Build Coastguard Worker   Value *Size = Builder.CreateMul(FirstArg, SecondArg);
758*9880d681SAndroid Build Coastguard Worker   return std::make_pair(Size, Zero);
759*9880d681SAndroid Build Coastguard Worker 
760*9880d681SAndroid Build Coastguard Worker   // TODO: handle more standard functions (+ wchar cousins):
761*9880d681SAndroid Build Coastguard Worker   // - strdup / strndup
762*9880d681SAndroid Build Coastguard Worker   // - strcpy / strncpy
763*9880d681SAndroid Build Coastguard Worker   // - strcat / strncat
764*9880d681SAndroid Build Coastguard Worker   // - memcpy / memmove
765*9880d681SAndroid Build Coastguard Worker   // - strcat / strncat
766*9880d681SAndroid Build Coastguard Worker   // - memset
767*9880d681SAndroid Build Coastguard Worker }
768*9880d681SAndroid Build Coastguard Worker 
769*9880d681SAndroid Build Coastguard Worker SizeOffsetEvalType
visitExtractElementInst(ExtractElementInst &)770*9880d681SAndroid Build Coastguard Worker ObjectSizeOffsetEvaluator::visitExtractElementInst(ExtractElementInst&) {
771*9880d681SAndroid Build Coastguard Worker   return unknown();
772*9880d681SAndroid Build Coastguard Worker }
773*9880d681SAndroid Build Coastguard Worker 
774*9880d681SAndroid Build Coastguard Worker SizeOffsetEvalType
visitExtractValueInst(ExtractValueInst &)775*9880d681SAndroid Build Coastguard Worker ObjectSizeOffsetEvaluator::visitExtractValueInst(ExtractValueInst&) {
776*9880d681SAndroid Build Coastguard Worker   return unknown();
777*9880d681SAndroid Build Coastguard Worker }
778*9880d681SAndroid Build Coastguard Worker 
779*9880d681SAndroid Build Coastguard Worker SizeOffsetEvalType
visitGEPOperator(GEPOperator & GEP)780*9880d681SAndroid Build Coastguard Worker ObjectSizeOffsetEvaluator::visitGEPOperator(GEPOperator &GEP) {
781*9880d681SAndroid Build Coastguard Worker   SizeOffsetEvalType PtrData = compute_(GEP.getPointerOperand());
782*9880d681SAndroid Build Coastguard Worker   if (!bothKnown(PtrData))
783*9880d681SAndroid Build Coastguard Worker     return unknown();
784*9880d681SAndroid Build Coastguard Worker 
785*9880d681SAndroid Build Coastguard Worker   Value *Offset = EmitGEPOffset(&Builder, DL, &GEP, /*NoAssumptions=*/true);
786*9880d681SAndroid Build Coastguard Worker   Offset = Builder.CreateAdd(PtrData.second, Offset);
787*9880d681SAndroid Build Coastguard Worker   return std::make_pair(PtrData.first, Offset);
788*9880d681SAndroid Build Coastguard Worker }
789*9880d681SAndroid Build Coastguard Worker 
visitIntToPtrInst(IntToPtrInst &)790*9880d681SAndroid Build Coastguard Worker SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitIntToPtrInst(IntToPtrInst&) {
791*9880d681SAndroid Build Coastguard Worker   // clueless
792*9880d681SAndroid Build Coastguard Worker   return unknown();
793*9880d681SAndroid Build Coastguard Worker }
794*9880d681SAndroid Build Coastguard Worker 
visitLoadInst(LoadInst &)795*9880d681SAndroid Build Coastguard Worker SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitLoadInst(LoadInst&) {
796*9880d681SAndroid Build Coastguard Worker   return unknown();
797*9880d681SAndroid Build Coastguard Worker }
798*9880d681SAndroid Build Coastguard Worker 
visitPHINode(PHINode & PHI)799*9880d681SAndroid Build Coastguard Worker SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitPHINode(PHINode &PHI) {
800*9880d681SAndroid Build Coastguard Worker   // Create 2 PHIs: one for size and another for offset.
801*9880d681SAndroid Build Coastguard Worker   PHINode *SizePHI   = Builder.CreatePHI(IntTy, PHI.getNumIncomingValues());
802*9880d681SAndroid Build Coastguard Worker   PHINode *OffsetPHI = Builder.CreatePHI(IntTy, PHI.getNumIncomingValues());
803*9880d681SAndroid Build Coastguard Worker 
804*9880d681SAndroid Build Coastguard Worker   // Insert right away in the cache to handle recursive PHIs.
805*9880d681SAndroid Build Coastguard Worker   CacheMap[&PHI] = std::make_pair(SizePHI, OffsetPHI);
806*9880d681SAndroid Build Coastguard Worker 
807*9880d681SAndroid Build Coastguard Worker   // Compute offset/size for each PHI incoming pointer.
808*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = PHI.getNumIncomingValues(); i != e; ++i) {
809*9880d681SAndroid Build Coastguard Worker     Builder.SetInsertPoint(&*PHI.getIncomingBlock(i)->getFirstInsertionPt());
810*9880d681SAndroid Build Coastguard Worker     SizeOffsetEvalType EdgeData = compute_(PHI.getIncomingValue(i));
811*9880d681SAndroid Build Coastguard Worker 
812*9880d681SAndroid Build Coastguard Worker     if (!bothKnown(EdgeData)) {
813*9880d681SAndroid Build Coastguard Worker       OffsetPHI->replaceAllUsesWith(UndefValue::get(IntTy));
814*9880d681SAndroid Build Coastguard Worker       OffsetPHI->eraseFromParent();
815*9880d681SAndroid Build Coastguard Worker       SizePHI->replaceAllUsesWith(UndefValue::get(IntTy));
816*9880d681SAndroid Build Coastguard Worker       SizePHI->eraseFromParent();
817*9880d681SAndroid Build Coastguard Worker       return unknown();
818*9880d681SAndroid Build Coastguard Worker     }
819*9880d681SAndroid Build Coastguard Worker     SizePHI->addIncoming(EdgeData.first, PHI.getIncomingBlock(i));
820*9880d681SAndroid Build Coastguard Worker     OffsetPHI->addIncoming(EdgeData.second, PHI.getIncomingBlock(i));
821*9880d681SAndroid Build Coastguard Worker   }
822*9880d681SAndroid Build Coastguard Worker 
823*9880d681SAndroid Build Coastguard Worker   Value *Size = SizePHI, *Offset = OffsetPHI, *Tmp;
824*9880d681SAndroid Build Coastguard Worker   if ((Tmp = SizePHI->hasConstantValue())) {
825*9880d681SAndroid Build Coastguard Worker     Size = Tmp;
826*9880d681SAndroid Build Coastguard Worker     SizePHI->replaceAllUsesWith(Size);
827*9880d681SAndroid Build Coastguard Worker     SizePHI->eraseFromParent();
828*9880d681SAndroid Build Coastguard Worker   }
829*9880d681SAndroid Build Coastguard Worker   if ((Tmp = OffsetPHI->hasConstantValue())) {
830*9880d681SAndroid Build Coastguard Worker     Offset = Tmp;
831*9880d681SAndroid Build Coastguard Worker     OffsetPHI->replaceAllUsesWith(Offset);
832*9880d681SAndroid Build Coastguard Worker     OffsetPHI->eraseFromParent();
833*9880d681SAndroid Build Coastguard Worker   }
834*9880d681SAndroid Build Coastguard Worker   return std::make_pair(Size, Offset);
835*9880d681SAndroid Build Coastguard Worker }
836*9880d681SAndroid Build Coastguard Worker 
visitSelectInst(SelectInst & I)837*9880d681SAndroid Build Coastguard Worker SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitSelectInst(SelectInst &I) {
838*9880d681SAndroid Build Coastguard Worker   SizeOffsetEvalType TrueSide  = compute_(I.getTrueValue());
839*9880d681SAndroid Build Coastguard Worker   SizeOffsetEvalType FalseSide = compute_(I.getFalseValue());
840*9880d681SAndroid Build Coastguard Worker 
841*9880d681SAndroid Build Coastguard Worker   if (!bothKnown(TrueSide) || !bothKnown(FalseSide))
842*9880d681SAndroid Build Coastguard Worker     return unknown();
843*9880d681SAndroid Build Coastguard Worker   if (TrueSide == FalseSide)
844*9880d681SAndroid Build Coastguard Worker     return TrueSide;
845*9880d681SAndroid Build Coastguard Worker 
846*9880d681SAndroid Build Coastguard Worker   Value *Size = Builder.CreateSelect(I.getCondition(), TrueSide.first,
847*9880d681SAndroid Build Coastguard Worker                                      FalseSide.first);
848*9880d681SAndroid Build Coastguard Worker   Value *Offset = Builder.CreateSelect(I.getCondition(), TrueSide.second,
849*9880d681SAndroid Build Coastguard Worker                                        FalseSide.second);
850*9880d681SAndroid Build Coastguard Worker   return std::make_pair(Size, Offset);
851*9880d681SAndroid Build Coastguard Worker }
852*9880d681SAndroid Build Coastguard Worker 
visitInstruction(Instruction & I)853*9880d681SAndroid Build Coastguard Worker SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitInstruction(Instruction &I) {
854*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "ObjectSizeOffsetEvaluator unknown instruction:" << I <<'\n');
855*9880d681SAndroid Build Coastguard Worker   return unknown();
856*9880d681SAndroid Build Coastguard Worker }
857