Change GetPointerBaseWithConstantOffset's DataLayout argument from a

reference to a pointer, so that it can handle the case where DataLayout
is not available and behave conservatively.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174024 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman
2013-01-31 02:00:45 +00:00
parent 8ed701da9a
commit a070d2a035
8 changed files with 60 additions and 61 deletions

View File

@@ -412,51 +412,49 @@ void Lint::visitMemoryReference(Instruction &I,
}
// Check for buffer overflows and misalignment.
if (TD) {
// 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, *TD)) {
// 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;
// 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, TD)) {
// 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 (!AI->isArrayAllocation() && ATy->isSized())
BaseSize = TD->getTypeAllocSize(ATy);
BaseAlign = AI->getAlignment();
if (BaseAlign == 0 && ATy->isSized())
BaseAlign = TD->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 (GTy->isSized())
BaseSize = TD->getTypeAllocSize(GTy);
BaseAlign = GV->getAlignment();
if (BaseAlign == 0 && GTy->isSized())
BaseAlign = TD->getABITypeAlignment(GTy);
}
if (AllocaInst *AI = dyn_cast<AllocaInst>(Base)) {
Type *ATy = AI->getAllocatedType();
if (TD && !AI->isArrayAllocation() && ATy->isSized())
BaseSize = TD->getTypeAllocSize(ATy);
BaseAlign = AI->getAlignment();
if (TD && BaseAlign == 0 && ATy->isSized())
BaseAlign = TD->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 (TD && GTy->isSized())
BaseSize = TD->getTypeAllocSize(GTy);
BaseAlign = GV->getAlignment();
if (TD && BaseAlign == 0 && GTy->isSized())
BaseAlign = TD->getABITypeAlignment(GTy);
}
// Accesses from before the start or after the end of the object are not
// defined.
Assert1(Size == AliasAnalysis::UnknownSize ||
BaseSize == AliasAnalysis::UnknownSize ||
(Offset >= 0 && Offset + Size <= BaseSize),
"Undefined behavior: Buffer overflow", &I);
// Accesses that say that the memory is more aligned than it is are not
// defined.
if (Align == 0 && Ty && Ty->isSized())
Align = TD->getABITypeAlignment(Ty);
Assert1(!BaseAlign || Align <= MinAlign(BaseAlign, Offset),
"Undefined behavior: Memory reference address is misaligned", &I);
}
// Accesses from before the start or after the end of the object are not
// defined.
Assert1(Size == AliasAnalysis::UnknownSize ||
BaseSize == AliasAnalysis::UnknownSize ||
(Offset >= 0 && Offset + Size <= BaseSize),
"Undefined behavior: Buffer overflow", &I);
// Accesses that say that the memory is more aligned than it is are not
// defined.
if (TD && Align == 0 && Ty && Ty->isSized())
Align = TD->getABITypeAlignment(Ty);
Assert1(!BaseAlign || Align <= MinAlign(BaseAlign, Offset),
"Undefined behavior: Memory reference address is misaligned", &I);
}
}