@@ -305,6 +305,85 @@ Value *llvm::getAllocAlignment(const CallBase *V,
305
305
return V->getOperand (FnData->AlignParam );
306
306
}
307
307
308
+ // / When we're compiling N-bit code, and the user uses parameters that are
309
+ // / greater than N bits (e.g. uint64_t on a 32-bit build), we can run into
310
+ // / trouble with APInt size issues. This function handles resizing + overflow
311
+ // / checks for us. Check and zext or trunc \p I depending on IntTyBits and
312
+ // / I's value.
313
+ static bool CheckedZextOrTrunc (APInt &I, unsigned IntTyBits) {
314
+ // More bits than we can handle. Checking the bit width isn't necessary, but
315
+ // it's faster than checking active bits, and should give `false` in the
316
+ // vast majority of cases.
317
+ if (I.getBitWidth () > IntTyBits && I.getActiveBits () > IntTyBits)
318
+ return false ;
319
+ if (I.getBitWidth () != IntTyBits)
320
+ I = I.zextOrTrunc (IntTyBits);
321
+ return true ;
322
+ }
323
+
324
+ Optional<APInt>
325
+ llvm::getAllocSize (const CallBase *CB,
326
+ const TargetLibraryInfo *TLI,
327
+ std::function<const Value*(const Value*)> Mapper) {
328
+ // Note: This handles both explicitly listed allocation functions and
329
+ // allocsize. The code structure could stand to be cleaned up a bit.
330
+ Optional<AllocFnsTy> FnData = getAllocationSize (CB, TLI);
331
+ if (!FnData)
332
+ return None;
333
+
334
+ // Get the index type for this address space, results and intermediate
335
+ // computations are performed at that width.
336
+ auto &DL = CB->getModule ()->getDataLayout ();
337
+ const unsigned IntTyBits = DL.getIndexTypeSizeInBits (CB->getType ());
338
+
339
+ // Handle strdup-like functions separately.
340
+ if (FnData->AllocTy == StrDupLike) {
341
+ APInt Size (IntTyBits, GetStringLength (Mapper (CB->getArgOperand (0 ))));
342
+ if (!Size)
343
+ return None;
344
+
345
+ // Strndup limits strlen.
346
+ if (FnData->FstParam > 0 ) {
347
+ const ConstantInt *Arg =
348
+ dyn_cast<ConstantInt>(Mapper (CB->getArgOperand (FnData->FstParam )));
349
+ if (!Arg)
350
+ return None;
351
+
352
+ APInt MaxSize = Arg->getValue ().zextOrSelf (IntTyBits);
353
+ if (Size.ugt (MaxSize))
354
+ Size = MaxSize + 1 ;
355
+ }
356
+ return Size;
357
+ }
358
+
359
+ const ConstantInt *Arg =
360
+ dyn_cast<ConstantInt>(Mapper (CB->getArgOperand (FnData->FstParam )));
361
+ if (!Arg)
362
+ return None;
363
+
364
+ APInt Size = Arg->getValue ();
365
+ if (!CheckedZextOrTrunc (Size, IntTyBits))
366
+ return None;
367
+
368
+ // Size is determined by just 1 parameter.
369
+ if (FnData->SndParam < 0 )
370
+ return Size;
371
+
372
+ Arg = dyn_cast<ConstantInt>(Mapper (CB->getArgOperand (FnData->SndParam )));
373
+ if (!Arg)
374
+ return None;
375
+
376
+ APInt NumElems = Arg->getValue ();
377
+ if (!CheckedZextOrTrunc (NumElems, IntTyBits))
378
+ return None;
379
+
380
+ bool Overflow;
381
+ Size = Size.umul_ov (NumElems, Overflow);
382
+ if (Overflow)
383
+ return None;
384
+ return Size;
385
+ }
386
+
308
387
Constant *llvm::getInitialValueOfAllocation (const CallBase *Alloc,
309
388
const TargetLibraryInfo *TLI,
310
389
Type *Ty) {
@@ -535,20 +614,8 @@ SizeOffsetType ObjectSizeOffsetVisitor::compute(Value *V) {
535
614
return unknown ();
536
615
}
537
616
538
- // / When we're compiling N-bit code, and the user uses parameters that are
539
- // / greater than N bits (e.g. uint64_t on a 32-bit build), we can run into
540
- // / trouble with APInt size issues. This function handles resizing + overflow
541
- // / checks for us. Check and zext or trunc \p I depending on IntTyBits and
542
- // / I's value.
543
617
bool ObjectSizeOffsetVisitor::CheckedZextOrTrunc (APInt &I) {
544
- // More bits than we can handle. Checking the bit width isn't necessary, but
545
- // it's faster than checking active bits, and should give `false` in the
546
- // vast majority of cases.
547
- if (I.getBitWidth () > IntTyBits && I.getActiveBits () > IntTyBits)
548
- return false ;
549
- if (I.getBitWidth () != IntTyBits)
550
- I = I.zextOrTrunc (IntTyBits);
551
- return true ;
618
+ return ::CheckedZextOrTrunc (I, IntTyBits);
552
619
}
553
620
554
621
SizeOffsetType ObjectSizeOffsetVisitor::visitAllocaInst (AllocaInst &I) {
@@ -589,53 +656,10 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
589
656
}
590
657
591
658
SizeOffsetType ObjectSizeOffsetVisitor::visitCallBase (CallBase &CB) {
592
- Optional<AllocFnsTy> FnData = getAllocationSize (&CB, TLI);
593
- if (!FnData)
594
- return unknown ();
595
-
596
- // Handle strdup-like functions separately.
597
- if (FnData->AllocTy == StrDupLike) {
598
- APInt Size (IntTyBits, GetStringLength (CB.getArgOperand (0 )));
599
- if (!Size)
600
- return unknown ();
601
-
602
- // Strndup limits strlen.
603
- if (FnData->FstParam > 0 ) {
604
- ConstantInt *Arg =
605
- dyn_cast<ConstantInt>(CB.getArgOperand (FnData->FstParam ));
606
- if (!Arg)
607
- return unknown ();
608
-
609
- APInt MaxSize = Arg->getValue ().zextOrSelf (IntTyBits);
610
- if (Size.ugt (MaxSize))
611
- Size = MaxSize + 1 ;
612
- }
613
- return std::make_pair (Size, Zero);
614
- }
615
-
616
- ConstantInt *Arg = dyn_cast<ConstantInt>(CB.getArgOperand (FnData->FstParam ));
617
- if (!Arg)
618
- return unknown ();
619
-
620
- APInt Size = Arg->getValue ();
621
- if (!CheckedZextOrTrunc (Size))
622
- return unknown ();
623
-
624
- // Size is determined by just 1 parameter.
625
- if (FnData->SndParam < 0 )
626
- return std::make_pair (Size, Zero);
627
-
628
- Arg = dyn_cast<ConstantInt>(CB.getArgOperand (FnData->SndParam ));
629
- if (!Arg)
630
- return unknown ();
631
-
632
- APInt NumElems = Arg->getValue ();
633
- if (!CheckedZextOrTrunc (NumElems))
634
- return unknown ();
635
-
636
- bool Overflow;
637
- Size = Size.umul_ov (NumElems, Overflow);
638
- return Overflow ? unknown () : std::make_pair (Size, Zero);
659
+ auto Mapper = [](const Value *V) { return V; };
660
+ if (Optional<APInt> Size = getAllocSize (&CB, TLI, Mapper))
661
+ return std::make_pair (*Size, Zero);
662
+ return unknown ();
639
663
}
640
664
641
665
SizeOffsetType
0 commit comments