- if (TD) {
- if (Align == 0 && Ty) Align = TD->getABITypeAlignment(Ty);
-
- if (Align != 0) {
- unsigned BitWidth = TD->getTypeSizeInBits(Ptr->getType());
- APInt Mask = APInt::getAllOnesValue(BitWidth),
- KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
- ComputeMaskedBits(Ptr, Mask, KnownZero, KnownOne, TD);
- Assert1(!(KnownOne & APInt::getLowBitsSet(BitWidth, Log2_32(Align))),
- "Undefined behavior: Memory reference address is misaligned", &I);
+ // Check for buffer overflows and misalignment.
+ // Only handles memory references that read/write something simple like an
+ // alloca instruction or a global variable.
+ int64_t Offset = 0;
+ if (Value *Base = GetPointerBaseWithConstantOffset(Ptr, Offset, DL)) {
+ // OK, so the access is to a constant offset from Ptr. Check that Ptr is
+ // something we can handle and if so extract the size of this base object
+ // along with its alignment.
+ uint64_t BaseSize = AliasAnalysis::UnknownSize;
+ unsigned BaseAlign = 0;
+
+ if (AllocaInst *AI = dyn_cast<AllocaInst>(Base)) {
+ Type *ATy = AI->getAllocatedType();
+ if (DL && !AI->isArrayAllocation() && ATy->isSized())
+ BaseSize = DL->getTypeAllocSize(ATy);
+ BaseAlign = AI->getAlignment();
+ if (DL && BaseAlign == 0 && ATy->isSized())
+ BaseAlign = DL->getABITypeAlignment(ATy);
+ } else if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
+ // If the global may be defined differently in another compilation unit
+ // then don't warn about funky memory accesses.
+ if (GV->hasDefinitiveInitializer()) {
+ Type *GTy = GV->getType()->getElementType();
+ if (DL && GTy->isSized())
+ BaseSize = DL->getTypeAllocSize(GTy);
+ BaseAlign = GV->getAlignment();
+ if (DL && BaseAlign == 0 && GTy->isSized())
+ BaseAlign = DL->getABITypeAlignment(GTy);
+ }