forked from OSchip/llvm-project
Fix a nasty bug with the partial destruction of nested arrays;
it escaped notice because it's only used for heterogeneous initialization. rdar://21397946 llvm-svn: 247597
This commit is contained in:
parent
a5f384487a
commit
f0f0b7a0eb
|
@ -1535,9 +1535,9 @@ static void emitPartialArrayDestroy(CodeGenFunction &CGF,
|
|||
}
|
||||
|
||||
if (arrayDepth) {
|
||||
llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, arrayDepth+1);
|
||||
llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
|
||||
|
||||
SmallVector<llvm::Value*,4> gepIndices(arrayDepth, zero);
|
||||
SmallVector<llvm::Value*,4> gepIndices(arrayDepth+1, zero);
|
||||
begin = CGF.Builder.CreateInBoundsGEP(begin, gepIndices, "pad.arraybegin");
|
||||
end = CGF.Builder.CreateInBoundsGEP(end, gepIndices, "pad.arrayend");
|
||||
}
|
||||
|
|
|
@ -173,3 +173,34 @@ namespace test3 {
|
|||
// invoke void @_ZN5test31BD1Ev(
|
||||
}
|
||||
}
|
||||
|
||||
namespace test4 {
|
||||
struct A { A(unsigned i); ~A(); };
|
||||
void test() {
|
||||
A v[2][3] = { { A(0), A(1), A(2) }, { A(3), A(4), A(5) } };
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: define void @_ZN5test44testEv()
|
||||
// CHECK: [[ARRAY:%.*]] = alloca [2 x [3 x [[A:%.*]]]], align
|
||||
// CHECK: [[A0:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]], [2 x [3 x [[A]]]]* [[ARRAY]], i64 0, i64 0
|
||||
// CHECK-NEXT: store [3 x [[A]]]* [[A0]],
|
||||
// CHECK-NEXT: [[A00:%.*]] = getelementptr inbounds [3 x [[A]]], [3 x [[A]]]* [[A0]], i64 0, i64 0
|
||||
// CHECK-NEXT: store [[A]]* [[A00]],
|
||||
// CHECK-NEXT: invoke void @_ZN5test41AC1Ej([[A]]* [[A00]], i32 0)
|
||||
// CHECK: [[A01:%.*]] = getelementptr inbounds [[A]], [[A]]* [[A00]], i64 1
|
||||
// CHECK-NEXT: store [[A]]* [[A01]],
|
||||
// CHECK-NEXT: invoke void @_ZN5test41AC1Ej([[A]]* [[A01]], i32 1)
|
||||
// CHECK: [[A02:%.*]] = getelementptr inbounds [[A]], [[A]]* [[A01]], i64 1
|
||||
// CHECK-NEXT: store [[A]]* [[A02]],
|
||||
// CHECK-NEXT: invoke void @_ZN5test41AC1Ej([[A]]* [[A02]], i32 2)
|
||||
// CHECK: [[A1:%.*]] = getelementptr inbounds [3 x [[A]]], [3 x [[A]]]* [[A0]], i64 1
|
||||
// CHECK-NEXT: store [3 x [[A]]]* [[A1]],
|
||||
// CHECK-NEXT: [[A10:%.*]] = getelementptr inbounds [3 x [[A]]], [3 x [[A]]]* [[A1]], i64 0, i64 0
|
||||
// CHECK-NEXT: store [[A]]* [[A10]],
|
||||
// CHECK-NEXT: invoke void @_ZN5test41AC1Ej([[A]]* [[A10]], i32 3)
|
||||
// CHECK: [[A11:%.*]] = getelementptr inbounds [[A]], [[A]]* [[A10]], i64 1
|
||||
// CHECK-NEXT: store [[A]]* [[A11]],
|
||||
// CHECK-NEXT: invoke void @_ZN5test41AC1Ej([[A]]* [[A11]], i32 4)
|
||||
// CHECK: [[A12:%.*]] = getelementptr inbounds [[A]], [[A]]* [[A11]], i64 1
|
||||
// CHECK-NEXT: store [[A]]* [[A12]],
|
||||
// CHECK-NEXT: invoke void @_ZN5test41AC1Ej([[A]]* [[A12]], i32 5)
|
||||
|
|
|
@ -121,4 +121,37 @@ namespace test4 {
|
|||
// CHECK: resume
|
||||
}
|
||||
|
||||
// rdar://21397946
|
||||
__attribute__((ns_returns_retained)) id test5_helper(unsigned);
|
||||
void test5(void) {
|
||||
id array[][2] = {
|
||||
test5_helper(0),
|
||||
test5_helper(1),
|
||||
test5_helper(2),
|
||||
test5_helper(3)
|
||||
};
|
||||
}
|
||||
// CHECK-LABEL: define void @_Z5test5v()
|
||||
// CHECK: [[ARRAY:%.*]] = alloca [2 x [2 x i8*]], align
|
||||
// CHECK: [[A0:%.*]] = getelementptr inbounds [2 x [2 x i8*]], [2 x [2 x i8*]]* [[ARRAY]], i64 0, i64 0
|
||||
// CHECK-NEXT: store [2 x i8*]* [[A0]],
|
||||
// CHECK-NEXT: [[A00:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[A0]], i64 0, i64 0
|
||||
// CHECK-NEXT: store i8** [[A00]],
|
||||
// CHECK-NEXT: [[T0:%.*]] = invoke i8* @_Z12test5_helperj(i32 0)
|
||||
// CHECK: store i8* [[T0]], i8** [[A00]], align
|
||||
// CHECK-NEXT: [[A01:%.*]] = getelementptr inbounds i8*, i8** [[A00]], i64 1
|
||||
// CHECK-NEXT: store i8** [[A01]],
|
||||
// CHECK-NEXT: [[T0:%.*]] = invoke i8* @_Z12test5_helperj(i32 1)
|
||||
// CHECK: store i8* [[T0]], i8** [[A01]], align
|
||||
// CHECK-NEXT: [[A1:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[A0]], i64 1
|
||||
// CHECK-NEXT: store [2 x i8*]* [[A1]],
|
||||
// CHECK-NEXT: [[A10:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[A1]], i64 0, i64 0
|
||||
// CHECK-NEXT: store i8** [[A10]],
|
||||
// CHECK-NEXT: [[T0:%.*]] = invoke i8* @_Z12test5_helperj(i32 2)
|
||||
// CHECK: store i8* [[T0]], i8** [[A10]], align
|
||||
// CHECK-NEXT: [[A11:%.*]] = getelementptr inbounds i8*, i8** [[A10]], i64 1
|
||||
// CHECK-NEXT: store i8** [[A11]],
|
||||
// CHECK-NEXT: [[T0:%.*]] = invoke i8* @_Z12test5_helperj(i32 3)
|
||||
// CHECK: store i8* [[T0]], i8** [[A11]], align
|
||||
|
||||
// CHECK: attributes [[NUW]] = { nounwind }
|
||||
|
|
Loading…
Reference in New Issue