r247597 - Fix a nasty bug with the partial destruction of nested arrays;

John McCall via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 14 11:57:09 PDT 2015


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 }




More information about the cfe-commits mailing list