[cfe-commits] r88680 - in /cfe/trunk: lib/CodeGen/CGCXX.cpp lib/CodeGen/CGCXXExpr.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenCXX/array-operator-delete-call.cpp

Fariborz Jahanian fjahanian at apple.com
Fri Nov 13 11:27:48 PST 2009


Author: fjahanian
Date: Fri Nov 13 13:27:47 2009
New Revision: 88680

URL: http://llvm.org/viewvc/llvm-project?rev=88680&view=rev
Log:
Code gen for arrady delete operator. Fixes pr5472.


Added:
    cfe/trunk/test/CodeGenCXX/array-operator-delete-call.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CGCXXExpr.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=88680&r1=88679&r2=88680&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Fri Nov 13 13:27:47 2009
@@ -521,16 +521,25 @@
                                            llvm::Value *This) {
   const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
   assert(CA && "Do we support VLA for destruction ?");
+  uint64_t ElementCount = getContext().getConstantArrayElementCount(CA);
+  llvm::Value* ElementCountPtr =
+    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), ElementCount);
+  EmitCXXAggrDestructorCall(D, ElementCountPtr, This);
+}
+
+/// EmitCXXAggrDestructorCall - calls the default destructor on array
+/// elements in reverse order of construction.
+void
+CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
+                                           llvm::Value *UpperCount,
+                                           llvm::Value *This) {
   llvm::Value *One = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
                                             1);
-  uint64_t ElementCount = getContext().getConstantArrayElementCount(CA);
   // Create a temporary for the loop index and initialize it with count of
   // array elements.
   llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
                                            "loop.index");
   // Index = ElementCount;
-  llvm::Value* UpperCount =
-    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), ElementCount);
   Builder.CreateStore(UpperCount, IndexPtr, false);
 
   // Start the loop with a block that tests the condition.
@@ -574,7 +583,7 @@
   EmitBlock(AfterFor, true);
 }
 
-/// EmitCXXAggrDestructorCall - Generates a helper function which when invoked,
+/// GenerateCXXAggrDestructorHelper - Generates a helper function which when invoked,
 /// calls the default destructor on array elements in reverse order of 
 /// construction.
 llvm::Constant * 

Modified: cfe/trunk/lib/CodeGen/CGCXXExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXExpr.cpp?rev=88680&r1=88679&r2=88680&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXXExpr.cpp Fri Nov 13 13:27:47 2009
@@ -235,11 +235,7 @@
 }
 
 void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
-  if (E->isArrayForm()) {
-    ErrorUnsupported(E, "delete[] expression");
-    return;
-  };
-
+  
   // Get at the argument before we performed the implicit conversion
   // to void*.
   const Expr *Arg = E->getArgument();
@@ -273,7 +269,33 @@
     if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
       if (!RD->hasTrivialDestructor()) {
         const CXXDestructorDecl *Dtor = RD->getDestructor(getContext());
-        if (Dtor->isVirtual()) {
+        if (E->isArrayForm()) {
+          QualType SizeTy = getContext().getSizeType();
+          uint64_t CookiePadding = std::max(getContext().getTypeSize(SizeTy),
+                static_cast<uint64_t>(getContext().getTypeAlign(DeleteTy))) / 8;
+          if (CookiePadding) {
+            llvm::Type *Ptr8Ty = 
+              llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
+            uint64_t CookieOffset =
+              CookiePadding - getContext().getTypeSize(SizeTy) / 8;
+            llvm::Value *AllocatedObjectPtr = 
+              Builder.CreateConstInBoundsGEP1_64(
+                            Builder.CreateBitCast(Ptr, Ptr8Ty), -CookiePadding);
+            llvm::Value *NumElementsPtr =
+              Builder.CreateConstInBoundsGEP1_64(AllocatedObjectPtr, 
+                                                 CookieOffset);
+            
+            NumElementsPtr =
+              Builder.CreateBitCast(NumElementsPtr,
+                            llvm::Type::getInt64Ty(VMContext)->getPointerTo());
+            llvm::Value *NumElements = 
+              Builder.CreateLoad(NumElementsPtr);
+            assert (!Dtor->isVirtual() && "delete [] with virtual dtors NYI");
+            EmitCXXAggrDestructorCall(Dtor, NumElements, Ptr);
+            Ptr = AllocatedObjectPtr;
+          }
+        }
+        else if (Dtor->isVirtual()) {
           const llvm::Type *Ty =
             CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(Dtor),
                                            /*isVariadic=*/false);

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=88680&r1=88679&r2=88680&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Nov 13 13:27:47 2009
@@ -646,6 +646,10 @@
                                  const ArrayType *Array,
                                  llvm::Value *This);
 
+  void EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
+                                 llvm::Value *NumElements,
+                                 llvm::Value *This);
+
   llvm::Constant * GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
                                                 const ArrayType *Array,
                                                 llvm::Value *This);

Added: cfe/trunk/test/CodeGenCXX/array-operator-delete-call.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/array-operator-delete-call.cpp?rev=88680&view=auto

==============================================================================
--- cfe/trunk/test/CodeGenCXX/array-operator-delete-call.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/array-operator-delete-call.cpp Fri Nov 13 13:27:47 2009
@@ -0,0 +1,52 @@
+// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
+
+extern "C" int printf(...);
+
+int count;
+
+struct S {
+  S() : iS (++count) { printf("S::S(%d)\n", iS); }
+  ~S() { printf("S::~S(%d)\n", iS); }
+  int iS;
+};
+
+struct COST
+{
+  S *cost;
+  unsigned *cost_val;
+
+  ~COST();
+  COST();
+};
+
+
+COST::COST()
+{
+  cost = new S[3];
+  cost_val = new unsigned[10];
+}
+
+COST::~COST()
+{
+  if (cost) {
+   delete [] cost;
+  }
+  if (cost_val)
+    delete [] cost_val;
+}
+
+COST c1;
+
+int main()
+{
+  COST c3;
+}
+COST c2;
+
+// CHECK-LP64: call     __ZdaPv
+
+// CHECK-LP32: call     L__ZdaPv
+





More information about the cfe-commits mailing list