Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions clang/lib/CodeGen/CGClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1502,7 +1502,8 @@ static void EmitConditionalArrayDtorCall(const CXXDestructorDecl *DD,
if (Dtor->getArrayOperatorDelete()) {
if (!Dtor->getGlobalArrayOperatorDelete()) {
CGF.EmitDeleteCall(Dtor->getArrayOperatorDelete(), allocatedPtr,
CGF.getContext().getCanonicalTagType(ClassDecl));
CGF.getContext().getCanonicalTagType(ClassDecl),
numElements, cookieSize);
} else {
// If global operator[] is set, the class had its own operator delete[].
// In that case, check the 4th bit. If it is set, we need to call
Expand All @@ -1519,12 +1520,14 @@ static void EmitConditionalArrayDtorCall(const CXXDestructorDecl *DD,
CGF.Builder.CreateCondBr(ShouldCallGlobDelete, ClassDelete, GlobDelete);
CGF.EmitBlock(ClassDelete);
CGF.EmitDeleteCall(Dtor->getArrayOperatorDelete(), allocatedPtr,
CGF.getContext().getCanonicalTagType(ClassDecl));
CGF.getContext().getCanonicalTagType(ClassDecl),
numElements, cookieSize);
CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);

CGF.EmitBlock(GlobDelete);
CGF.EmitDeleteCall(Dtor->getGlobalArrayOperatorDelete(), allocatedPtr,
CGF.getContext().getCanonicalTagType(ClassDecl));
CGF.getContext().getCanonicalTagType(ClassDecl),
numElements, cookieSize);
}
} else {
// No operators delete[] were found, so emit a trap.
Expand Down
36 changes: 24 additions & 12 deletions clang/test/CodeGenCXX/microsoft-vector-deleting-dtors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,13 @@ void bar() {
// CHECK-NEXT: %[[ISFIRSTBITZERO:.*]] = icmp eq i32 %[[FIRSTBIT]], 0
// CHECK-NEXT: br i1 %[[ISFIRSTBITZERO]], label %dtor.continue, label %dtor.call_delete_after_array_destroy
// CHECK: dtor.call_delete_after_array_destroy:
// X64-NEXT: call void @"??_V@YAXPEAX_K@Z"(ptr noundef %[[COOKIEGEP]], i64 noundef 8)
// X86-NEXT: call void @"??_V@YAXPAXI@Z"(ptr noundef %[[COOKIEGEP]], i32 noundef 4)
// CHECK-NEXT: br label %dtor.continue
// X64-NEXT: %[[ARRSZ:.*]] = mul i64 8, %[[HOWMANY]]
// X86-NEXT: %[[ARRSZ:.*]] = mul i32 4, %[[HOWMANY]]
// X64-NEXT: %[[TOTALSZ:.*]] = add i64 %[[ARRSZ]], 8
// X86-NEXT: %[[TOTALSZ:.*]] = add i32 %[[ARRSZ]], 4
// X64-NEXT: call void @"??_V@YAXPEAX_K@Z"(ptr noundef %[[COOKIEGEP]], i64 noundef %[[TOTALSZ]])
// X86-NEXT: call void @"??_V@YAXPAXI@Z"(ptr noundef %[[COOKIEGEP]], i32 noundef %[[TOTALSZ]])
// CHECK-NEXT: br label %dtor.continue
// CHECK: dtor.scalar:
// X64-NEXT: call void @"??1Parrot@@UEAA@XZ"(ptr noundef nonnull align 8 dereferenceable(8) %[[LTHIS]])
// X86-NEXT: call x86_thiscallcc void @"??1Parrot@@UAE@XZ"(ptr noundef nonnull align 4 dereferenceable(4) %[[LTHIS]])
Expand Down Expand Up @@ -252,8 +256,12 @@ void bar() {
// X86-NEXT: call void @"??_VHasOperatorDelete@@SAXPAX@Z"
// CHECK-NEXT: br label %dtor.continue
// CHECK: dtor.call_glob_delete_after_array_destroy:
// X64-NEXT: call void @"??_V@YAXPEAX_K@Z"(ptr noundef %2, i64 noundef 8)
// X86-NEXT: call void @"??_V@YAXPAXI@Z"(ptr noundef %2, i32 noundef 4)
// X64-NEXT: %[[ARRSZ:.*]] = mul i64 8, %[[COOKIE:.*]]
// X86-NEXT: %[[ARRSZ:.*]] = mul i32 4, %[[COOKIE:.*]]
// X64-NEXT: %[[TOTALSZ:.*]] = add i64 %[[ARRSZ]], 8
// X86-NEXT: %[[TOTALSZ:.*]] = add i32 %[[ARRSZ]], 4
// X64-NEXT: call void @"??_V@YAXPEAX_K@Z"(ptr noundef %2, i64 noundef %[[TOTALSZ]])
// X86-NEXT: call void @"??_V@YAXPAXI@Z"(ptr noundef %2, i32 noundef %[[TOTALSZ]])
// CHECK-NEXT: br label %dtor.continue


Expand Down Expand Up @@ -314,22 +322,26 @@ void foobartest() {
// CHECK-NEXT: %5 = icmp eq i32 %4, 0
// CHECK-NEXT: br i1 %5, label %dtor.continue, label %dtor.call_delete_after_array_destroy
// CHECK: dtor.call_delete_after_array_destroy:
// X64-NEXT: call void @"??_V@YAXPEAX_K@Z"(ptr noundef %2, i64 noundef 16)
// X86-NEXT: call void @"??_V@YAXPAXI@Z"(ptr noundef %2, i32 noundef 8)
// X64-NEXT: %[[ARRSZ:.*]] = mul i64 16, %[[COOKIE:.*]]
// X86-NEXT: %[[ARRSZ:.*]] = mul i32 8, %[[COOKIE:.*]]
// X64-NEXT: %[[TOTALSZ:.*]] = add i64 %[[ARRSZ]], 8
// X86-NEXT: %[[TOTALSZ:.*]] = add i32 %[[ARRSZ]], 4
// X64-NEXT: call void @"??_V@YAXPEAX_K@Z"(ptr noundef %2, i64 noundef %[[TOTALSZ]])
// X86-NEXT: call void @"??_V@YAXPAXI@Z"(ptr noundef %2, i32 noundef %[[TOTALSZ]])
// CHECK-NEXT: br label %dtor.continue
// CHECK: dtor.scalar:
// X64-NEXT: call void @"??1Derived@@UEAA@XZ"(ptr noundef nonnull align 8 dereferenceable(16) %this1)
// X86-NEXT: call x86_thiscallcc void @"??1Derived@@UAE@XZ"(ptr noundef nonnull align 4 dereferenceable(8) %this1)
// CHECK-NEXT: %6 = and i32 %should_call_delete2, 1
// CHECK-NEXT: %7 = icmp eq i32 %6, 0
// CHECK-NEXT: br i1 %7, label %dtor.continue, label %dtor.call_delete
// CHECK-NEXT: %8 = and i32 %should_call_delete2, 1
// CHECK-NEXT: %9 = icmp eq i32 %8, 0
// CHECK-NEXT: br i1 %9, label %dtor.continue, label %dtor.call_delete
// CHECK: dtor.call_delete:
// X64-NEXT: call void @"??3@YAXPEAX_K@Z"(ptr noundef %this1, i64 noundef 16)
// X86-NEXT: call void @"??3@YAXPAXI@Z"(ptr noundef %this1, i32 noundef 8)
// CHECK-NEXT: br label %dtor.continue
// CHECK: dtor.continue:
// CHECK-NEXT: %8 = load ptr, ptr %retval
// CHECK-NEXT: ret ptr %8
// CHECK-NEXT: %10 = load ptr, ptr %retval
// CHECK-NEXT: ret ptr %10

// X64: define weak dso_local noundef ptr @"??_EAllocatedAsArray@@UEAAPEAXI@Z"
// X86: define weak dso_local x86_thiscallcc noundef ptr @"??_EAllocatedAsArray@@UAEPAXI@Z"
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ void TesttheTest() {
// X64: define weak dso_local noundef ptr @"??_EDrawingBuffer@@UEAAPEAXI@Z"
// X64: call void @"??1DrawingBuffer@@UEAA@XZ"(ptr noundef nonnull align 8 dereferenceable(8) %arraydestroy.element)
// X64: call void @"??_V?$RefCounted@UDrawingBuffer@@@@SAXPEAX@Z"(ptr noundef %2)
// X64: call void @"??_V@YAXPEAX_K@Z"(ptr noundef %2, i64 noundef 8)
// X64: call void @"??_V@YAXPEAX_K@Z"(ptr noundef %2, i64 noundef %{{.*}})
// X64: call void @"??1DrawingBuffer@@UEAA@XZ"(ptr noundef nonnull align 8 dereferenceable(8) %this1)
// X64: call void @"??3@YAXPEAX_K@Z"(ptr noundef %this1, i64 noundef 8)
// X64: call void @"??3@YAXPEAX_K@Z"(ptr noundef %this1, i64 noundef {{.*}})


// X86: define dso_local void @"??3@YAXPAXI@Z"(ptr noundef %0, i32 noundef %1)
Expand All @@ -70,9 +70,9 @@ void TesttheTest() {
// X86: define weak dso_local x86_thiscallcc noundef ptr @"??_EDrawingBuffer@@UAEPAXI@Z"
// X86: call x86_thiscallcc void @"??1DrawingBuffer@@UAE@XZ"(ptr noundef nonnull align 4 dereferenceable(4) %arraydestroy.element)
// X86: call void @"??_V?$RefCounted@UDrawingBuffer@@@@SAXPAX@Z"(ptr noundef %2)
// X86: call void @"??_V@YAXPAXI@Z"(ptr noundef %2, i32 noundef 4)
// X86: call void @"??_V@YAXPAXI@Z"(ptr noundef %2, i32 noundef {{.*}})
// X86 call x86_thiscallcc void @"??1DrawingBuffer@@UAE@XZ"(ptr noundef nonnull align 4 dereferenceable(4) %this1)
// X86: call void @"??3@YAXPAXI@Z"(ptr noundef %this1, i32 noundef 4)
// X86: call void @"??3@YAXPAXI@Z"(ptr noundef %this1, i32 noundef {{.*}})


// X64: define weak dso_local noundef ptr @"??_ETest@@UEAAPEAXI@Z"(ptr noundef nonnull align 8 dereferenceable(8) %this, i32 noundef %should_call_delete)
Expand Down
54 changes: 54 additions & 0 deletions clang/test/CodeGenCXX/msvc-vector-deleting-dtors-sized-delete.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// RUN: %clang_cc1 -emit-llvm -fms-extensions %s -triple=x86_64-pc-windows-msvc -o - | FileCheck --check-prefixes=X64,CHECK %s
// RUN: %clang_cc1 -emit-llvm -fms-extensions %s -triple=i386-pc-windows-msvc -o - | FileCheck --check-prefixes=X86,CHECK %s

using size_t = __SIZE_TYPE__;
void operator delete[](void *ptr, size_t sz) { }

struct Test {
virtual ~Test() {}
void operator delete[](void *ptr, size_t sz) { }
int x;
int y;
};

void test() {
Test* a = new Test[10];
delete[] a;
}

// X64: define weak dso_local noundef ptr @"??_ETest@@UEAAPEAXI@Z"(
// X64-SAME: ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[IMPLICIT_PARAM:.*]])
// X86: define weak dso_local x86_thiscallcc noundef ptr @"??_ETest@@UAEPAXI@Z"(
// X86-SAME: ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[IMPLICIT_PARAM:.*]])
// CHECK: entry:
// CHECK-NEXT: %[[RET:.*]] = alloca ptr
// CHECK-NEXT: %[[IPADDR:.*]] = alloca i32
// CHECK-NEXT: %[[THISADDR:.*]] = alloca ptr
// CHECK-NEXT: store i32 %[[IMPLICIT_PARAM]], ptr %[[IPADDR]]
// CHECK-NEXT: store ptr %[[THIS]], ptr %[[THISADDR]]
// CHECK-NEXT: %[[LTHIS:.*]] = load ptr, ptr %[[THISADDR]]
// CHECK-NEXT: store ptr %[[LTHIS]], ptr %[[RET]]
// CHECK-NEXT: %[[LIP:.*]] = load i32, ptr %[[IPADDR]]
// CHECK-NEXT: %[[SECONDBIT:.*]] = and i32 %[[LIP]], 2
// CHECK-NEXT: %[[ISSECONDBITZERO:.*]] = icmp eq i32 %[[SECONDBIT]], 0
// CHECK-NEXT: br i1 %[[ISSECONDBITZERO:.*]], label %dtor.scalar, label %dtor.vector
// CHECK: dtor.vector:
// X64-NEXT: %[[COOKIEGEP:.*]] = getelementptr inbounds i8, ptr %[[LTHIS]], i64 -8
// X86-NEXT: %[[COOKIEGEP:.*]] = getelementptr inbounds i8, ptr %[[LTHIS]], i32 -4
// X64-NEXT: %[[HOWMANY:.*]] = load i64, ptr %[[COOKIEGEP]]
// X86-NEXT: %[[HOWMANY:.*]] = load i32, ptr %[[COOKIEGEP]]
// CHECK: dtor.call_class_delete_after_array_destroy:
// X64-NEXT: %[[ARRSZ:.*]] = mul i64 16, %[[HOWMANY]]
// X86-NEXT: %[[ARRSZ:.*]] = mul i32 12, %[[HOWMANY]]
// X64-NEXT: %[[TOTALSZ:.*]] = add i64 %[[ARRSZ]], 8
// X86-NEXT: %[[TOTALSZ:.*]] = add i32 %[[ARRSZ]], 4
// X64-NEXT: call void @"??_VTest@@SAXPEAX_K@Z"(ptr noundef %2, i64 noundef %[[TOTALSZ]])
// X86-NEXT: call void @"??_VTest@@SAXPAXI@Z"(ptr noundef %2, i32 noundef %[[TOTALSZ]])

// CHECK: dtor.call_glob_delete_after_array_destroy:
// X64-NEXT: %[[ARRSZ1:.*]] = mul i64 16, %[[HOWMANY]]
// X86-NEXT: %[[ARRSZ1:.*]] = mul i32 12, %[[HOWMANY]]
// X64-NEXT: %[[TOTALSZ1:.*]] = add i64 %[[ARRSZ1]], 8
// X86-NEXT: %[[TOTALSZ1:.*]] = add i32 %[[ARRSZ1]], 4
// X64-NEXT: call void @"??_V@YAXPEAX_K@Z"(ptr noundef %2, i64 noundef %[[TOTALSZ1]])
// X86-NEXT: call void @"??_V@YAXPAXI@Z"(ptr noundef %2, i32 noundef %[[TOTALSZ1]])
8 changes: 6 additions & 2 deletions clang/test/Modules/msvc-vector-deleting-destructors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@ void out_of_module_tests(Derived *p, Derived *p1) {
// CHECK32-NEXT: call void @"??_VBase1@@SAXPAX@Z"(ptr noundef %2)
// CHECK64-NEXT: call void @"??_VBase1@@SAXPEAX@Z"(ptr noundef %2)
// CHECK: dtor.call_glob_delete_after_array_destroy:
// CHECK32-NEXT: call void @"??_V@YAXPAXI@Z"(ptr noundef %2, i32 noundef 8)
// CHECK64-NEXT: call void @"??_V@YAXPEAX_K@Z"(ptr noundef %2, i64 noundef 16)
// CHECK64-NEXT: %[[ARRSZ:.*]] = mul i64 16, %[[COOKIE:.*]]
// CHECK32-NEXT: %[[ARRSZ:.*]] = mul i32 8, %[[COOKIE:.*]]
// CHECK64-NEXT: %[[TOTALSZ:.*]] = add i64 %[[ARRSZ]], 8
// CHECK32-NEXT: %[[TOTALSZ:.*]] = add i32 %[[ARRSZ]], 4
// CHECK32-NEXT: call void @"??_V@YAXPAXI@Z"(ptr noundef %2, i32 noundef %[[TOTALSZ]])
// CHECK64-NEXT: call void @"??_V@YAXPEAX_K@Z"(ptr noundef %2, i64 noundef %[[TOTALSZ]])
// CHECK: dtor.call_glob_delete:
// CHECK32-NEXT: call void @"??3@YAXPAXI@Z"(ptr noundef %this1, i32 noundef 8)
// CHECK64-NEXT: call void @"??3@YAXPEAX_K@Z"(ptr noundef %this1, i64 noundef 16)
Expand Down
8 changes: 6 additions & 2 deletions clang/test/PCH/msvc-vector-deleting-destructors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ void out_of_module_tests(Derived *p, Derived *p1) {
// CHECK32-NEXT: call void @"??_VBase1@@SAXPAX@Z"(ptr noundef %2)
// CHECK64-NEXT: call void @"??_VBase1@@SAXPEAX@Z"(ptr noundef %2)
// CHECK: dtor.call_glob_delete_after_array_destroy:
// CHECK32-NEXT: call void @"??_V@YAXPAXI@Z"(ptr noundef %2, i32 noundef 8)
// CHECK64-NEXT: call void @"??_V@YAXPEAX_K@Z"(ptr noundef %2, i64 noundef 16)
// CHECK64-NEXT: %[[ARRSZ:.*]] = mul i64 16, %[[COOKIE:.*]]
// CHECK32-NEXT: %[[ARRSZ:.*]] = mul i32 8, %[[COOKIE:.*]]
// CHECK64-NEXT: %[[TOTALSZ:.*]] = add i64 %[[ARRSZ]], 8
// CHECK32-NEXT: %[[TOTALSZ:.*]] = add i32 %[[ARRSZ]], 4
// CHECK32-NEXT: call void @"??_V@YAXPAXI@Z"(ptr noundef %2, i32 noundef %[[TOTALSZ]])
// CHECK64-NEXT: call void @"??_V@YAXPEAX_K@Z"(ptr noundef %2, i64 noundef %[[TOTALSZ]])
// CHECK: dtor.call_glob_delete:
// CHECK32-NEXT: call void @"??3@YAXPAXI@Z"(ptr noundef %this1, i32 noundef 8)
// CHECK64-NEXT: call void @"??3@YAXPEAX_K@Z"(ptr noundef %this1, i64 noundef 16)
Expand Down