[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