From 920bd79f344acfabe23c8fb00363c58532426753 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 2 Jun 2003 05:42:39 +0000 Subject: [PATCH] Be more robust in the face of undefined behavior. Fixes bug: BasicAA/2003-06-01-AliasCrash.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6538 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/BasicAliasAnalysis.cpp | 35 ++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index cdf6f6dc44e..42d00c2b605 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -182,6 +182,22 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size, return MayAlias; } +static Value *CheckArrayIndicesForOverflow(const Type *PtrTy, + const std::vector &Indices, + const ConstantInt *Idx) { + if (const ConstantSInt *IdxS = dyn_cast(Idx)) { + if (IdxS->getValue() < 0) // Underflow on the array subscript? + return Constant::getNullValue(Type::LongTy); + else { // Check for overflow + const ArrayType *ATy = + cast(GetElementPtrInst::getIndexedType(PtrTy, Indices,true)); + if (IdxS->getValue() >= (int64_t)ATy->getNumElements()) + return ConstantSInt::get(Type::LongTy, ATy->getNumElements()-1); + } + } + return (Value*)Idx; // Everything is acceptable. +} + // CheckGEPInstructions - Check two GEP instructions of compatible types and // equal number of arguments. This checks to see if the index expressions // preclude the pointers from aliasing... @@ -214,7 +230,7 @@ BasicAliasAnalysis::CheckGEPInstructions(GetElementPtrInst *GEP1, unsigned G1S, // unsigned SizeMax = std::max(G1S, G2S); if (SizeMax == ~0U) return MayAlias; // Avoid frivolous work... - + // Scan for the first operand that is constant and unequal in the // two getelemenptrs... unsigned FirstConstantOper = UnequalOper; @@ -262,16 +278,20 @@ BasicAliasAnalysis::CheckGEPInstructions(GetElementPtrInst *GEP1, unsigned G1S, const Type *GEPPointerTy = GEP1->getOperand(0)->getType(); // Loop over the rest of the operands... - for (unsigned i = FirstConstantOper+1; i!=NumGEPOperands; ++i){ + for (unsigned i = FirstConstantOper+1; i != NumGEPOperands; ++i) { const Value *Op1 = GEP1->getOperand(i); const Value *Op2 = GEP2->getOperand(i); if (Op1 == Op2) { // If they are equal, use a zero index... Indices1.push_back(Constant::getNullValue(Op1->getType())); Indices2.push_back(Indices1.back()); } else { - if (isa(Op1)) + if (const ConstantInt *Op1C = dyn_cast(Op1)) { + // If this is an array index, make sure the array element is in range... + if (i != 1) // The pointer index can be "out of range" + Op1 = CheckArrayIndicesForOverflow(GEPPointerTy, Indices1, Op1C); + Indices1.push_back((Value*)Op1); - else { + } else { // GEP1 is known to produce a value less than GEP2. To be // conservatively correct, we must assume the largest possible constant // is used in this position. This cannot be the initial index to the @@ -287,8 +307,13 @@ BasicAliasAnalysis::CheckGEPInstructions(GetElementPtrInst *GEP1, unsigned G1S, ElTy->getNumElements()-1)); } - if (isa(Op2)) + if (const ConstantInt *Op1C = dyn_cast(Op2)) { + // If this is an array index, make sure the array element is in range... + if (i != 1) // The pointer index can be "out of range" + Op1 = CheckArrayIndicesForOverflow(GEPPointerTy, Indices2, Op1C); + Indices2.push_back((Value*)Op2); + } else // Conservatively assume the minimum value for this index Indices2.push_back(Constant::getNullValue(Op2->getType())); }