-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[clang][win] Fix size passed to delete[] in vector deleting destructors #172513
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-clang-modules @llvm/pr-subscribers-clang Author: Mariya Podchishchaeva (Fznamznon) ChangesDue to missing parameters only size of a single array element was passed. Reported by #170337 (comment) Full diff: https://github.com/llvm/llvm-project/pull/172513.diff 6 Files Affected:
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 826f5799bae3c..a5096506f0ab1 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -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
@@ -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.
diff --git a/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors.cpp b/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors.cpp
index e8012abb79aee..cbce869fb21b6 100644
--- a/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors.cpp
+++ b/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors.cpp
@@ -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]])
@@ -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
@@ -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"
diff --git a/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp b/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp
index 1b1564227c40f..b16cb30d7133f 100644
--- a/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp
+++ b/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp
@@ -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)
@@ -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)
diff --git a/clang/test/CodeGenCXX/msvc-vector-deleting-dtors-sized-delete.cpp b/clang/test/CodeGenCXX/msvc-vector-deleting-dtors-sized-delete.cpp
new file mode 100644
index 0000000000000..6c9faa88e08e9
--- /dev/null
+++ b/clang/test/CodeGenCXX/msvc-vector-deleting-dtors-sized-delete.cpp
@@ -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]])
diff --git a/clang/test/Modules/msvc-vector-deleting-destructors.cpp b/clang/test/Modules/msvc-vector-deleting-destructors.cpp
index a0806054355db..68faa687251d7 100644
--- a/clang/test/Modules/msvc-vector-deleting-destructors.cpp
+++ b/clang/test/Modules/msvc-vector-deleting-destructors.cpp
@@ -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)
diff --git a/clang/test/PCH/msvc-vector-deleting-destructors.cpp b/clang/test/PCH/msvc-vector-deleting-destructors.cpp
index f548dba8efd20..1409b41d2df82 100644
--- a/clang/test/PCH/msvc-vector-deleting-destructors.cpp
+++ b/clang/test/PCH/msvc-vector-deleting-destructors.cpp
@@ -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)
|
|
@llvm/pr-subscribers-clang-codegen Author: Mariya Podchishchaeva (Fznamznon) ChangesDue to missing parameters only size of a single array element was passed. Reported by #170337 (comment) Full diff: https://github.com/llvm/llvm-project/pull/172513.diff 6 Files Affected:
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 826f5799bae3c..a5096506f0ab1 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -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
@@ -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.
diff --git a/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors.cpp b/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors.cpp
index e8012abb79aee..cbce869fb21b6 100644
--- a/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors.cpp
+++ b/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors.cpp
@@ -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]])
@@ -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
@@ -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"
diff --git a/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp b/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp
index 1b1564227c40f..b16cb30d7133f 100644
--- a/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp
+++ b/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp
@@ -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)
@@ -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)
diff --git a/clang/test/CodeGenCXX/msvc-vector-deleting-dtors-sized-delete.cpp b/clang/test/CodeGenCXX/msvc-vector-deleting-dtors-sized-delete.cpp
new file mode 100644
index 0000000000000..6c9faa88e08e9
--- /dev/null
+++ b/clang/test/CodeGenCXX/msvc-vector-deleting-dtors-sized-delete.cpp
@@ -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]])
diff --git a/clang/test/Modules/msvc-vector-deleting-destructors.cpp b/clang/test/Modules/msvc-vector-deleting-destructors.cpp
index a0806054355db..68faa687251d7 100644
--- a/clang/test/Modules/msvc-vector-deleting-destructors.cpp
+++ b/clang/test/Modules/msvc-vector-deleting-destructors.cpp
@@ -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)
diff --git a/clang/test/PCH/msvc-vector-deleting-destructors.cpp b/clang/test/PCH/msvc-vector-deleting-destructors.cpp
index f548dba8efd20..1409b41d2df82 100644
--- a/clang/test/PCH/msvc-vector-deleting-destructors.cpp
+++ b/clang/test/PCH/msvc-vector-deleting-destructors.cpp
@@ -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)
|
efriedma-quic
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
zmodem
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for the quick fix!
Due to missing parameters to
EmitDeleteCallonly size of a single array element was passed todelete[].Reported by #170337 (comment)