зеркало из https://github.com/microsoft/clang-1.git
PR12571: Objects of type clang::ConstantArrayType aren't always emitted with
type llvm::ArrayType -- sometimes we emit them as packed structs. Don't assert if such a global array has an element type with a non-trivial destructor. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155305 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
a77e072634
Коммит
1664d540d1
|
@ -881,33 +881,49 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType,
|
|||
llvm::ConstantInt *zero = Builder.getInt32(0);
|
||||
gepIndices.push_back(zero);
|
||||
|
||||
// It's more efficient to calculate the count from the LLVM
|
||||
// constant-length arrays than to re-evaluate the array bounds.
|
||||
uint64_t countFromCLAs = 1;
|
||||
QualType eltType;
|
||||
|
||||
llvm::ArrayType *llvmArrayType =
|
||||
cast<llvm::ArrayType>(
|
||||
dyn_cast<llvm::ArrayType>(
|
||||
cast<llvm::PointerType>(addr->getType())->getElementType());
|
||||
while (true) {
|
||||
while (llvmArrayType) {
|
||||
assert(isa<ConstantArrayType>(arrayType));
|
||||
assert(cast<ConstantArrayType>(arrayType)->getSize().getZExtValue()
|
||||
== llvmArrayType->getNumElements());
|
||||
|
||||
gepIndices.push_back(zero);
|
||||
countFromCLAs *= llvmArrayType->getNumElements();
|
||||
eltType = arrayType->getElementType();
|
||||
|
||||
llvmArrayType =
|
||||
dyn_cast<llvm::ArrayType>(llvmArrayType->getElementType());
|
||||
if (!llvmArrayType) break;
|
||||
|
||||
arrayType = getContext().getAsArrayType(arrayType->getElementType());
|
||||
assert(arrayType && "LLVM and Clang types are out-of-synch");
|
||||
assert((!llvmArrayType || arrayType) &&
|
||||
"LLVM and Clang types are out-of-synch");
|
||||
}
|
||||
|
||||
baseType = arrayType->getElementType();
|
||||
if (arrayType) {
|
||||
// From this point onwards, the Clang array type has been emitted
|
||||
// as some other type (probably a packed struct). Compute the array
|
||||
// size, and just emit the 'begin' expression as a bitcast.
|
||||
while (arrayType) {
|
||||
countFromCLAs *=
|
||||
cast<ConstantArrayType>(arrayType)->getSize().getZExtValue();
|
||||
eltType = arrayType->getElementType();
|
||||
arrayType = getContext().getAsArrayType(eltType);
|
||||
}
|
||||
|
||||
// Create the actual GEP.
|
||||
addr = Builder.CreateInBoundsGEP(addr, gepIndices, "array.begin");
|
||||
unsigned AddressSpace =
|
||||
cast<llvm::PointerType>(addr->getType())->getAddressSpace();
|
||||
llvm::Type *BaseType = ConvertType(eltType)->getPointerTo(AddressSpace);
|
||||
addr = Builder.CreateBitCast(addr, BaseType, "array.begin");
|
||||
} else {
|
||||
// Create the actual GEP.
|
||||
addr = Builder.CreateInBoundsGEP(addr, gepIndices, "array.begin");
|
||||
}
|
||||
|
||||
baseType = eltType;
|
||||
|
||||
llvm::Value *numElements
|
||||
= llvm::ConstantInt::get(SizeTy, countFromCLAs);
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
// REQUIRES: x86-64-registered-target
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
|
||||
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
extern "C" int printf(...);
|
||||
|
||||
|
@ -24,11 +22,24 @@ static S sarr1[4];
|
|||
S s2;
|
||||
S arr3[3];
|
||||
|
||||
// CHECK-LP64: callq ___cxa_atexit
|
||||
// CHECK-LP64: callq ___cxa_atexit
|
||||
// CHECK-LP64: callq ___cxa_atexit
|
||||
// CHECK-LP64: callq ___cxa_atexit
|
||||
// CHECK-LP64: callq ___cxa_atexit
|
||||
// CHECK-LP64: callq ___cxa_atexit
|
||||
// CHECK-LP64: callq ___cxa_atexit
|
||||
// CHECK-LP64: callq ___cxa_atexit
|
||||
// CHECK: call {{.*}} @__cxa_atexit
|
||||
// CHECK: call {{.*}} @__cxa_atexit
|
||||
// CHECK: call {{.*}} @__cxa_atexit
|
||||
// CHECK: call {{.*}} @__cxa_atexit
|
||||
// CHECK: call {{.*}} @__cxa_atexit
|
||||
// CHECK: call {{.*}} @__cxa_atexit
|
||||
// CHECK: call {{.*}} @__cxa_atexit
|
||||
// CHECK: call {{.*}} @__cxa_atexit
|
||||
|
||||
struct T {
|
||||
double d;
|
||||
int n;
|
||||
~T();
|
||||
};
|
||||
T t[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
|
||||
|
||||
// CHECK: call {{.*}} @__cxa_atexit
|
||||
// CHECK: getelementptr inbounds ({{.*}} bitcast {{.*}}* @t to %struct.T*), i64 6
|
||||
// CHECK: call void @_ZN1TD1Ev
|
||||
// CHECK: icmp eq {{.*}} @t
|
||||
// CHECK: br i1 {{.*}}
|
||||
|
|
Загрузка…
Ссылка в новой задаче