https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/97733
>From f009148063ba41d39fc844f4432ceb51377f381c Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Date: Thu, 4 Jul 2024 17:05:11 +0300 Subject: [PATCH 1/3] [clang] Implement P3144R2 "Deleting a Pointer to an Incomplete Type Should be Ill-formed" --- .../clang/Basic/DiagnosticSemaKinds.td | 2 ++ clang/lib/Sema/SemaExprCXX.cpp | 12 ++++++--- clang/test/CXX/drs/cwg5xx.cpp | 22 +++++++++------- clang/test/SemaCXX/new-delete.cpp | 26 ++++++++++++------- 4 files changed, 41 insertions(+), 21 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 3df64b2ecef1b2..5c3e311ac63829 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7991,6 +7991,8 @@ def err_ambiguous_delete_operand : Error< def warn_delete_incomplete : Warning< "deleting pointer to incomplete type %0 may cause undefined behavior">, InGroup<DeleteIncomplete>; +def err_delete_incomplete : Error< + "cannot delete pointer to incomplete type %0">; def err_delete_incomplete_class_type : Error< "deleting incomplete class type %0; no conversions to pointer type">; def err_delete_explicit_conversion : Error< diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 69074f92a0286b..fcf2189a308a86 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -3719,8 +3719,11 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, // The C++ standard bans deleting a pointer to a non-object type, which // effectively bans deletion of "void*". However, most compilers support // this, so we treat it as a warning unless we're in a SFINAE context. - Diag(StartLoc, diag::ext_delete_void_ptr_operand) - << Type << Ex.get()->getSourceRange(); + // But we still prohibit this since C++26. + Diag(StartLoc, LangOpts.CPlusPlus26 ? diag::err_delete_incomplete + : diag::ext_delete_void_ptr_operand) + << (LangOpts.CPlusPlus26 ? Pointee : Type) + << Ex.get()->getSourceRange(); } else if (Pointee->isFunctionType() || Pointee->isVoidType() || Pointee->isSizelessType()) { return ExprError(Diag(StartLoc, diag::err_delete_operand) @@ -3729,7 +3732,10 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, // FIXME: This can result in errors if the definition was imported from a // module but is hidden. if (!RequireCompleteType(StartLoc, Pointee, - diag::warn_delete_incomplete, Ex.get())) { + LangOpts.CPlusPlus26 + ? diag::err_delete_incomplete + : diag::warn_delete_incomplete, + Ex.get())) { if (const RecordType *RT = PointeeElem->getAs<RecordType>()) PointeeRD = cast<CXXRecordDecl>(RT->getDecl()); } diff --git a/clang/test/CXX/drs/cwg5xx.cpp b/clang/test/CXX/drs/cwg5xx.cpp index 9d890f981348a7..6a0bb7a1966693 100644 --- a/clang/test/CXX/drs/cwg5xx.cpp +++ b/clang/test/CXX/drs/cwg5xx.cpp @@ -1,9 +1,10 @@ -// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-11,cxx98-14,cxx98-17,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx98-11,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx17,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx23,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-23,cxx98-11,cxx98-14,cxx98-17,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx98-23,cxx98-11,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx98-23,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++17 %s -verify=expected,cxx98-23,since-cxx17,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++20 %s -verify=expected,cxx98-23,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++23 %s -verify=expected,cxx98-23,since-cxx23,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx26,since-cxx23,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors #if __cplusplus == 199711L #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) @@ -901,7 +902,8 @@ namespace cwg573 { // cwg573: no void *d = reinterpret_cast<void*>(c); // cxx98-error@-1 {{cast between pointer-to-function and pointer-to-object is an extension}} void f() { delete a; } - // expected-error@-1 {{cannot delete expression with pointer-to-'void' type 'void *'}} + // cxx98-23-error@-1 {{cannot delete expression with pointer-to-'void' type 'void *'}} + // since-cxx26-error@-2 {{cannot delete pointer to incomplete type 'void'}} int n = d - a; // expected-error@-1 {{arithmetic on pointers to void}} // FIXME: This is ill-formed. @@ -1238,11 +1240,13 @@ namespace cwg599 { // cwg599: partial struct V { operator int*(); operator Fn*(); }; void f(void *p, void (*q)(), S s, T t, U u, V v) { delete p; - // expected-error@-1 {{cannot delete expression with pointer-to-'void' type 'void *'}} + // cxx98-23-error@-1 {{cannot delete expression with pointer-to-'void' type 'void *'}} + // since-cxx26-error@-2 {{cannot delete pointer to incomplete type 'void'}} delete q; // expected-error@-1 {{cannot delete expression of type 'void (*)()'}} delete s; - // expected-error@-1 {{cannot delete expression with pointer-to-'void' type 'void *'}} + // cxx98-23-error@-1 {{cannot delete expression with pointer-to-'void' type 'void *'}} + // since-cxx26-error@-2 {{cannot delete pointer to incomplete type 'void'}} delete t; // expected-error@-1 {{cannot delete expression of type 'T'}} // FIXME: This is valid, but is rejected due to a non-conforming GNU diff --git a/clang/test/SemaCXX/new-delete.cpp b/clang/test/SemaCXX/new-delete.cpp index 1a99c6aac604f5..ec6ad43476f944 100644 --- a/clang/test/SemaCXX/new-delete.cpp +++ b/clang/test/SemaCXX/new-delete.cpp @@ -1,8 +1,10 @@ -// RUN: %clang_cc1 -fsyntax-only -verify=expected,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++98 -// RUN: %clang_cc1 -fsyntax-only -verify=expected,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++11 -// RUN: %clang_cc1 -fsyntax-only -verify=expected,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++14 -// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++17 -// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17,cxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++20 +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98-23,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++98 +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98-23,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98-23,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++14 +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98-23,cxx17,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++17 +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98-23,cxx17,cxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++20 +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98-23,cxx17,cxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++23 +// RUN: %clang_cc1 -fsyntax-only -verify=expected,since-cxx26,cxx17,cxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++2c // FIXME Location is (frontend) // cxx17-note@*:* {{candidate function not viable: requires 2 arguments, but 3 were provided}} @@ -172,8 +174,12 @@ void bad_deletes() { delete 0; // expected-error {{cannot delete expression of type 'int'}} delete [0] (int*)0; // expected-error {{expected variable name or 'this' in lambda capture list}} - delete (void*)0; // expected-warning {{cannot delete expression with pointer-to-'void' type 'void *'}} - delete (T*)0; // expected-warning {{deleting pointer to incomplete type}} + delete (void*)0; + // cxx98-23-warning@-1 {{cannot delete expression with pointer-to-'void' type 'void *'}} + // since-cxx26-error@-2 {{cannot delete pointer to incomplete type 'void'}} + delete (T*)0; + // cxx98-23-warning@-1 {{deleting pointer to incomplete type}} + // since-cxx26-error@-2 {{cannot delete pointer to incomplete type 'T'}} ::S::delete (int*)0; // expected-error {{expected unqualified-id}} } @@ -513,8 +519,10 @@ namespace DeleteIncompleteClass { namespace DeleteIncompleteClassPointerError { struct A; // expected-note {{forward declaration}} - void f(A *x) { 1+delete x; } // expected-warning {{deleting pointer to incomplete type}} \ - // expected-error {{invalid operands to binary expression}} + void f(A *x) { 1+delete x; } + // expected-error@-1 {{invalid operands to binary expression}} + // cxx98-23-warning@-2 {{deleting pointer to incomplete type}} + // since-cxx26-error@-3 {{cannot delete pointer to incomplete type 'A'}} } namespace PR10504 { >From bdcc4ab396e2ed65e23afe4409b3d1487e16e806 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Date: Fri, 5 Jul 2024 12:07:29 +0300 Subject: [PATCH 2/3] Address feedback --- clang/docs/ReleaseNotes.rst | 4 ++++ clang/include/clang/Basic/DiagnosticGroups.td | 2 ++ clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 +++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f149684214567d..3a3dec4cbc60a0 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -265,6 +265,7 @@ C++2c Feature Support - Implemented `P2809R3: Trivial infinite loops are not Undefined Behavior <https://wg21.link/P2809R3>`_. +- Implemented `P3144R2 Deleting a Pointer to an Incomplete Type Should be Ill-formed <https://wg21.link/P3144R2>`_. Resolutions to C++ Defect Reports ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -431,6 +432,9 @@ New Compiler Flags Matches MSVC behaviour by defining ``__STDC__`` to ``1`` when MSVC compatibility mode is used. It has no effect for C++ code. +- ``-Wc++2c-compat``group was added to help migrating existing codebases + to C++26. + Deprecated Compiler Flags ------------------------- diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 9431eea1f6be22..0fc87b45ba05a7 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -420,6 +420,8 @@ def CXX20CompatPedantic : DiagGroup<"c++20-compat-pedantic", def : DiagGroup<"c++2a-compat", [CXX20Compat]>; def : DiagGroup<"c++2a-compat-pedantic", [CXX20CompatPedantic]>; +def CXX26Compat : DiagGroup<"c++2c-compat", []>; + def ExitTimeDestructors : DiagGroup<"exit-time-destructors">; def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">; def FourByteMultiChar : DiagGroup<"four-char-constants">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5c3e311ac63829..c0a9fa6cbacb6d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7989,8 +7989,9 @@ def ext_delete_void_ptr_operand : ExtWarn< def err_ambiguous_delete_operand : Error< "ambiguous conversion of delete expression of type %0 to a pointer">; def warn_delete_incomplete : Warning< - "deleting pointer to incomplete type %0 may cause undefined behavior">, - InGroup<DeleteIncomplete>; + "deleting pointer to incomplete type %0 is incompatible with C++2c" + " and may cause undefined behavior">, + InGroup<CXX26Compat>; def err_delete_incomplete : Error< "cannot delete pointer to incomplete type %0">; def err_delete_incomplete_class_type : Error< >From 3a28e5223fe85971d2afcd27a4af6a26368f0b37 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Date: Fri, 5 Jul 2024 13:05:32 +0300 Subject: [PATCH 3/3] Change C++ Status page accordingly --- clang/www/cxx_status.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html index f12ce38ba3d79c..0c013e6d7cb58d 100755 --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -213,7 +213,7 @@ <h2 id="cxx26">C++2c implementation status</h2> <tr> <td>Deleting a Pointer to an Incomplete Type Should be Ill-formed</td> <td><a href="https://wg21.link/P3144">P3144R2</a></td> - <td class="none" align="center">No</td> + <td class="Unreleased" align="center">Clang 19</td> </tr> <tr> <td>Ordering of constraints involving fold expressions</td> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits