aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGCXX.cpp11
-rw-r--r--lib/CodeGen/CGCXXExpr.cpp1
-rw-r--r--test/CodeGenCXX/array-operator-delete-call.cpp11
3 files changed, 21 insertions, 2 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index c23ad59764..bcb0b5c5c3 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -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);
diff --git a/lib/CodeGen/CGCXXExpr.cpp b/lib/CodeGen/CGCXXExpr.cpp
index aa8acab4e6..abf8d16524 100644
--- a/lib/CodeGen/CGCXXExpr.cpp
+++ b/lib/CodeGen/CGCXXExpr.cpp
@@ -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;
}
diff --git a/test/CodeGenCXX/array-operator-delete-call.cpp b/test/CodeGenCXX/array-operator-delete-call.cpp
index d394aa1673..c23d33632a 100644
--- a/test/CodeGenCXX/array-operator-delete-call.cpp
+++ b/test/CodeGenCXX/array-operator-delete-call.cpp
@@ -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;
}