aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Analysis/Lint.cpp24
-rw-r--r--test/Other/lint.ll8
2 files changed, 24 insertions, 8 deletions
diff --git a/lib/Analysis/Lint.cpp b/lib/Analysis/Lint.cpp
index 83bdf52..6e765a7 100644
--- a/lib/Analysis/Lint.cpp
+++ b/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);
+ }
}
}
}
diff --git a/test/Other/lint.ll b/test/Other/lint.ll
index c84f56f..f6787e9 100644
--- a/test/Other/lint.ll
+++ b/test/Other/lint.ll
@@ -11,6 +11,8 @@ declare void @one_arg(i32)
@CG = constant i32 7
define i32 @foo() noreturn {
+ %buf = alloca i8
+ %buf2 = alloca {i8, i8}, align 2
; CHECK: Caller and callee calling convention differ
call void @bar()
; CHECK: Null pointer dereference
@@ -26,8 +28,10 @@ define i32 @foo() noreturn {
; CHECK: Address one pointer dereference
store i32 0, i32* inttoptr (i64 1 to i32*)
; CHECK: Memory reference address is misaligned
- %x = inttoptr i32 1 to i32*
- load i32* %x, align 4
+ store i8 0, i8* %buf, align 2
+; CHECK: Memory reference address is misaligned
+ %gep = getelementptr {i8, i8}* %buf2, i32 0, i32 1
+ store i8 0, i8* %gep, align 2
; CHECK: Division by zero
%sd = sdiv i32 2, 0
; CHECK: Division by zero