summaryrefslogtreecommitdiffstats
path: root/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2012-05-03 16:50:55 +0000
committerdim <dim@FreeBSD.org>2012-05-03 16:50:55 +0000
commit2c5e9d71aba3b1a85f07c08d2c09d40b8547264b (patch)
tree8575c732129e272992ac5d7b4c2519238fff4735 /lib/Analysis/ConstantFolding.cpp
parent1fc08f5e9ef733ef1ce6f363fecedc2260e78974 (diff)
downloadFreeBSD-src-2c5e9d71aba3b1a85f07c08d2c09d40b8547264b.zip
FreeBSD-src-2c5e9d71aba3b1a85f07c08d2c09d40b8547264b.tar.gz
Vendor import of llvm release_31 branch r155985:
http://llvm.org/svn/llvm-project/llvm/branches/release_31@155985
Diffstat (limited to 'lib/Analysis/ConstantFolding.cpp')
-rw-r--r--lib/Analysis/ConstantFolding.cpp14
1 files changed, 11 insertions, 3 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index 7a0a4e1e..783c32e 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -681,6 +681,7 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
// This makes it easy to determine if the getelementptr is "inbounds".
// Also, this helps GlobalOpt do SROA on GlobalVariables.
Type *Ty = Ptr->getType();
+ assert(Ty->isPointerTy() && "Forming regular GEP of non-pointer type");
SmallVector<Constant*, 32> NewIdxs;
do {
if (SequentialType *ATy = dyn_cast<SequentialType>(Ty)) {
@@ -711,10 +712,17 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
}
Ty = ATy->getElementType();
} else if (StructType *STy = dyn_cast<StructType>(Ty)) {
- // Determine which field of the struct the offset points into. The
- // getZExtValue is at least as safe as the StructLayout API because we
- // know the offset is within the struct at this point.
+ // If we end up with an offset that isn't valid for this struct type, we
+ // can't re-form this GEP in a regular form, so bail out. The pointer
+ // operand likely went through casts that are necessary to make the GEP
+ // sensible.
const StructLayout &SL = *TD->getStructLayout(STy);
+ if (Offset.uge(SL.getSizeInBytes()))
+ break;
+
+ // Determine which field of the struct the offset points into. The
+ // getZExtValue is fine as we've already ensured that the offset is
+ // within the range representable by the StructLayout API.
unsigned ElIdx = SL.getElementContainingOffset(Offset.getZExtValue());
NewIdxs.push_back(ConstantInt::get(Type::getInt32Ty(Ty->getContext()),
ElIdx));
OpenPOWER on IntegriCloud