diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-02-16 04:02:09 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-02-16 04:02:09 +0000 |
commit | 9b529a76e9c607f2715529abe1cc9c2cffa35563 (patch) | |
tree | d2adf38680fd5073fb4a69d327dd8a2a221dc3ba /llvm/lib/IR/Constants.cpp | |
parent | 7540eafb5c5f5b31436800dc6345f7b39d174e97 (diff) | |
download | bcm5719-llvm-9b529a76e9c607f2715529abe1cc9c2cffa35563.tar.gz bcm5719-llvm-9b529a76e9c607f2715529abe1cc9c2cffa35563.zip |
IR: Properly return nullptr when getAggregateElement is out-of-bounds
We didn't properly handle the out-of-bounds case for
ConstantAggregateZero and UndefValue. This would manifest as a crash
when the constant folder was asked to fold a load of a constant global
whose struct type has no operands.
This fixes PR22595.
llvm-svn: 229352
Diffstat (limited to 'llvm/lib/IR/Constants.cpp')
-rw-r--r-- | llvm/lib/IR/Constants.cpp | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index 1d2602aef13..44052b22457 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -257,11 +257,11 @@ Constant *Constant::getAggregateElement(unsigned Elt) const { if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) return Elt < CV->getNumOperands() ? CV->getOperand(Elt) : nullptr; - if (const ConstantAggregateZero *CAZ =dyn_cast<ConstantAggregateZero>(this)) - return CAZ->getElementValue(Elt); + if (const ConstantAggregateZero *CAZ = dyn_cast<ConstantAggregateZero>(this)) + return Elt < CAZ->getNumElements() ? CAZ->getElementValue(Elt) : nullptr; if (const UndefValue *UV = dyn_cast<UndefValue>(this)) - return UV->getElementValue(Elt); + return Elt < UV->getNumElements() ? UV->getElementValue(Elt) : nullptr; if (const ConstantDataSequential *CDS =dyn_cast<ConstantDataSequential>(this)) return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt) @@ -764,6 +764,14 @@ Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const { return getStructElement(Idx); } +unsigned ConstantAggregateZero::getNumElements() const { + const Type *Ty = getType(); + if (const auto *AT = dyn_cast<ArrayType>(Ty)) + return AT->getNumElements(); + if (const auto *VT = dyn_cast<VectorType>(Ty)) + return VT->getNumElements(); + return Ty->getStructNumElements(); +} //===----------------------------------------------------------------------===// // UndefValue Implementation @@ -797,7 +805,14 @@ UndefValue *UndefValue::getElementValue(unsigned Idx) const { return getStructElement(Idx); } - +unsigned UndefValue::getNumElements() const { + const Type *Ty = getType(); + if (const auto *AT = dyn_cast<ArrayType>(Ty)) + return AT->getNumElements(); + if (const auto *VT = dyn_cast<VectorType>(Ty)) + return VT->getNumElements(); + return Ty->getStructNumElements(); +} //===----------------------------------------------------------------------===// // ConstantXXX Classes |