summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/Lint.cpp
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2012-09-25 10:00:49 +0000
committerDuncan Sands <baldrick@free.fr>2012-09-25 10:00:49 +0000
commit3f4d0b17246e70dba8978d668e80b57641ddc5b8 (patch)
treed9e1dd1175cb21653bcb21543466930d58509c16 /llvm/lib/Analysis/Lint.cpp
parent924ce0d9aa8f5dca78cde7eee3f90eb3cb9be15f (diff)
downloadbcm5719-llvm-3f4d0b17246e70dba8978d668e80b57641ddc5b8.tar.gz
bcm5719-llvm-3f4d0b17246e70dba8978d668e80b57641ddc5b8.zip
Change the way the lint sanity checking pass detects misaligned memory accesses.
Previously it was only be able to detect problems if the pointer was a numerical value (eg inttoptr i32 1 to i32*), but not if it was an alloca or globa. The reason was the use of ComputeMaskedBits: imagine you have "alloca i8, align 2", and ask ComputeMaskedBits what it knows about the bits of the alloca pointer. It can tell you that the bottom bit is known zero (due to align 2) but it can't tell you that bit 1 is known one. That's because the address could be an even multiple of 2 rather than an odd multiple, eg it might be a multiple of 4. Thus trying to use KnownOne is ineffective in the case of an alloca as it will never have any bits set. Instead look explicitly for constant offsets from allocas and globals. llvm-svn: 164595
Diffstat (limited to 'llvm/lib/Analysis/Lint.cpp')
-rw-r--r--llvm/lib/Analysis/Lint.cpp24
1 files changed, 18 insertions, 6 deletions
diff --git a/llvm/lib/Analysis/Lint.cpp b/llvm/lib/Analysis/Lint.cpp
index 83bdf5286ad..6e765a7fdea 100644
--- a/llvm/lib/Analysis/Lint.cpp
+++ b/llvm/lib/Analysis/Lint.cpp
@@ -412,14 +412,26 @@ void Lint::visitMemoryReference(Instruction &I,
}
if (TD) {
- if (Align == 0 && Ty) Align = TD->getABITypeAlignment(Ty);
+ if (Align == 0 && Ty && Ty->isSized())
+ Align = TD->getABITypeAlignment(Ty);
if (Align != 0) {
- unsigned BitWidth = TD->getTypeSizeInBits(Ptr->getType());
- APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
- ComputeMaskedBits(Ptr, KnownZero, KnownOne, TD);
- Assert1(!(KnownOne & APInt::getLowBitsSet(BitWidth, Log2_32(Align))),
- "Undefined behavior: Memory reference address is misaligned", &I);
+ int64_t Offset = 0;
+ if (Value *Base = GetPointerBaseWithConstantOffset(Ptr, Offset, *TD)) {
+ unsigned BaseAlign = 0;
+ if (AllocaInst *AI = dyn_cast<AllocaInst>(Base)) {
+ BaseAlign = AI->getAlignment();
+ if (BaseAlign == 0 && AI->getAllocatedType()->isSized())
+ BaseAlign = TD->getABITypeAlignment(AI->getAllocatedType());
+ } else if (GlobalValue *GV = dyn_cast<GlobalVariable>(Base)) {
+ BaseAlign = GV->getAlignment();
+ if (BaseAlign == 0 && GV->getType()->getElementType()->isSized())
+ BaseAlign = TD->getABITypeAlignment(GV->getType()->getElementType());
+ }
+ Assert1((!BaseAlign || Align <= MinAlign(BaseAlign, Offset)),
+ "Undefined behavior: Memory reference address is misaligned",
+ &I);
+ }
}
}
}
OpenPOWER on IntegriCloud