[PATCH] Fix PR18177 -- initializer-lists with multi-D new arrays causes crash

Faisal Vali faisalv at yahoo.com
Mon Dec 9 13:00:57 PST 2013


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 =
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2365.1.patch
Type: text/x-patch
Size: 1449 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131209/7f626309/attachment.bin>


More information about the cfe-commits mailing list