aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorVlad Serebrennikov <serebrennikov.vladislav@gmail.com>2024-07-05 22:27:04 +0400
committerGitHub <noreply@github.com>2024-07-05 22:27:04 +0400
commit788731cdbd732180639988c9589adbe63bb28afa (patch)
tree09f805fc70bafbae3579889ba1f7f2180c8f8a0b /clang/lib
parent0f1da49b4d854ce7c6572000da3fb6cb0a1245d2 (diff)
downloadllvm-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.cpp12
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());
}