https://github.com/ankit-cybertron updated https://github.com/llvm/llvm-project/pull/213455
>From b09136141651917ef6f3531a15929aa8a44cb25c Mon Sep 17 00:00:00 2001 From: Ankit Kumar Tiwari <[email protected]> Date: Sat, 1 Aug 2026 20:24:16 +0530 Subject: [PATCH 1/4] [Clang] Skip type-aware delete resolution for incomplete types + test --- clang/lib/Sema/SemaExprCXX.cpp | 15 ++++++---- .../type-aware-delete-incomplete-type.cpp | 30 +++++++++++++++++++ 2 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 clang/test/SemaCXX/type-aware-delete-incomplete-type.cpp diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 538604aa2e64b..e8e109d40ced8 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4149,10 +4149,15 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName( ArrayForm ? OO_Array_Delete : OO_Delete); + bool IsComplete = isCompleteType(StartLoc, Pointee); + TypeAwareAllocationMode PassTypeIdentity = + IsComplete ? ShouldUseTypeAwareOperatorNewOrDelete() + : TypeAwareAllocationMode::No; + if (PointeeRD) { - ImplicitDeallocationParameters IDP = { - Pointee, ShouldUseTypeAwareOperatorNewOrDelete(), - AlignedAllocationMode::No, SizedDeallocationMode::No}; + ImplicitDeallocationParameters IDP = {Pointee, PassTypeIdentity, + AlignedAllocationMode::No, + SizedDeallocationMode::No}; if (!UseGlobal && FindDeallocationFunction(StartLoc, PointeeRD, DeleteName, OperatorDelete, IDP)) @@ -4199,7 +4204,6 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, return ExprError(); } - bool IsComplete = isCompleteType(StartLoc, Pointee); bool CanProvideSize = IsComplete && (!ArrayForm || UsualArrayDeleteWantsSize || Pointee.isDestructedType()); @@ -4207,8 +4211,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, // Look for a global declaration. ImplicitDeallocationParameters IDP = { - Pointee, ShouldUseTypeAwareOperatorNewOrDelete(), - alignedAllocationModeFromBool(Overaligned), + Pointee, PassTypeIdentity, alignedAllocationModeFromBool(Overaligned), sizedDeallocationModeFromBool(CanProvideSize)}; OperatorDelete = FindUsualDeallocationFunction(StartLoc, IDP, DeleteName); if (!OperatorDelete) diff --git a/clang/test/SemaCXX/type-aware-delete-incomplete-type.cpp b/clang/test/SemaCXX/type-aware-delete-incomplete-type.cpp new file mode 100644 index 0000000000000..2eb74beaec8d0 --- /dev/null +++ b/clang/test/SemaCXX/type-aware-delete-incomplete-type.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify=warn %s +// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify=warn %s +// RUN: %clang_cc1 -std=c++26 -fsyntax-only -verify=err %s +// RUN: %clang_cc1 -std=c++17 -emit-llvm -o - %s | FileCheck %s + +class Foo; // warn-note {{forward declaration of 'Foo'}} \ + // err-note {{forward declaration of 'Foo'}} + +typedef __SIZE_TYPE__ size_t; + +namespace std { + enum class align_val_t : size_t {}; + template <class T> struct type_identity { + typedef T type; + }; +} + +template <class T> +void operator delete(std::type_identity<T>, void *, size_t, std::align_val_t); // warn-warning {{type aware allocators are a Clang extension}} \ + // err-warning {{type aware allocators are a Clang extension}} + +void f(Foo *o) { + delete o; + // warn-warning@-1 {{deleting pointer to incomplete type 'Foo' is incompatible with C++2c and may cause undefined behavior}} + // err-error@-2 {{cannot delete pointer to incomplete type 'Foo'}} +} + +// CHECK-LABEL: define {{.*}} @_Z1fP3Foo +// CHECK-NOT: call {{.*}} @{{.*}}operator delete{{.*}}type_identity +// CHECK: call void @_ZdlPv \ No newline at end of file >From 8895993e2023881aee12f91e2336e3a9a04b7218 Mon Sep 17 00:00:00 2001 From: Ankit Kumar Tiwari <[email protected]> Date: Mon, 3 Aug 2026 00:33:16 +0530 Subject: [PATCH 2/4] Add warning when dropping type-aware delete for incomplete types --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 ++++ clang/lib/Sema/SemaExprCXX.cpp | 7 +++++-- clang/test/SemaCXX/type-aware-delete-incomplete-type.cpp | 8 +++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index cce6f70a58893..e45a5e4c4cb08 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10444,6 +10444,10 @@ def err_destroying_operator_delete_not_usual : Error< def err_type_aware_destroying_operator_delete : Error< "destroying delete is not permitted to be type aware">; +def warn_type_aware_delete_incomplete : Warning< + "type-aware deallocation is not used for deletion of " + "pointer to incomplete type %0">, + InGroup<DeleteIncomplete>; def warn_ext_type_aware_allocators : ExtWarn< "type aware allocators are a Clang extension">, InGroup<DiagGroup<"ext-cxx-type-aware-allocators">>; def err_type_aware_allocator_missing_matching_operator : Error< diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index e8e109d40ced8..54bd27ff853d1 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4151,8 +4151,11 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, bool IsComplete = isCompleteType(StartLoc, Pointee); TypeAwareAllocationMode PassTypeIdentity = - IsComplete ? ShouldUseTypeAwareOperatorNewOrDelete() - : TypeAwareAllocationMode::No; + ShouldUseTypeAwareOperatorNewOrDelete(); + if (!IsComplete && isTypeAwareAllocation(PassTypeIdentity)) { + Diag(StartLoc, diag::warn_type_aware_delete_incomplete) << Pointee; + PassTypeIdentity = TypeAwareAllocationMode::No; + } if (PointeeRD) { ImplicitDeallocationParameters IDP = {Pointee, PassTypeIdentity, diff --git a/clang/test/SemaCXX/type-aware-delete-incomplete-type.cpp b/clang/test/SemaCXX/type-aware-delete-incomplete-type.cpp index 2eb74beaec8d0..610fd8a81a74b 100644 --- a/clang/test/SemaCXX/type-aware-delete-incomplete-type.cpp +++ b/clang/test/SemaCXX/type-aware-delete-incomplete-type.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify=warn %s // RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify=warn %s // RUN: %clang_cc1 -std=c++26 -fsyntax-only -verify=err %s -// RUN: %clang_cc1 -std=c++17 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s class Foo; // warn-note {{forward declaration of 'Foo'}} \ // err-note {{forward declaration of 'Foo'}} @@ -21,8 +21,10 @@ void operator delete(std::type_identity<T>, void *, size_t, std::align_val_t); / void f(Foo *o) { delete o; - // warn-warning@-1 {{deleting pointer to incomplete type 'Foo' is incompatible with C++2c and may cause undefined behavior}} - // err-error@-2 {{cannot delete pointer to incomplete type 'Foo'}} + // warn-warning@-1 {{type-aware deallocation is not used for deletion of pointer to incomplete type 'Foo'}} + // warn-warning@-2 {{deleting pointer to incomplete type 'Foo' is incompatible with C++2c and may cause undefined behavior}} + // err-warning@-3 {{type-aware deallocation is not used for deletion of pointer to incomplete type 'Foo'}} + // err-error@-4 {{cannot delete pointer to incomplete type 'Foo'}} } // CHECK-LABEL: define {{.*}} @_Z1fP3Foo >From 58ff52629ea67fd553ea82a1717af64451ec18bd Mon Sep 17 00:00:00 2001 From: Ankit Kumar Tiwari <[email protected]> Date: Sun, 9 Aug 2026 02:36:38 +0530 Subject: [PATCH 3/4] Add error for type-aware binding to incomplete types --- .../clang/Basic/DiagnosticSemaKinds.td | 3 ++ clang/lib/Sema/SemaExprCXX.cpp | 13 ++++---- .../type-aware-delete-incomplete-type.cpp | 30 +++++++++++++------ 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index e45a5e4c4cb08..8d959bd907eb7 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10448,6 +10448,9 @@ def warn_type_aware_delete_incomplete : Warning< "type-aware deallocation is not used for deletion of " "pointer to incomplete type %0">, InGroup<DeleteIncomplete>; +def err_type_aware_delete_incomplete : Error< + "type-aware deallocation function matches incomplete type %0; " + "the type must be complete to use type-aware deallocation">; def warn_ext_type_aware_allocators : ExtWarn< "type aware allocators are a Clang extension">, InGroup<DiagGroup<"ext-cxx-type-aware-allocators">>; def err_type_aware_allocator_missing_matching_operator : Error< diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 54bd27ff853d1..e9917a08a6f89 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4152,10 +4152,6 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, bool IsComplete = isCompleteType(StartLoc, Pointee); TypeAwareAllocationMode PassTypeIdentity = ShouldUseTypeAwareOperatorNewOrDelete(); - if (!IsComplete && isTypeAwareAllocation(PassTypeIdentity)) { - Diag(StartLoc, diag::warn_type_aware_delete_incomplete) << Pointee; - PassTypeIdentity = TypeAwareAllocationMode::No; - } if (PointeeRD) { ImplicitDeallocationParameters IDP = {Pointee, PassTypeIdentity, @@ -4242,11 +4238,16 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, unsigned AddressParamIdx = 0; if (OperatorDelete->isTypeAwareOperatorNewOrDelete()) { + if (!IsComplete) { + Diag(StartLoc, diag::err_type_aware_delete_incomplete) << Pointee; + return ExprError(); + } QualType TypeIdentity = OperatorDelete->getParamDecl(0)->getType(); - if (RequireCompleteType(StartLoc, TypeIdentity, - diag::err_incomplete_type)) + if (RequireCompleteType(StartLoc, TypeIdentity, diag::err_incomplete_type)) return ExprError(); AddressParamIdx = 1; + } else if (!IsComplete && isTypeAwareAllocation(PassTypeIdentity)) { + Diag(StartLoc, diag::warn_type_aware_delete_incomplete) << Pointee; } // Convert the operand to the type of the first parameter of operator diff --git a/clang/test/SemaCXX/type-aware-delete-incomplete-type.cpp b/clang/test/SemaCXX/type-aware-delete-incomplete-type.cpp index 610fd8a81a74b..7fb2698997b7b 100644 --- a/clang/test/SemaCXX/type-aware-delete-incomplete-type.cpp +++ b/clang/test/SemaCXX/type-aware-delete-incomplete-type.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify=warn %s // RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify=warn %s // RUN: %clang_cc1 -std=c++26 -fsyntax-only -verify=err %s -// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -DCODEGEN -emit-llvm -o - %s | FileCheck %s class Foo; // warn-note {{forward declaration of 'Foo'}} \ // err-note {{forward declaration of 'Foo'}} @@ -15,18 +15,30 @@ namespace std { }; } -template <class T> -void operator delete(std::type_identity<T>, void *, size_t, std::align_val_t); // warn-warning {{type aware allocators are a Clang extension}} \ +void operator delete(std::type_identity<Foo>, void *, size_t, std::align_val_t); // warn-warning {{type aware allocators are a Clang extension}} \ // err-warning {{type aware allocators are a Clang extension}} +#ifndef CODEGEN void f(Foo *o) { delete o; - // warn-warning@-1 {{type-aware deallocation is not used for deletion of pointer to incomplete type 'Foo'}} - // warn-warning@-2 {{deleting pointer to incomplete type 'Foo' is incompatible with C++2c and may cause undefined behavior}} - // err-warning@-3 {{type-aware deallocation is not used for deletion of pointer to incomplete type 'Foo'}} - // err-error@-4 {{cannot delete pointer to incomplete type 'Foo'}} + // warn-warning@-1 {{deleting pointer to incomplete type 'Foo' is incompatible with C++2c and may cause undefined behavior}} + // warn-error@-2 {{type-aware deallocation function matches incomplete type 'Foo'; the type must be complete to use type-aware deallocation}} + // err-error@-3 {{cannot delete pointer to incomplete type 'Foo'}} + // err-error@-4 {{type-aware deallocation function matches incomplete type 'Foo'; the type must be complete to use type-aware deallocation}} } +#endif -// CHECK-LABEL: define {{.*}} @_Z1fP3Foo +class Bar; // warn-note {{forward declaration of 'Bar'}} \ + // err-note {{forward declaration of 'Bar'}} + +void g(Bar *b) { + delete b; + // warn-warning@-1 {{type-aware deallocation is not used for deletion of pointer to incomplete type 'Bar'}} + // warn-warning@-2 {{deleting pointer to incomplete type 'Bar' is incompatible with C++2c and may cause undefined behavior}} + // err-warning@-3 {{type-aware deallocation is not used for deletion of pointer to incomplete type 'Bar'}} + // err-error@-4 {{cannot delete pointer to incomplete type 'Bar'}} +} + +// CHECK-LABEL: define {{.*}} @_Z1gP3Bar // CHECK-NOT: call {{.*}} @{{.*}}operator delete{{.*}}type_identity -// CHECK: call void @_ZdlPv \ No newline at end of file +// CHECK: call void @_ZdlPv >From 4d5b6a4e83b2e7a62e09149eb26f1963d722ea4c Mon Sep 17 00:00:00 2001 From: Ankit Kumar Tiwari <[email protected]> Date: Sun, 9 Aug 2026 02:40:45 +0530 Subject: [PATCH 4/4] Fix formatting --- clang/lib/Sema/SemaExprCXX.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index e9917a08a6f89..07a32e98ccd9e 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4243,7 +4243,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, return ExprError(); } QualType TypeIdentity = OperatorDelete->getParamDecl(0)->getType(); - if (RequireCompleteType(StartLoc, TypeIdentity, diag::err_incomplete_type)) + if (RequireCompleteType(StartLoc, TypeIdentity, + diag::err_incomplete_type)) return ExprError(); AddressParamIdx = 1; } else if (!IsComplete && isTypeAwareAllocation(PassTypeIdentity)) { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
