llvm.org GIT mirror llvm / 6de0a12
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/trunk@229352 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 4 years ago
3 changed file(s) with 44 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
323323 /// getElementValue - Return a zero of the right value for the specified GEP
324324 /// index.
325325 Constant *getElementValue(unsigned Idx) const;
326
327 /// \brief Return the number of elements in the array, vector, or struct.
328 unsigned getNumElements() const;
326329
327330 /// Methods for support type inquiry through isa, cast, and dyn_cast:
328331 ///
11951198 /// index.
11961199 UndefValue *getElementValue(unsigned Idx) const;
11971200
1201 /// \brief Return the number of elements in the array, vector, or struct.
1202 unsigned getNumElements() const;
1203
11981204 void destroyConstant() override;
11991205
12001206 /// Methods for support type inquiry through isa, cast, and dyn_cast:
256256 if (const ConstantVector *CV = dyn_cast(this))
257257 return Elt < CV->getNumOperands() ? CV->getOperand(Elt) : nullptr;
258258
259 if (const ConstantAggregateZero *CAZ =dyn_cast(this))
260 return CAZ->getElementValue(Elt);
259 if (const ConstantAggregateZero *CAZ = dyn_cast(this))
260 return Elt < CAZ->getNumElements() ? CAZ->getElementValue(Elt) : nullptr;
261261
262262 if (const UndefValue *UV = dyn_cast(this))
263 return UV->getElementValue(Elt);
263 return Elt < UV->getNumElements() ? UV->getElementValue(Elt) : nullptr;
264264
265265 if (const ConstantDataSequential *CDS =dyn_cast(this))
266266 return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt)
763763 return getStructElement(Idx);
764764 }
765765
766 unsigned ConstantAggregateZero::getNumElements() const {
767 const Type *Ty = getType();
768 if (const auto *AT = dyn_cast(Ty))
769 return AT->getNumElements();
770 if (const auto *VT = dyn_cast(Ty))
771 return VT->getNumElements();
772 return Ty->getStructNumElements();
773 }
766774
767775 //===----------------------------------------------------------------------===//
768776 // UndefValue Implementation
796804 return getStructElement(Idx);
797805 }
798806
799
807 unsigned UndefValue::getNumElements() const {
808 const Type *Ty = getType();
809 if (const auto *AT = dyn_cast(Ty))
810 return AT->getNumElements();
811 if (const auto *VT = dyn_cast(Ty))
812 return VT->getNumElements();
813 return Ty->getStructNumElements();
814 }
800815
801816 //===----------------------------------------------------------------------===//
802817 // ConstantXXX Classes
0 ; RUN: opt < %s -instsimplify -S | FileCheck %s
1
2 @zeroinit = constant {} zeroinitializer
3 @undef = constant {} undef
4
5 define i32 @crash_on_zeroinit() {
6 ; CHECK-LABEL: @crash_on_zeroinit
7 ; CHECK: ret i32 0
8 %load = load i32* bitcast ({}* @zeroinit to i32*)
9 ret i32 %load
10 }
11
12 define i32 @crash_on_undef() {
13 ; CHECK-LABEL: @crash_on_undef
14 ; CHECK: ret i32 undef
15 %load = load i32* bitcast ({}* @undef to i32*)
16 ret i32 %load
17 }
18