summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGCXX.cpp17
-rw-r--r--clang/lib/CodeGen/CGCXXExpr.cpp34
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h4
3 files changed, 45 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index 9b83f001735..c23ad597649 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -521,16 +521,25 @@ CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
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 @@ CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
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 *
diff --git a/clang/lib/CodeGen/CGCXXExpr.cpp b/clang/lib/CodeGen/CGCXXExpr.cpp
index a21149973da..d9275fc0a76 100644
--- a/clang/lib/CodeGen/CGCXXExpr.cpp
+++ b/clang/lib/CodeGen/CGCXXExpr.cpp
@@ -235,11 +235,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
}
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 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
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);
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index c69dcb505ac..5f8a1969f91 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -646,6 +646,10 @@ public:
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);
OpenPOWER on IntegriCloud