Author: rjmccall Date: Mon Sep 14 13:57:08 2015 New Revision: 247597 URL: http://llvm.org/viewvc/llvm-project?rev=247597&view=rev Log: Fix a nasty bug with the partial destruction of nested arrays; it escaped notice because it's only used for heterogeneous initialization.
rdar://21397946 Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/test/CodeGenCXX/partial-destruction.cpp cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=247597&r1=247596&r2=247597&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Mon Sep 14 13:57:08 2015 @@ -1535,9 +1535,9 @@ static void emitPartialArrayDestroy(Code } 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"); } Modified: cfe/trunk/test/CodeGenCXX/partial-destruction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/partial-destruction.cpp?rev=247597&r1=247596&r2=247597&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/partial-destruction.cpp (original) +++ cfe/trunk/test/CodeGenCXX/partial-destruction.cpp Mon Sep 14 13:57:08 2015 @@ -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) Modified: cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm?rev=247597&r1=247596&r2=247597&view=diff ============================================================================== --- cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm (original) +++ cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm Mon Sep 14 13:57:08 2015 @@ -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 } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits