comparison lib/Analysis/MemoryBuiltins.cpp @ 120:1172e4bd9c6f

update 4.0.0
author mir3636
date Fri, 25 Nov 2016 19:14:25 +0900
parents 7d135dc70f03
children 803732b1fca8
comparison
equal deleted inserted replaced
101:34baf5011add 120:1172e4bd9c6f
40 AllocLike = MallocLike | CallocLike | StrDupLike, 40 AllocLike = MallocLike | CallocLike | StrDupLike,
41 AnyAlloc = AllocLike | ReallocLike 41 AnyAlloc = AllocLike | ReallocLike
42 }; 42 };
43 43
44 struct AllocFnsTy { 44 struct AllocFnsTy {
45 LibFunc::Func Func;
46 AllocType AllocTy; 45 AllocType AllocTy;
47 unsigned char NumParams; 46 unsigned NumParams;
48 // First and Second size parameters (or -1 if unused) 47 // First and Second size parameters (or -1 if unused)
49 signed char FstParam, SndParam; 48 int FstParam, SndParam;
50 }; 49 };
51 50
52 // FIXME: certain users need more information. E.g., SimplifyLibCalls needs to 51 // FIXME: certain users need more information. E.g., SimplifyLibCalls needs to
53 // know which functions are nounwind, noalias, nocapture parameters, etc. 52 // know which functions are nounwind, noalias, nocapture parameters, etc.
54 static const AllocFnsTy AllocationFnData[] = { 53 static const std::pair<LibFunc::Func, AllocFnsTy> AllocationFnData[] = {
55 {LibFunc::malloc, MallocLike, 1, 0, -1}, 54 {LibFunc::malloc, {MallocLike, 1, 0, -1}},
56 {LibFunc::valloc, MallocLike, 1, 0, -1}, 55 {LibFunc::valloc, {MallocLike, 1, 0, -1}},
57 {LibFunc::Znwj, OpNewLike, 1, 0, -1}, // new(unsigned int) 56 {LibFunc::Znwj, {OpNewLike, 1, 0, -1}}, // new(unsigned int)
58 {LibFunc::ZnwjRKSt9nothrow_t, MallocLike, 2, 0, -1}, // new(unsigned int, nothrow) 57 {LibFunc::ZnwjRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow)
59 {LibFunc::Znwm, OpNewLike, 1, 0, -1}, // new(unsigned long) 58 {LibFunc::Znwm, {OpNewLike, 1, 0, -1}}, // new(unsigned long)
60 {LibFunc::ZnwmRKSt9nothrow_t, MallocLike, 2, 0, -1}, // new(unsigned long, nothrow) 59 {LibFunc::ZnwmRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned long, nothrow)
61 {LibFunc::Znaj, OpNewLike, 1, 0, -1}, // new[](unsigned int) 60 {LibFunc::Znaj, {OpNewLike, 1, 0, -1}}, // new[](unsigned int)
62 {LibFunc::ZnajRKSt9nothrow_t, MallocLike, 2, 0, -1}, // new[](unsigned int, nothrow) 61 {LibFunc::ZnajRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new[](unsigned int, nothrow)
63 {LibFunc::Znam, OpNewLike, 1, 0, -1}, // new[](unsigned long) 62 {LibFunc::Znam, {OpNewLike, 1, 0, -1}}, // new[](unsigned long)
64 {LibFunc::ZnamRKSt9nothrow_t, MallocLike, 2, 0, -1}, // new[](unsigned long, nothrow) 63 {LibFunc::ZnamRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new[](unsigned long, nothrow)
65 {LibFunc::msvc_new_int, OpNewLike, 1, 0, -1}, // new(unsigned int) 64 {LibFunc::msvc_new_int, {OpNewLike, 1, 0, -1}}, // new(unsigned int)
66 {LibFunc::msvc_new_int_nothrow, MallocLike, 2, 0, -1}, // new(unsigned int, nothrow) 65 {LibFunc::msvc_new_int_nothrow, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow)
67 {LibFunc::msvc_new_longlong, OpNewLike, 1, 0, -1}, // new(unsigned long long) 66 {LibFunc::msvc_new_longlong, {OpNewLike, 1, 0, -1}}, // new(unsigned long long)
68 {LibFunc::msvc_new_longlong_nothrow, MallocLike, 2, 0, -1}, // new(unsigned long long, nothrow) 67 {LibFunc::msvc_new_longlong_nothrow, {MallocLike, 2, 0, -1}}, // new(unsigned long long, nothrow)
69 {LibFunc::msvc_new_array_int, OpNewLike, 1, 0, -1}, // new[](unsigned int) 68 {LibFunc::msvc_new_array_int, {OpNewLike, 1, 0, -1}}, // new[](unsigned int)
70 {LibFunc::msvc_new_array_int_nothrow, MallocLike, 2, 0, -1}, // new[](unsigned int, nothrow) 69 {LibFunc::msvc_new_array_int_nothrow, {MallocLike, 2, 0, -1}}, // new[](unsigned int, nothrow)
71 {LibFunc::msvc_new_array_longlong, OpNewLike, 1, 0, -1}, // new[](unsigned long long) 70 {LibFunc::msvc_new_array_longlong, {OpNewLike, 1, 0, -1}}, // new[](unsigned long long)
72 {LibFunc::msvc_new_array_longlong_nothrow, MallocLike, 2, 0, -1}, // new[](unsigned long long, nothrow) 71 {LibFunc::msvc_new_array_longlong_nothrow, {MallocLike, 2, 0, -1}}, // new[](unsigned long long, nothrow)
73 {LibFunc::calloc, CallocLike, 2, 0, 1}, 72 {LibFunc::calloc, {CallocLike, 2, 0, 1}},
74 {LibFunc::realloc, ReallocLike, 2, 1, -1}, 73 {LibFunc::realloc, {ReallocLike, 2, 1, -1}},
75 {LibFunc::reallocf, ReallocLike, 2, 1, -1}, 74 {LibFunc::reallocf, {ReallocLike, 2, 1, -1}},
76 {LibFunc::strdup, StrDupLike, 1, -1, -1}, 75 {LibFunc::strdup, {StrDupLike, 1, -1, -1}},
77 {LibFunc::strndup, StrDupLike, 2, 1, -1} 76 {LibFunc::strndup, {StrDupLike, 2, 1, -1}}
78 // TODO: Handle "int posix_memalign(void **, size_t, size_t)" 77 // TODO: Handle "int posix_memalign(void **, size_t, size_t)"
79 }; 78 };
80 79
81 80
82 static Function *getCalledFunction(const Value *V, bool LookThroughBitCast) { 81 static Function *getCalledFunction(const Value *V, bool LookThroughBitCast) {
94 if (!Callee || !Callee->isDeclaration()) 93 if (!Callee || !Callee->isDeclaration())
95 return nullptr; 94 return nullptr;
96 return Callee; 95 return Callee;
97 } 96 }
98 97
99 /// \brief Returns the allocation data for the given value if it is a call to a 98 /// Returns the allocation data for the given value if it's either a call to a
100 /// known allocation function, and NULL otherwise. 99 /// known allocation function, or a call to a function with the allocsize
101 static const AllocFnsTy *getAllocationData(const Value *V, AllocType AllocTy, 100 /// attribute.
102 const TargetLibraryInfo *TLI, 101 static Optional<AllocFnsTy> getAllocationData(const Value *V, AllocType AllocTy,
103 bool LookThroughBitCast = false) { 102 const TargetLibraryInfo *TLI,
103 bool LookThroughBitCast = false) {
104 // Skip intrinsics 104 // Skip intrinsics
105 if (isa<IntrinsicInst>(V)) 105 if (isa<IntrinsicInst>(V))
106 return nullptr; 106 return None;
107 107
108 Function *Callee = getCalledFunction(V, LookThroughBitCast); 108 const Function *Callee = getCalledFunction(V, LookThroughBitCast);
109 if (!Callee) 109 if (!Callee)
110 return nullptr; 110 return None;
111
112 // If it has allocsize, we can skip checking if it's a known function.
113 //
114 // MallocLike is chosen here because allocsize makes no guarantees about the
115 // nullness of the result of the function, nor does it deal with strings, nor
116 // does it require that the memory returned is zeroed out.
117 const AllocType AllocSizeAllocTy = MallocLike;
118 if ((AllocTy & AllocSizeAllocTy) == AllocSizeAllocTy &&
119 Callee->hasFnAttribute(Attribute::AllocSize)) {
120 Attribute Attr = Callee->getFnAttribute(Attribute::AllocSize);
121 std::pair<unsigned, Optional<unsigned>> Args = Attr.getAllocSizeArgs();
122
123 AllocFnsTy Result;
124 Result.AllocTy = AllocSizeAllocTy;
125 Result.NumParams = Callee->getNumOperands();
126 Result.FstParam = Args.first;
127 Result.SndParam = Args.second.getValueOr(-1);
128 return Result;
129 }
111 130
112 // Make sure that the function is available. 131 // Make sure that the function is available.
113 StringRef FnName = Callee->getName(); 132 StringRef FnName = Callee->getName();
114 LibFunc::Func TLIFn; 133 LibFunc::Func TLIFn;
115 if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn)) 134 if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn))
116 return nullptr; 135 return None;
117 136
118 const AllocFnsTy *FnData = 137 const auto *Iter =
119 std::find_if(std::begin(AllocationFnData), std::end(AllocationFnData), 138 std::find_if(std::begin(AllocationFnData), std::end(AllocationFnData),
120 [TLIFn](const AllocFnsTy &Fn) { return Fn.Func == TLIFn; }); 139 [TLIFn](const std::pair<LibFunc::Func, AllocFnsTy> &P) {
121 140 return P.first == TLIFn;
122 if (FnData == std::end(AllocationFnData)) 141 });
123 return nullptr; 142
124 143 if (Iter == std::end(AllocationFnData))
144 return None;
145
146 const AllocFnsTy *FnData = &Iter->second;
125 if ((FnData->AllocTy & AllocTy) != FnData->AllocTy) 147 if ((FnData->AllocTy & AllocTy) != FnData->AllocTy)
126 return nullptr; 148 return None;
127 149
128 // Check function prototype. 150 // Check function prototype.
129 int FstParam = FnData->FstParam; 151 int FstParam = FnData->FstParam;
130 int SndParam = FnData->SndParam; 152 int SndParam = FnData->SndParam;
131 FunctionType *FTy = Callee->getFunctionType(); 153 FunctionType *FTy = Callee->getFunctionType();
136 (FTy->getParamType(FstParam)->isIntegerTy(32) || 158 (FTy->getParamType(FstParam)->isIntegerTy(32) ||
137 FTy->getParamType(FstParam)->isIntegerTy(64))) && 159 FTy->getParamType(FstParam)->isIntegerTy(64))) &&
138 (SndParam < 0 || 160 (SndParam < 0 ||
139 FTy->getParamType(SndParam)->isIntegerTy(32) || 161 FTy->getParamType(SndParam)->isIntegerTy(32) ||
140 FTy->getParamType(SndParam)->isIntegerTy(64))) 162 FTy->getParamType(SndParam)->isIntegerTy(64)))
141 return FnData; 163 return *FnData;
142 return nullptr; 164 return None;
143 } 165 }
144 166
145 static bool hasNoAliasAttr(const Value *V, bool LookThroughBitCast) { 167 static bool hasNoAliasAttr(const Value *V, bool LookThroughBitCast) {
146 ImmutableCallSite CS(LookThroughBitCast ? V->stripPointerCasts() : V); 168 ImmutableCallSite CS(LookThroughBitCast ? V->stripPointerCasts() : V);
147 return CS && CS.hasFnAttr(Attribute::NoAlias); 169 return CS && CS.paramHasAttr(AttributeSet::ReturnIndex, Attribute::NoAlias);
148 } 170 }
149 171
150 172
151 /// \brief Tests if a value is a call or invoke to a library function that 173 /// \brief Tests if a value is a call or invoke to a library function that
152 /// allocates or reallocates memory (either malloc, calloc, realloc, or strdup 174 /// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
153 /// like). 175 /// like).
154 bool llvm::isAllocationFn(const Value *V, const TargetLibraryInfo *TLI, 176 bool llvm::isAllocationFn(const Value *V, const TargetLibraryInfo *TLI,
155 bool LookThroughBitCast) { 177 bool LookThroughBitCast) {
156 return getAllocationData(V, AnyAlloc, TLI, LookThroughBitCast); 178 return getAllocationData(V, AnyAlloc, TLI, LookThroughBitCast).hasValue();
157 } 179 }
158 180
159 /// \brief Tests if a value is a call or invoke to a function that returns a 181 /// \brief Tests if a value is a call or invoke to a function that returns a
160 /// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions). 182 /// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
161 bool llvm::isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI, 183 bool llvm::isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI,
168 190
169 /// \brief Tests if a value is a call or invoke to a library function that 191 /// \brief Tests if a value is a call or invoke to a library function that
170 /// allocates uninitialized memory (such as malloc). 192 /// allocates uninitialized memory (such as malloc).
171 bool llvm::isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, 193 bool llvm::isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
172 bool LookThroughBitCast) { 194 bool LookThroughBitCast) {
173 return getAllocationData(V, MallocLike, TLI, LookThroughBitCast); 195 return getAllocationData(V, MallocLike, TLI, LookThroughBitCast).hasValue();
174 } 196 }
175 197
176 /// \brief Tests if a value is a call or invoke to a library function that 198 /// \brief Tests if a value is a call or invoke to a library function that
177 /// allocates zero-filled memory (such as calloc). 199 /// allocates zero-filled memory (such as calloc).
178 bool llvm::isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, 200 bool llvm::isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
179 bool LookThroughBitCast) { 201 bool LookThroughBitCast) {
180 return getAllocationData(V, CallocLike, TLI, LookThroughBitCast); 202 return getAllocationData(V, CallocLike, TLI, LookThroughBitCast).hasValue();
181 } 203 }
182 204
183 /// \brief Tests if a value is a call or invoke to a library function that 205 /// \brief Tests if a value is a call or invoke to a library function that
184 /// allocates memory (either malloc, calloc, or strdup like). 206 /// allocates memory (either malloc, calloc, or strdup like).
185 bool llvm::isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI, 207 bool llvm::isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
186 bool LookThroughBitCast) { 208 bool LookThroughBitCast) {
187 return getAllocationData(V, AllocLike, TLI, LookThroughBitCast); 209 return getAllocationData(V, AllocLike, TLI, LookThroughBitCast).hasValue();
188 } 210 }
189 211
190 /// extractMallocCall - Returns the corresponding CallInst if the instruction 212 /// extractMallocCall - Returns the corresponding CallInst if the instruction
191 /// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we 213 /// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we
192 /// ignore InvokeInst here. 214 /// ignore InvokeInst here.
212 234
213 // If malloc call's arg can be determined to be a multiple of ElementSize, 235 // If malloc call's arg can be determined to be a multiple of ElementSize,
214 // return the multiple. Otherwise, return NULL. 236 // return the multiple. Otherwise, return NULL.
215 Value *MallocArg = CI->getArgOperand(0); 237 Value *MallocArg = CI->getArgOperand(0);
216 Value *Multiple = nullptr; 238 Value *Multiple = nullptr;
217 if (ComputeMultiple(MallocArg, ElementSize, Multiple, 239 if (ComputeMultiple(MallocArg, ElementSize, Multiple, LookThroughSExt))
218 LookThroughSExt))
219 return Multiple; 240 return Multiple;
220 241
221 return nullptr; 242 return nullptr;
222 } 243 }
223 244
343 364
344 365
345 //===----------------------------------------------------------------------===// 366 //===----------------------------------------------------------------------===//
346 // Utility functions to compute size of objects. 367 // Utility functions to compute size of objects.
347 // 368 //
348 369 static APInt getSizeWithOverflow(const SizeOffsetType &Data) {
370 if (Data.second.isNegative() || Data.first.ult(Data.second))
371 return APInt(Data.first.getBitWidth(), 0);
372 return Data.first - Data.second;
373 }
349 374
350 /// \brief Compute the size of the object pointed by Ptr. Returns true and the 375 /// \brief Compute the size of the object pointed by Ptr. Returns true and the
351 /// object size in Size if successful, and false otherwise. 376 /// object size in Size if successful, and false otherwise.
352 /// If RoundToAlign is true, then Size is rounded up to the aligment of allocas, 377 /// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
353 /// byval arguments, and global variables. 378 /// byval arguments, and global variables.
354 bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, 379 bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
355 const TargetLibraryInfo *TLI, bool RoundToAlign) { 380 const TargetLibraryInfo *TLI, bool RoundToAlign,
356 ObjectSizeOffsetVisitor Visitor(DL, TLI, Ptr->getContext(), RoundToAlign); 381 llvm::ObjSizeMode Mode) {
382 ObjectSizeOffsetVisitor Visitor(DL, TLI, Ptr->getContext(),
383 RoundToAlign, Mode);
357 SizeOffsetType Data = Visitor.compute(const_cast<Value*>(Ptr)); 384 SizeOffsetType Data = Visitor.compute(const_cast<Value*>(Ptr));
358 if (!Visitor.bothKnown(Data)) 385 if (!Visitor.bothKnown(Data))
359 return false; 386 return false;
360 387
361 APInt ObjSize = Data.first, Offset = Data.second; 388 Size = getSizeWithOverflow(Data).getZExtValue();
362 // check for overflow
363 if (Offset.slt(0) || ObjSize.ult(Offset))
364 Size = 0;
365 else
366 Size = (ObjSize - Offset).getZExtValue();
367 return true; 389 return true;
368 } 390 }
369
370 391
371 STATISTIC(ObjectVisitorArgument, 392 STATISTIC(ObjectVisitorArgument,
372 "Number of arguments with unsolved size and offset"); 393 "Number of arguments with unsolved size and offset");
373 STATISTIC(ObjectVisitorLoad, 394 STATISTIC(ObjectVisitorLoad,
374 "Number of load instructions with unsolved size and offset"); 395 "Number of load instructions with unsolved size and offset");
381 } 402 }
382 403
383 ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const DataLayout &DL, 404 ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const DataLayout &DL,
384 const TargetLibraryInfo *TLI, 405 const TargetLibraryInfo *TLI,
385 LLVMContext &Context, 406 LLVMContext &Context,
386 bool RoundToAlign) 407 bool RoundToAlign,
387 : DL(DL), TLI(TLI), RoundToAlign(RoundToAlign) { 408 ObjSizeMode Mode)
409 : DL(DL), TLI(TLI), RoundToAlign(RoundToAlign), Mode(Mode) {
388 // Pointer size must be rechecked for each object visited since it could have 410 // Pointer size must be rechecked for each object visited since it could have
389 // a different address space. 411 // a different address space.
390 } 412 }
391 413
392 SizeOffsetType ObjectSizeOffsetVisitor::compute(Value *V) { 414 SizeOffsetType ObjectSizeOffsetVisitor::compute(Value *V) {
441 } 463 }
442 return unknown(); 464 return unknown();
443 } 465 }
444 466
445 SizeOffsetType ObjectSizeOffsetVisitor::visitArgument(Argument &A) { 467 SizeOffsetType ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
446 // no interprocedural analysis is done at the moment 468 // No interprocedural analysis is done at the moment.
447 if (!A.hasByValOrInAllocaAttr()) { 469 if (!A.hasByValOrInAllocaAttr()) {
448 ++ObjectVisitorArgument; 470 ++ObjectVisitorArgument;
449 return unknown(); 471 return unknown();
450 } 472 }
451 PointerType *PT = cast<PointerType>(A.getType()); 473 PointerType *PT = cast<PointerType>(A.getType());
452 APInt Size(IntTyBits, DL.getTypeAllocSize(PT->getElementType())); 474 APInt Size(IntTyBits, DL.getTypeAllocSize(PT->getElementType()));
453 return std::make_pair(align(Size, A.getParamAlignment()), Zero); 475 return std::make_pair(align(Size, A.getParamAlignment()), Zero);
454 } 476 }
455 477
456 SizeOffsetType ObjectSizeOffsetVisitor::visitCallSite(CallSite CS) { 478 SizeOffsetType ObjectSizeOffsetVisitor::visitCallSite(CallSite CS) {
457 const AllocFnsTy *FnData = getAllocationData(CS.getInstruction(), AnyAlloc, 479 Optional<AllocFnsTy> FnData =
458 TLI); 480 getAllocationData(CS.getInstruction(), AnyAlloc, TLI);
459 if (!FnData) 481 if (!FnData)
460 return unknown(); 482 return unknown();
461 483
462 // handle strdup-like functions separately 484 // Handle strdup-like functions separately.
463 if (FnData->AllocTy == StrDupLike) { 485 if (FnData->AllocTy == StrDupLike) {
464 APInt Size(IntTyBits, GetStringLength(CS.getArgument(0))); 486 APInt Size(IntTyBits, GetStringLength(CS.getArgument(0)));
465 if (!Size) 487 if (!Size)
466 return unknown(); 488 return unknown();
467 489
468 // strndup limits strlen 490 // Strndup limits strlen.
469 if (FnData->FstParam > 0) { 491 if (FnData->FstParam > 0) {
470 ConstantInt *Arg= dyn_cast<ConstantInt>(CS.getArgument(FnData->FstParam)); 492 ConstantInt *Arg =
493 dyn_cast<ConstantInt>(CS.getArgument(FnData->FstParam));
471 if (!Arg) 494 if (!Arg)
472 return unknown(); 495 return unknown();
473 496
474 APInt MaxSize = Arg->getValue().zextOrSelf(IntTyBits); 497 APInt MaxSize = Arg->getValue().zextOrSelf(IntTyBits);
475 if (Size.ugt(MaxSize)) 498 if (Size.ugt(MaxSize))
480 503
481 ConstantInt *Arg = dyn_cast<ConstantInt>(CS.getArgument(FnData->FstParam)); 504 ConstantInt *Arg = dyn_cast<ConstantInt>(CS.getArgument(FnData->FstParam));
482 if (!Arg) 505 if (!Arg)
483 return unknown(); 506 return unknown();
484 507
485 APInt Size = Arg->getValue().zextOrSelf(IntTyBits); 508 // When we're compiling N-bit code, and the user uses parameters that are
486 // size determined by just 1 parameter 509 // greater than N bits (e.g. uint64_t on a 32-bit build), we can run into
510 // trouble with APInt size issues. This function handles resizing + overflow
511 // checks for us.
512 auto CheckedZextOrTrunc = [&](APInt &I) {
513 // More bits than we can handle. Checking the bit width isn't necessary, but
514 // it's faster than checking active bits, and should give `false` in the
515 // vast majority of cases.
516 if (I.getBitWidth() > IntTyBits && I.getActiveBits() > IntTyBits)
517 return false;
518 if (I.getBitWidth() != IntTyBits)
519 I = I.zextOrTrunc(IntTyBits);
520 return true;
521 };
522
523 APInt Size = Arg->getValue();
524 if (!CheckedZextOrTrunc(Size))
525 return unknown();
526
527 // Size is determined by just 1 parameter.
487 if (FnData->SndParam < 0) 528 if (FnData->SndParam < 0)
488 return std::make_pair(Size, Zero); 529 return std::make_pair(Size, Zero);
489 530
490 Arg = dyn_cast<ConstantInt>(CS.getArgument(FnData->SndParam)); 531 Arg = dyn_cast<ConstantInt>(CS.getArgument(FnData->SndParam));
491 if (!Arg) 532 if (!Arg)
492 return unknown(); 533 return unknown();
493 534
494 Size *= Arg->getValue().zextOrSelf(IntTyBits); 535 APInt NumElems = Arg->getValue();
495 return std::make_pair(Size, Zero); 536 if (!CheckedZextOrTrunc(NumElems))
537 return unknown();
538
539 bool Overflow;
540 Size = Size.umul_ov(NumElems, Overflow);
541 return Overflow ? unknown() : std::make_pair(Size, Zero);
496 542
497 // TODO: handle more standard functions (+ wchar cousins): 543 // TODO: handle more standard functions (+ wchar cousins):
498 // - strdup / strndup 544 // - strdup / strndup
499 // - strcpy / strncpy 545 // - strcpy / strncpy
500 // - strcat / strncat 546 // - strcat / strncat
527 573
528 return std::make_pair(PtrData.first, PtrData.second + Offset); 574 return std::make_pair(PtrData.first, PtrData.second + Offset);
529 } 575 }
530 576
531 SizeOffsetType ObjectSizeOffsetVisitor::visitGlobalAlias(GlobalAlias &GA) { 577 SizeOffsetType ObjectSizeOffsetVisitor::visitGlobalAlias(GlobalAlias &GA) {
532 if (GA.mayBeOverridden()) 578 if (GA.isInterposable())
533 return unknown(); 579 return unknown();
534 return compute(GA.getAliasee()); 580 return compute(GA.getAliasee());
535 } 581 }
536 582
537 SizeOffsetType ObjectSizeOffsetVisitor::visitGlobalVariable(GlobalVariable &GV){ 583 SizeOffsetType ObjectSizeOffsetVisitor::visitGlobalVariable(GlobalVariable &GV){
558 } 604 }
559 605
560 SizeOffsetType ObjectSizeOffsetVisitor::visitSelectInst(SelectInst &I) { 606 SizeOffsetType ObjectSizeOffsetVisitor::visitSelectInst(SelectInst &I) {
561 SizeOffsetType TrueSide = compute(I.getTrueValue()); 607 SizeOffsetType TrueSide = compute(I.getTrueValue());
562 SizeOffsetType FalseSide = compute(I.getFalseValue()); 608 SizeOffsetType FalseSide = compute(I.getFalseValue());
563 if (bothKnown(TrueSide) && bothKnown(FalseSide) && TrueSide == FalseSide) 609 if (bothKnown(TrueSide) && bothKnown(FalseSide)) {
564 return TrueSide; 610 if (TrueSide == FalseSide) {
611 return TrueSide;
612 }
613
614 APInt TrueResult = getSizeWithOverflow(TrueSide);
615 APInt FalseResult = getSizeWithOverflow(FalseSide);
616
617 if (TrueResult == FalseResult) {
618 return TrueSide;
619 }
620 if (Mode == ObjSizeMode::Min) {
621 if (TrueResult.slt(FalseResult))
622 return TrueSide;
623 return FalseSide;
624 }
625 if (Mode == ObjSizeMode::Max) {
626 if (TrueResult.sgt(FalseResult))
627 return TrueSide;
628 return FalseSide;
629 }
630 }
565 return unknown(); 631 return unknown();
566 } 632 }
567 633
568 SizeOffsetType ObjectSizeOffsetVisitor::visitUndefValue(UndefValue&) { 634 SizeOffsetType ObjectSizeOffsetVisitor::visitUndefValue(UndefValue&) {
569 return std::make_pair(Zero, Zero); 635 return std::make_pair(Zero, Zero);
589 Zero = ConstantInt::get(IntTy, 0); 655 Zero = ConstantInt::get(IntTy, 0);
590 656
591 SizeOffsetEvalType Result = compute_(V); 657 SizeOffsetEvalType Result = compute_(V);
592 658
593 if (!bothKnown(Result)) { 659 if (!bothKnown(Result)) {
594 // erase everything that was computed in this iteration from the cache, so 660 // Erase everything that was computed in this iteration from the cache, so
595 // that no dangling references are left behind. We could be a bit smarter if 661 // that no dangling references are left behind. We could be a bit smarter if
596 // we kept a dependency graph. It's probably not worth the complexity. 662 // we kept a dependency graph. It's probably not worth the complexity.
597 for (PtrSetTy::iterator I=SeenVals.begin(), E=SeenVals.end(); I != E; ++I) { 663 for (const Value *SeenVal : SeenVals) {
598 CacheMapTy::iterator CacheIt = CacheMap.find(*I); 664 CacheMapTy::iterator CacheIt = CacheMap.find(SeenVal);
599 // non-computable results can be safely cached 665 // non-computable results can be safely cached
600 if (CacheIt != CacheMap.end() && anyKnown(CacheIt->second)) 666 if (CacheIt != CacheMap.end() && anyKnown(CacheIt->second))
601 CacheMap.erase(CacheIt); 667 CacheMap.erase(CacheIt);
602 } 668 }
603 } 669 }
613 return std::make_pair(ConstantInt::get(Context, Const.first), 679 return std::make_pair(ConstantInt::get(Context, Const.first),
614 ConstantInt::get(Context, Const.second)); 680 ConstantInt::get(Context, Const.second));
615 681
616 V = V->stripPointerCasts(); 682 V = V->stripPointerCasts();
617 683
618 // check cache 684 // Check cache.
619 CacheMapTy::iterator CacheIt = CacheMap.find(V); 685 CacheMapTy::iterator CacheIt = CacheMap.find(V);
620 if (CacheIt != CacheMap.end()) 686 if (CacheIt != CacheMap.end())
621 return CacheIt->second; 687 return CacheIt->second;
622 688
623 // always generate code immediately before the instruction being 689 // Always generate code immediately before the instruction being
624 // processed, so that the generated code dominates the same BBs 690 // processed, so that the generated code dominates the same BBs.
625 BuilderTy::InsertPointGuard Guard(Builder); 691 BuilderTy::InsertPointGuard Guard(Builder);
626 if (Instruction *I = dyn_cast<Instruction>(V)) 692 if (Instruction *I = dyn_cast<Instruction>(V))
627 Builder.SetInsertPoint(I); 693 Builder.SetInsertPoint(I);
628 694
629 // now compute the size and offset 695 // Now compute the size and offset.
630 SizeOffsetEvalType Result; 696 SizeOffsetEvalType Result;
631 697
632 // Record the pointers that were handled in this run, so that they can be 698 // Record the pointers that were handled in this run, so that they can be
633 // cleaned later if something fails. We also use this set to break cycles that 699 // cleaned later if something fails. We also use this set to break cycles that
634 // can occur in dead code. 700 // can occur in dead code.
641 } else if (isa<Argument>(V) || 707 } else if (isa<Argument>(V) ||
642 (isa<ConstantExpr>(V) && 708 (isa<ConstantExpr>(V) &&
643 cast<ConstantExpr>(V)->getOpcode() == Instruction::IntToPtr) || 709 cast<ConstantExpr>(V)->getOpcode() == Instruction::IntToPtr) ||
644 isa<GlobalAlias>(V) || 710 isa<GlobalAlias>(V) ||
645 isa<GlobalVariable>(V)) { 711 isa<GlobalVariable>(V)) {
646 // ignore values where we cannot do more than what ObjectSizeVisitor can 712 // Ignore values where we cannot do more than ObjectSizeVisitor.
647 Result = unknown(); 713 Result = unknown();
648 } else { 714 } else {
649 DEBUG(dbgs() << "ObjectSizeOffsetEvaluator::compute() unhandled value: " 715 DEBUG(dbgs() << "ObjectSizeOffsetEvaluator::compute() unhandled value: "
650 << *V << '\n'); 716 << *V << '\n');
651 Result = unknown(); 717 Result = unknown();
668 Size = Builder.CreateMul(Size, ArraySize); 734 Size = Builder.CreateMul(Size, ArraySize);
669 return std::make_pair(Size, Zero); 735 return std::make_pair(Size, Zero);
670 } 736 }
671 737
672 SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitCallSite(CallSite CS) { 738 SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitCallSite(CallSite CS) {
673 const AllocFnsTy *FnData = getAllocationData(CS.getInstruction(), AnyAlloc, 739 Optional<AllocFnsTy> FnData =
674 TLI); 740 getAllocationData(CS.getInstruction(), AnyAlloc, TLI);
675 if (!FnData) 741 if (!FnData)
676 return unknown(); 742 return unknown();
677 743
678 // handle strdup-like functions separately 744 // Handle strdup-like functions separately.
679 if (FnData->AllocTy == StrDupLike) { 745 if (FnData->AllocTy == StrDupLike) {
680 // TODO 746 // TODO
681 return unknown(); 747 return unknown();
682 } 748 }
683 749
729 SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitLoadInst(LoadInst&) { 795 SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitLoadInst(LoadInst&) {
730 return unknown(); 796 return unknown();
731 } 797 }
732 798
733 SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitPHINode(PHINode &PHI) { 799 SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitPHINode(PHINode &PHI) {
734 // create 2 PHIs: one for size and another for offset 800 // Create 2 PHIs: one for size and another for offset.
735 PHINode *SizePHI = Builder.CreatePHI(IntTy, PHI.getNumIncomingValues()); 801 PHINode *SizePHI = Builder.CreatePHI(IntTy, PHI.getNumIncomingValues());
736 PHINode *OffsetPHI = Builder.CreatePHI(IntTy, PHI.getNumIncomingValues()); 802 PHINode *OffsetPHI = Builder.CreatePHI(IntTy, PHI.getNumIncomingValues());
737 803
738 // insert right away in the cache to handle recursive PHIs 804 // Insert right away in the cache to handle recursive PHIs.
739 CacheMap[&PHI] = std::make_pair(SizePHI, OffsetPHI); 805 CacheMap[&PHI] = std::make_pair(SizePHI, OffsetPHI);
740 806
741 // compute offset/size for each PHI incoming pointer 807 // Compute offset/size for each PHI incoming pointer.
742 for (unsigned i = 0, e = PHI.getNumIncomingValues(); i != e; ++i) { 808 for (unsigned i = 0, e = PHI.getNumIncomingValues(); i != e; ++i) {
743 Builder.SetInsertPoint(&*PHI.getIncomingBlock(i)->getFirstInsertionPt()); 809 Builder.SetInsertPoint(&*PHI.getIncomingBlock(i)->getFirstInsertionPt());
744 SizeOffsetEvalType EdgeData = compute_(PHI.getIncomingValue(i)); 810 SizeOffsetEvalType EdgeData = compute_(PHI.getIncomingValue(i));
745 811
746 if (!bothKnown(EdgeData)) { 812 if (!bothKnown(EdgeData)) {