From: Frits van Bommel Date: Sun, 5 Dec 2010 20:50:26 +0000 (+0000) Subject: Fix PR 4170 by having ExtractValueInst::getIndexedType() reject out-of-bounds indexing. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=a4805cf6efbcd405916cdd0eb4b6170231e906c7;p=oota-llvm.git Fix PR 4170 by having ExtractValueInst::getIndexedType() reject out-of-bounds indexing. Also add asserts that the indices are valid in InsertValueInst::init(). ExtractValueInst already asserts when constructed with invalid indices. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120956 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index d8130d41f9a..1892c009e22 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -1424,6 +1424,8 @@ int ShuffleVectorInst::getMaskValue(unsigned i) const { void InsertValueInst::init(Value *Agg, Value *Val, const unsigned *Idx, unsigned NumIdx, const Twine &Name) { assert(NumOperands == 2 && "NumOperands not initialized?"); + assert(ExtractValueInst::getIndexedType(Agg->getType(), Idx, Idx + NumIdx) == + Val->getType() && "Inserted value must match indexed type!"); Op<0>() = Agg; Op<1>() = Val; @@ -1434,6 +1436,8 @@ void InsertValueInst::init(Value *Agg, Value *Val, const unsigned *Idx, void InsertValueInst::init(Value *Agg, Value *Val, unsigned Idx, const Twine &Name) { assert(NumOperands == 2 && "NumOperands not initialized?"); + assert(ExtractValueInst::getIndexedType(Agg->getType(), Idx) == Val->getType() + && "Inserted value must match indexed type!"); Op<0>() = Agg; Op<1>() = Val; @@ -1506,13 +1510,26 @@ ExtractValueInst::ExtractValueInst(const ExtractValueInst &EVI) const Type* ExtractValueInst::getIndexedType(const Type *Agg, const unsigned *Idxs, unsigned NumIdx) { - unsigned CurIdx = 0; - for (; CurIdx != NumIdx; ++CurIdx) { - const CompositeType *CT = dyn_cast(Agg); - if (!CT || CT->isPointerTy() || CT->isVectorTy()) return 0; + for (unsigned CurIdx = 0; CurIdx != NumIdx; ++CurIdx) { unsigned Index = Idxs[CurIdx]; - if (!CT->indexValid(Index)) return 0; - Agg = CT->getTypeAtIndex(Index); + // We can't use CompositeType::indexValid(Index) here. + // indexValid() always returns true for arrays because getelementptr allows + // out-of-bounds indices. Since we don't allow those for extractvalue and + // insertvalue we need to check array indexing manually. + // Since the only other types we can index into are struct types it's just + // as easy to check those manually as well. + if (const ArrayType *AT = dyn_cast(Agg)) { + if (Index >= AT->getNumElements()) + return 0; + } else if (const StructType *ST = dyn_cast(Agg)) { + if (Index >= ST->getNumElements()) + return 0; + } else { + // Not a valid type to index into. + return 0; + } + + Agg = cast(Agg)->getTypeAtIndex(Index); // If the new type forwards to another type, then it is in the middle // of being refined to another type (and hence, may have dropped all @@ -1521,7 +1538,7 @@ const Type* ExtractValueInst::getIndexedType(const Type *Agg, if (const Type *Ty = Agg->getForwardedType()) Agg = Ty; } - return CurIdx == NumIdx ? Agg : 0; + return Agg; } const Type* ExtractValueInst::getIndexedType(const Type *Agg, diff --git a/test/Assembler/extractvalue-invalid-idx.ll b/test/Assembler/extractvalue-invalid-idx.ll new file mode 100644 index 00000000000..f9644eadbd5 --- /dev/null +++ b/test/Assembler/extractvalue-invalid-idx.ll @@ -0,0 +1,8 @@ +; RUN: not llvm-as < %s |& grep {invalid indices for extractvalue} +; PR4170 + +define void @test() { +entry: + extractvalue [0 x i32] undef, 0 + ret void +} diff --git a/test/Assembler/insertvalue-invalid-idx.ll b/test/Assembler/insertvalue-invalid-idx.ll new file mode 100644 index 00000000000..86e7258cc59 --- /dev/null +++ b/test/Assembler/insertvalue-invalid-idx.ll @@ -0,0 +1,7 @@ +; RUN: not llvm-as < %s |& grep {invalid indices for insertvalue} + +define void @test() { +entry: + insertvalue [0 x i32] undef, i32 0, 0 + ret void +}