]> granicus.if.org Git - clang/commitdiff
Code gen. For virtual destructor call on array objects
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 13 Nov 2009 22:29:45 +0000 (22:29 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 13 Nov 2009 22:29:45 +0000 (22:29 +0000)
(still part of pr5472).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88712 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCXX.cpp
lib/CodeGen/CGCXXExpr.cpp
test/CodeGenCXX/array-operator-delete-call.cpp

index c23ad597649184e8bdbb77686b65508edc4ede9a..bcb0b5c5c3b1de66cc05b2166224d9c6cad1dd0e 100644 (file)
@@ -567,7 +567,16 @@ CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
   Counter = Builder.CreateLoad(IndexPtr);
   Counter = Builder.CreateSub(Counter, One);
   llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
-  EmitCXXDestructorCall(D, Dtor_Complete, Address);
+  if (D->isVirtual()) {
+    const llvm::Type *Ty =
+      CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(D),
+                                     /*isVariadic=*/false);
+    
+    llvm::Value *Callee = BuildVirtualCall(D, Dtor_Deleting, Address, Ty);
+    EmitCXXMemberCall(D, Callee, Address, 0, 0);
+  }
+  else
+    EmitCXXDestructorCall(D, Dtor_Complete, Address);
 
   EmitBlock(ContinueBlock);
 
index aa8acab4e61bcf882a376b76a3dbb3e19b53c447..abf8d16524d1c1739a4371dbc1cf1d0cfe848e98 100644 (file)
@@ -293,7 +293,6 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
               Builder.CreateIntCast(NumElements, 
                                     llvm::Type::getInt64Ty(VMContext), false, 
                                     "count.tmp");
-            assert (!Dtor->isVirtual() && "delete [] with virtual dtors NYI");
             EmitCXXAggrDestructorCall(Dtor, NumElements, Ptr);
             Ptr = AllocatedObjectPtr;
           }
index d394aa167396e23cfe3353ac4bf54b18a08c6044..c23d33632a38b14ad371668a38f2c9c1711928be 100644 (file)
@@ -13,9 +13,16 @@ struct S {
   int iS;
 };
 
+struct V {
+  V() : iV (++count) { printf("V::V(%d)\n", iV); }
+  virtual ~V() { printf("V::~V(%d)\n", iV); }
+  int iV;
+};
+
 struct COST
 {
   S *cost;
+  V *vcost;
   unsigned *cost_val;
 
   ~COST();
@@ -26,6 +33,7 @@ struct COST
 COST::COST()
 {
   cost = new S[3];
+  vcost = new V[4];
   cost_val = new unsigned[10];
 }
 
@@ -34,6 +42,9 @@ COST::~COST()
   if (cost) {
    delete [] cost;
   }
+  if (vcost) {
+   delete [] vcost;
+  }
   if (cost_val)
     delete [] cost_val;
 }