diff options
author | Frits van Bommel <fvbommel@gmail.com> | 2010-12-05 20:50:26 +0000 |
---|---|---|
committer | Frits van Bommel <fvbommel@gmail.com> | 2010-12-05 20:50:26 +0000 |
commit | a4805cf6efbcd405916cdd0eb4b6170231e906c7 (patch) | |
tree | 7f10020b63a6676f0387f7ed29f10a39c79c4b28 | |
parent | 120188605fd1e3228c65daf2c5cd6c7a62d6a335 (diff) | |
download | external_llvm-a4805cf6efbcd405916cdd0eb4b6170231e906c7.zip external_llvm-a4805cf6efbcd405916cdd0eb4b6170231e906c7.tar.gz external_llvm-a4805cf6efbcd405916cdd0eb4b6170231e906c7.tar.bz2 |
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
-rw-r--r-- | lib/VMCore/Instructions.cpp | 31 | ||||
-rw-r--r-- | test/Assembler/extractvalue-invalid-idx.ll | 8 | ||||
-rw-r--r-- | test/Assembler/insertvalue-invalid-idx.ll | 7 |
3 files changed, 39 insertions, 7 deletions
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index d8130d4..1892c00 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<CompositeType>(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<ArrayType>(Agg)) { + if (Index >= AT->getNumElements()) + return 0; + } else if (const StructType *ST = dyn_cast<StructType>(Agg)) { + if (Index >= ST->getNumElements()) + return 0; + } else { + // Not a valid type to index into. + return 0; + } + + Agg = cast<CompositeType>(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 0000000..f9644ea --- /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 0000000..86e7258 --- /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 +} |