[cfe-commits] r99404 - in /cfe/trunk: lib/CodeGen/CGExprCXX.cpp test/CodeGenCXX/multi-dim-operator-new.cpp

Fariborz Jahanian fjahanian at apple.com
Wed Mar 24 09:57:01 PDT 2010


Author: fjahanian
Date: Wed Mar 24 11:57:01 2010
New Revision: 99404

URL: http://llvm.org/viewvc/llvm-project?rev=99404&view=rev
Log:
Code gen for multi-dimensional dynamic allocations.
Fixes PR6641.

Added:
    cfe/trunk/test/CodeGenCXX/multi-dim-operator-new.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=99404&r1=99403&r2=99404&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Wed Mar 24 11:57:01 2010
@@ -411,7 +411,8 @@
   return CalculateCookiePadding(Ctx, E->getAllocatedType());
 }
 
-static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF, 
+static llvm::Value *EmitCXXNewAllocSize(ASTContext &Context,
+                                        CodeGenFunction &CGF, 
                                         const CXXNewExpr *E,
                                         llvm::Value *& NumElements) {
   QualType Type = E->getAllocatedType();
@@ -432,6 +433,15 @@
     
     NumElements = 
       llvm::ConstantInt::get(SizeTy, Result.Val.getInt().getZExtValue());
+    while (const ArrayType *AType = Context.getAsArrayType(Type)) {
+      const llvm::ArrayType *llvmAType =
+        cast<llvm::ArrayType>(CGF.ConvertType(Type));
+      NumElements =
+        CGF.Builder.CreateMul(NumElements, 
+                              llvm::ConstantInt::get(
+                                        SizeTy, llvmAType->getNumElements()));
+      Type = AType->getElementType();
+    }
     
     return llvm::ConstantInt::get(SizeTy, AllocSize.getQuantity());
   }
@@ -444,6 +454,16 @@
     CGF.Builder.CreateMul(NumElements, 
                           llvm::ConstantInt::get(SizeTy, 
                                                  TypeSize.getQuantity()));
+  
+  while (const ArrayType *AType = Context.getAsArrayType(Type)) {
+    const llvm::ArrayType *llvmAType =
+      cast<llvm::ArrayType>(CGF.ConvertType(Type));
+    NumElements =
+      CGF.Builder.CreateMul(NumElements, 
+                            llvm::ConstantInt::get(
+                                          SizeTy, llvmAType->getNumElements()));
+    Type = AType->getElementType();
+  }
 
   // And add the cookie padding if necessary.
   if (!CookiePadding.isZero())
@@ -504,7 +524,8 @@
   QualType SizeTy = getContext().getSizeType();
 
   llvm::Value *NumElements = 0;
-  llvm::Value *AllocSize = EmitCXXNewAllocSize(*this, E, NumElements);
+  llvm::Value *AllocSize = EmitCXXNewAllocSize(getContext(),
+                                               *this, E, NumElements);
   
   NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
 
@@ -590,10 +611,20 @@
                                                 CookiePadding.getQuantity());
   }
   
-  NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
-
-  EmitNewInitializer(*this, E, NewPtr, NumElements);
-
+  if (AllocType->isArrayType()) {
+    while (const ArrayType *AType = getContext().getAsArrayType(AllocType))
+      AllocType = AType->getElementType();
+    NewPtr = 
+      Builder.CreateBitCast(NewPtr, 
+                          ConvertType(getContext().getPointerType(AllocType)));
+    EmitNewInitializer(*this, E, NewPtr, NumElements);
+    NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
+  }
+  else {
+    NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
+    EmitNewInitializer(*this, E, NewPtr, NumElements);
+  }
+  
   if (NullCheckResult) {
     Builder.CreateBr(NewEnd);
     NewNotNull = Builder.GetInsertBlock();

Added: cfe/trunk/test/CodeGenCXX/multi-dim-operator-new.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/multi-dim-operator-new.cpp?rev=99404&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/multi-dim-operator-new.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/multi-dim-operator-new.cpp Wed Mar 24 11:57:01 2010
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// PR6641
+
+extern "C" int printf(const char *, ...);
+
+struct Foo {
+ Foo() : iFoo (2) {
+  printf("%p\n", this);
+ }
+ int iFoo;
+};
+
+
+typedef Foo (*T)[3][4];
+
+T bar() {
+ return new Foo[2][3][4];
+}
+
+T bug(int i) {
+  return new Foo[i][3][4];
+}
+
+void pr(T a) {
+  for (int i = 0; i < 3; i++)
+   for (int j = 0; j < 4; j++)
+     printf("%p\n", a[i][j]);
+}
+
+Foo *test() {
+  return new Foo[5];
+}
+
+int main() {
+ T f =  bar();
+ pr(f);
+ f = bug(3);
+ pr(f);
+
+ Foo * g = test();
+ for (int i = 0; i < 5; i++)
+ printf("%d\n", g[i].iFoo);
+ return 0;
+}





More information about the cfe-commits mailing list