diff options
author | Vlad Serebrennikov <serebrennikov.vladislav@gmail.com> | 2024-07-05 22:27:04 +0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-05 22:27:04 +0400 |
commit | 788731cdbd732180639988c9589adbe63bb28afa (patch) | |
tree | 09f805fc70bafbae3579889ba1f7f2180c8f8a0b /clang/lib | |
parent | 0f1da49b4d854ce7c6572000da3fb6cb0a1245d2 (diff) | |
download | llvm-788731cdbd732180639988c9589adbe63bb28afa.zip llvm-788731cdbd732180639988c9589adbe63bb28afa.tar.gz llvm-788731cdbd732180639988c9589adbe63bb28afa.tar.bz2 |
[clang] Implement P3144R2 "Deleting a Pointer to an Incomplete Type..." (#97733)
This patch implements (not yet published)
[P3144R2](https://wiki.edg.com/pub/Wg21stlouis2024/StrawPolls/p3144r2.pdf)
"Deleting a Pointer to an Incomplete Type Should be Ill-formed". Wording
changes (not yet merged into the working draft) read:
> 7.6.2.9 [expr.delete] Delete
> If the object being deleted has incomplete class type at the point of
deletion <del>and the complete class has a
non-trivial destructor or a deallocation function, the behavior is
undefined</del>, <ins>the program is ill-formed</ins>.
We preserve status quo of emitting a warning when deleting a pointer to
incomplete type up to, and including, C++23, but make it ill-formed
since C++26. Same goes for deleting pointers to `void`, which has been
allowed as an extension.
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 69074f9..fcf2189 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()); } |