forked from OSchip/llvm-project
[PR47636] Fix tryEmitPrivate to handle non-constantarraytypes
As mentioned in the bug report, tryEmitPrivate chokes on the MaterializeTemporaryExpr in the reproducers, since it assumes that if there are elements, than it must be a ConstantArrayType. However, the MaterializeTemporaryExpr (which matches exactly the AST when it is NOT a global/static) has an incomplete array type. This changes the section where the number-of-elements is non-zero to properly handle non-CAT types by just extracting it as an array type (since all we needed was the element type out of it).
This commit is contained in:
parent
f2efb5742c
commit
606a734755
|
@ -2108,8 +2108,7 @@ llvm::Constant *ConstantEmitter::tryEmitPrivate(const APValue &Value,
|
|||
case APValue::Union:
|
||||
return ConstStructBuilder::BuildStruct(*this, Value, DestType);
|
||||
case APValue::Array: {
|
||||
const ConstantArrayType *CAT =
|
||||
CGM.getContext().getAsConstantArrayType(DestType);
|
||||
const ArrayType *ArrayTy = CGM.getContext().getAsArrayType(DestType);
|
||||
unsigned NumElements = Value.getArraySize();
|
||||
unsigned NumInitElts = Value.getArrayInitializedElts();
|
||||
|
||||
|
@ -2117,7 +2116,7 @@ llvm::Constant *ConstantEmitter::tryEmitPrivate(const APValue &Value,
|
|||
llvm::Constant *Filler = nullptr;
|
||||
if (Value.hasArrayFiller()) {
|
||||
Filler = tryEmitAbstractForMemory(Value.getArrayFiller(),
|
||||
CAT->getElementType());
|
||||
ArrayTy->getElementType());
|
||||
if (!Filler)
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2132,7 +2131,7 @@ llvm::Constant *ConstantEmitter::tryEmitPrivate(const APValue &Value,
|
|||
llvm::Type *CommonElementType = nullptr;
|
||||
for (unsigned I = 0; I < NumInitElts; ++I) {
|
||||
llvm::Constant *C = tryEmitPrivateForMemory(
|
||||
Value.getArrayInitializedElt(I), CAT->getElementType());
|
||||
Value.getArrayInitializedElt(I), ArrayTy->getElementType());
|
||||
if (!C) return nullptr;
|
||||
|
||||
if (I == 0)
|
||||
|
@ -2144,11 +2143,10 @@ llvm::Constant *ConstantEmitter::tryEmitPrivate(const APValue &Value,
|
|||
|
||||
// This means that the array type is probably "IncompleteType" or some
|
||||
// type that is not ConstantArray.
|
||||
if (CAT == nullptr && CommonElementType == nullptr && !NumInitElts) {
|
||||
const ArrayType *AT = CGM.getContext().getAsArrayType(DestType);
|
||||
CommonElementType = CGM.getTypes().ConvertType(AT->getElementType());
|
||||
llvm::ArrayType *AType = llvm::ArrayType::get(CommonElementType,
|
||||
NumElements);
|
||||
if (!Filler && !NumInitElts) {
|
||||
CommonElementType = CGM.getTypes().ConvertType(ArrayTy->getElementType());
|
||||
llvm::ArrayType *AType =
|
||||
llvm::ArrayType::get(CommonElementType, NumElements);
|
||||
return llvm::ConstantAggregateZero::get(AType);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
// RUN: %clang_cc1 -o - -emit-llvm -triple x86_64-linux-pc %s | FileCheck %s
|
||||
int(&&intu_rvref)[] {1,2,3,4};
|
||||
// CHECK: @_ZGR10intu_rvref_ = internal global [4 x i32] [i32 1, i32 2, i32 3, i32 4]
|
||||
// CHECK: @intu_rvref = constant [4 x i32]* @_ZGR10intu_rvref_
|
||||
|
||||
void foo() {
|
||||
static const int(&&intu_rvref)[] {1,2,3,4};
|
||||
// CHECK: @_ZZ3foovE10intu_rvref = internal constant [4 x i32]* @_ZGRZ3foovE10intu_rvref_
|
||||
// CHECK: @_ZGRZ3foovE10intu_rvref_ = internal constant [4 x i32] [i32 1, i32 2, i32 3, i32 4]
|
||||
}
|
Loading…
Reference in New Issue