Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,8 @@ Bug Fixes in This Version
- Fixed a crash when GNU statement expression contains invalid statement (#GH113468).
- Fixed a failed assertion when using ``__attribute__((noderef))`` on an
``_Atomic``-qualified type (#GH116124).
- No longer incorrectly diagnosing use of a deleted destructor when the
selected overload of ``operator delete`` for that type is a destroying delete.

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3792,13 +3792,15 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
.HasSizeT;
}

if (!PointeeRD->hasIrrelevantDestructor())
if (!PointeeRD->hasIrrelevantDestructor() &&
(!OperatorDelete || !OperatorDelete->isDestroyingOperatorDelete())) {
if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) {
MarkFunctionReferenced(StartLoc,
const_cast<CXXDestructorDecl*>(Dtor));
const_cast<CXXDestructorDecl *>(Dtor));
if (DiagnoseUseOfDecl(Dtor, StartLoc))
return ExprError();
}
}

CheckVirtualDtorCall(PointeeRD->getDestructor(), StartLoc,
/*IsDelete=*/true, /*CallCanBeVirtual=*/true,
Expand Down
22 changes: 20 additions & 2 deletions clang/test/CXX/expr/expr.unary/expr.delete/p10.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
// RUN: %clang_cc1 -std=c++1z -verify %s
// RUN: %clang_cc1 -std=c++20 -verify %s

using size_t = decltype(sizeof(0));
namespace std { enum class align_val_t : size_t {}; }
namespace std {
enum class align_val_t : size_t {};
struct destroying_delete_t {
explicit destroying_delete_t() = default;
};

inline constexpr destroying_delete_t destroying_delete{};
}

// Aligned version is preferred over unaligned version,
// unsized version is preferred over sized version.
Expand All @@ -23,3 +30,14 @@ struct alignas(Align) B {
};
void f(B<__STDCPP_DEFAULT_NEW_ALIGNMENT__> *p) { delete p; }
void f(B<__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2> *p) { delete p; } // expected-error {{deleted}}

// Ensure that a deleted destructor is acceptable when the selected overload
// for operator delete is a destroying delete. See the comments in GH118660.
struct S {
~S() = delete;
void operator delete(S *, std::destroying_delete_t) noexcept {}
};

void foo(S *s) {
delete s; // Was rejected, is intended to be accepted.
}
Loading