[PATCH] [Patch] Assertion failure when a multidimensional array allocated with new operator is explicitly list initialized.

jyoti allur jyoti.yalamanchili at gmail.com
Fri Nov 15 07:06:12 PST 2013


  Modified to generalize the patch to handle explicit initialization of array of any dimensions successfully. The assertion failure mentioned before is resolved with this patch and regression is verified to be successful without any additional failures.
  Please let me know of this patch is good to commit ?

Hi rsmith, eli.friedman, dblaikie,

http://llvm-reviews.chandlerc.com/D1986

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D1986?vs=5056&id=5574#toc

Files:
  llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
  llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp
  llvm/tools/clang/test/CodeGenCXX/cxx0x-initializer-placement-new-array.cpp

Index: llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
===================================================================
--- llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
+++ llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
@@ -1566,6 +1566,14 @@
   /// to ItaniumCXXABI.cpp together with all the references to VTT.
   llvm::Value *GetVTTParameter(GlobalDecl GD, bool ForVirtualBase,
                                bool Delegating);
+  void CheckArrayInitializer(CodeGenFunction* CGF, const InitListExpr* Init,
+      QualType ElemType, llvm::Value *NewPtr, llvm::AllocaInst* endOfInit,
+                                          unsigned &Index);
+  void CheckSubExprInitializer(CodeGenFunction* CGF,  const Expr* expr,
+      QualType ElemType, llvm::Value *NewPtr, llvm::AllocaInst* endOfInit,
+                                          unsigned &Index);
+  void CheckExplicitInitializer(CodeGenFunction* CGF,  const InitListExpr* Init,
+      QualType ElemType, llvm::Value *NewPtr, llvm::AllocaInst* endOfInit);
 
   void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
                                       CXXCtorType CtorType,
Index: llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp
===================================================================
--- llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp
+++ llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp
@@ -783,14 +783,7 @@
       cleanup = EHStack.stable_begin();
     }
 
-    for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i) {
-      // Tell the cleanup that it needs to destroy up to this
-      // element.  TODO: some of these stores can be trivially
-      // observed to be unnecessary.
-      if (endOfInit) Builder.CreateStore(explicitPtr, endOfInit);
-      StoreAnyExprIntoOneUnit(*this, ILE->getInit(i), elementType, explicitPtr);
-      explicitPtr =Builder.CreateConstGEP1_32(explicitPtr, 1, "array.exp.next");
-    }
+    CheckExplicitInitializer(this, ILE, elementType, explicitPtr, endOfInit);
 
     // The remaining elements are filled with the array filler expression.
     Init = ILE->getArrayFiller();
@@ -1857,3 +1850,48 @@
     EmitInitializerForField(*CurField, LV, *i, ArrayIndexes);
   }
 }
+
+void CodeGenFunction::CheckArrayInitializer(CodeGenFunction* CGF,
+                          const InitListExpr* ILE, QualType ElemType,
+                          llvm::Value *NewPtr,
+                          llvm::AllocaInst* endOfInit,
+                          unsigned &Index) {
+  while(Index <  ILE->getNumInits()) {
+    CheckSubExprInitializer(CGF, ILE->getInit(Index), ElemType, NewPtr, endOfInit, Index);
+  }
+}
+
+void CodeGenFunction::CheckSubExprInitializer(CodeGenFunction* CGF,
+                          const Expr* expr, QualType ElemType,
+                          llvm::Value *NewPtr,
+                          llvm::AllocaInst* endOfInit,
+                          unsigned &Index) {
+  if (const InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
+    if (!ElemType->isRecordType() || ElemType->isAggregateType()) {
+      CheckExplicitInitializer(CGF, SubInitList, ElemType, NewPtr, endOfInit);
+      ++Index;  ///ROW increment
+      return;
+    }
+  }
+
+  if(ElemType->isLiteralType(getContext())
+      || ElemType->isObjectType()
+      || ElemType->isComplexType()
+      || ElemType->isScalarType()
+      || ElemType->isAggregateType() ) {
+    if (endOfInit != 0) Builder.CreateStore(NewPtr, endOfInit);
+    StoreAnyExprIntoOneUnit(*CGF, expr, ElemType, NewPtr);
+    NewPtr =Builder.CreateConstGEP1_32(NewPtr, 1, "array.exp.next");
+    Index++;
+    return;
+  }
+
+}
+
+void CodeGenFunction::CheckExplicitInitializer(CodeGenFunction* CGF,
+                          const InitListExpr* Init, QualType ElemType,
+                          llvm::Value *NewPtr, llvm::AllocaInst* endOfInit) {
+  unsigned Index = 0;
+  CheckArrayInitializer(CGF, Init, ElemType, NewPtr, endOfInit, Index);
+
+}
Index: llvm/tools/clang/test/CodeGenCXX/cxx0x-initializer-placement-new-array.cpp
===================================================================
--- llvm/tools/clang/test/CodeGenCXX/cxx0x-initializer-placement-new-array.cpp
+++ llvm/tools/clang/test/CodeGenCXX/cxx0x-initializer-placement-new-array.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c++11 -S -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s
+
+typedef __SIZE_TYPE__ size_t;
+void* operator new[](size_t, void *p) { return p; }
+template <typename T = size_t>
+void f ()
+{
+  size_t coord [2][2];
+  new (&coord) size_t [2][2]
+   {
+     {0,0},
+     {0,0},
+   };
+   // CHECK: %coord = alloca [2 x [2 x i32]], align 4
+   // CHECK: %0 = bitcast [2 x [2 x i32]]* %coord to i8*
+   // CHECK: %1 = bitcast i8* %0 to i32*
+   // CHECK: %array.end = getelementptr inbounds i32* %1, i32 4
+   // CHECK-NEXT: store i32 0, i32* %1, align 4
+   // CHECK-NEXT: %array.exp.next = getelementptr i32* %1, i32 1
+   // CHECK-NEXT: store i32 0, i32* %1, align 4
+   // CHECK-NEXT: %array.exp.next1 = getelementptr i32* %1, i32 1
+   // CHECK-NEXT: store i32 0, i32* %1, align 4
+   // CHECK-NEXT: %array.exp.next2 = getelementptr i32* %1, i32 1
+   // CHECK-NEXT: store i32 0, i32* %1, align 4
+   // CHECK-NEXT: %array.exp.next3 = getelementptr i32* %1, i32 1
+
+}
+
+int main ()
+{
+  f<>();
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1986.2.patch
Type: text/x-patch
Size: 5298 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131115/7f4fdbd8/attachment.bin>


More information about the cfe-commits mailing list