Hi rsmith, doug.gregor, rjmccall,

See http://llvm.org/bugs/show_bug.cgi?id=18177.

Essentially clang currently crashes when performing the following forms of new 
array initialization:
new int[2][3]{{1}, {2}};

This is because emission of new initialization confuses itself at times between 
the notion of obtaining a 2 element array of int[3] vs 6 elements of int - this 
leads to issues with the type of the initializer expression being an aggregate 
and the type being initialized expected to be a scalar.

I fixed this by having the emission just use the allocated type as is and not 
go digging into the base type of the array.

My testing on windows 7 of the code below all seemed to output what would be 
expected (although some regressions in codegencxx do fail, but glancing at 
them, its just an issue of adjusting the pointer arithmetic).

  {
    auto f4 = new int[100][200][300]{{{1,2,3}, {4, 5, 6}}, {{10, 20, 30}}};
    FV_DUMP((3,f4[0][0][2]));
    FV_DUMP((6,f4[0][1][2]));
    FV_DUMP((0,f4[0][1][3]));
    FV_DUMP((30,f4[1][0][2]));
    FV_DUMP((0,f4[1][0][3]));
    FV_DUMP((0,f4[2][0][3]));
  }

and 
  {
  struct A {
    int x = num();
    ~A() {}
    A() =default;
    A(int x) : x{x} { }
    static int num() { 
      static int x;
      return ++x;
    }
  };
  A (*x)[20] = new A[10][20]{{A{1234}, A{5678}}};
  FV_DUMP(x[0][0].x);
  FV_DUMP(x[0][1].x);
  FV_DUMP(x[0][2].x);
  }

If this direction seems like the right way to go - please let me know - and 
i'll include the painful codegencxx tests and fix the regressions in my next 
revision to this patch.

Thanks!

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

Files:
  lib/CodeGen/CGExprCXX.cpp

Index: lib/CodeGen/CGExprCXX.cpp
===================================================================
--- lib/CodeGen/CGExprCXX.cpp
+++ lib/CodeGen/CGExprCXX.cpp
@@ -540,12 +540,6 @@
     if (adjustedCount.ult(minElements))
       hasAnyOverflow = true;
 
-    // Scale numElements by that.  This might overflow, but we don't
-    // care because it only overflows if allocationSize does, too, and
-    // if that overflows then we shouldn't use this.
-    numElements = llvm::ConstantInt::get(CGF.SizeTy,
-                                         adjustedCount * arraySizeMultiplier);
-
     // Compute the size before cookie, and track whether it overflowed.
     bool overflow;
     llvm::APInt allocationSize
@@ -782,7 +776,6 @@
                                        getDestroyer(dtorKind));
       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
@@ -1102,8 +1095,8 @@
 
 llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
   // The element type being allocated.
-  QualType allocType = getContext().getBaseElementType(E->getAllocatedType());
-
+  QualType allocType = E->getAllocatedType();
+  
   // 1. Build a call to the allocation function.
   FunctionDecl *allocator = E->getOperatorNew();
   const FunctionProtoType *allocatorType =
Index: lib/CodeGen/CGExprCXX.cpp
===================================================================
--- lib/CodeGen/CGExprCXX.cpp
+++ lib/CodeGen/CGExprCXX.cpp
@@ -540,12 +540,6 @@
     if (adjustedCount.ult(minElements))
       hasAnyOverflow = true;
 
-    // Scale numElements by that.  This might overflow, but we don't
-    // care because it only overflows if allocationSize does, too, and
-    // if that overflows then we shouldn't use this.
-    numElements = llvm::ConstantInt::get(CGF.SizeTy,
-                                         adjustedCount * arraySizeMultiplier);
-
     // Compute the size before cookie, and track whether it overflowed.
     bool overflow;
     llvm::APInt allocationSize
@@ -782,7 +776,6 @@
                                        getDestroyer(dtorKind));
       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
@@ -1102,8 +1095,8 @@
 
 llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
   // The element type being allocated.
-  QualType allocType = getContext().getBaseElementType(E->getAllocatedType());
-
+  QualType allocType = E->getAllocatedType();
+  
   // 1. Build a call to the allocation function.
   FunctionDecl *allocator = E->getOperatorNew();
   const FunctionProtoType *allocatorType =
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to