diff options
author | Tom Stellard <thomas.stellard@amd.com> | 2015-03-17 18:09:58 +0000 |
---|---|---|
committer | Tom Stellard <thomas.stellard@amd.com> | 2015-03-17 18:09:58 +0000 |
commit | 3f8396f9ba6a7aed66bb020ad589f2f59e30c3ec (patch) | |
tree | f33f3baf5c5df4b4ec3d1dc4501fd6066e624e09 | |
parent | a3bab355fb9502daea77934636ec794ec9f28ebb (diff) | |
download | llvm-3f8396f9ba6a7aed66bb020ad589f2f59e30c3ec.tar.gz |
Merging r229352:
------------------------------------------------------------------------
r229352 | david.majnemer | 2015-02-15 23:02:09 -0500 (Sun, 15 Feb 2015) | 9 lines
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.
------------------------------------------------------------------------
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_35@232512 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/IR/Constants.h | 6 | ||||
-rw-r--r-- | lib/IR/Constants.cpp | 23 | ||||
-rw-r--r-- | test/Transforms/InstSimplify/load.ll | 19 |
3 files changed, 44 insertions, 4 deletions
diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h index 0e72f040d3e0..3cf31c475b95 100644 --- a/include/llvm/IR/Constants.h +++ b/include/llvm/IR/Constants.h @@ -326,6 +326,9 @@ public: /// index. Constant *getElementValue(unsigned Idx) const; + /// \brief Return the number of elements in the array, vector, or struct. + unsigned getNumElements() const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: /// static bool classof(const Value *V) { @@ -1164,6 +1167,9 @@ public: /// index. UndefValue *getElementValue(unsigned Idx) const; + /// \brief Return the number of elements in the array, vector, or struct. + unsigned getNumElements() const; + void destroyConstant() override; /// Methods for support type inquiry through isa, cast, and dyn_cast: diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp index b815936ac428..7557886181e9 100644 --- a/lib/IR/Constants.cpp +++ b/lib/IR/Constants.cpp @@ -212,11 +212,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) @@ -721,6 +721,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 @@ -754,7 +762,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 diff --git a/test/Transforms/InstSimplify/load.ll b/test/Transforms/InstSimplify/load.ll new file mode 100644 index 000000000000..92953cd0ebfb --- /dev/null +++ b/test/Transforms/InstSimplify/load.ll @@ -0,0 +1,19 @@ +; RUN: opt < %s -instsimplify -S | FileCheck %s + +@zeroinit = constant {} zeroinitializer +@undef = constant {} undef + +define i32 @crash_on_zeroinit() { +; CHECK-LABEL: @crash_on_zeroinit +; CHECK: ret i32 0 + %load = load i32* bitcast ({}* @zeroinit to i32*) + ret i32 %load +} + +define i32 @crash_on_undef() { +; CHECK-LABEL: @crash_on_undef +; CHECK: ret i32 undef + %load = load i32* bitcast ({}* @undef to i32*) + ret i32 %load +} + |