diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2024-12-05 14:26:33 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-05 14:26:33 -0500 |
commit | 91354fb1469620cc92c4bf1a11444b2e7f13d54d (patch) | |
tree | eb3adc0df314375c442983d24c2d16536942272c /clang/lib/Sema/SemaExceptionSpec.cpp | |
parent | 2214e02378185cec51eedb68c028342c8c19740b (diff) | |
download | llvm-91354fb1469620cc92c4bf1a11444b2e7f13d54d.zip llvm-91354fb1469620cc92c4bf1a11444b2e7f13d54d.tar.gz llvm-91354fb1469620cc92c4bf1a11444b2e7f13d54d.tar.bz2 |
[C++20] Destroying delete can cause a type to be noexcept when deleting (#118687)
Given a `noexcept` operator with an operand that calls `delete`, Clang
was not considering whether the selected `operator delete` function was
a destroying delete or not when inspecting whether the deleted object
type has a throwing destructor. Thus, the operator would return `false`
for a type with a potentially throwing destructor even though that
destructor would not be called due to the destroying delete. Clang now
takes the kind of delete operator into consideration.
Fixes #118660
Diffstat (limited to 'clang/lib/Sema/SemaExceptionSpec.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExceptionSpec.cpp | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index ecfd79a..6a9f43d 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1205,15 +1205,16 @@ CanThrowResult Sema::canThrow(const Stmt *S) { if (DTy.isNull() || DTy->isDependentType()) { CT = CT_Dependent; } else { - CT = canCalleeThrow(*this, DE, DE->getOperatorDelete()); - if (const RecordType *RT = DTy->getAs<RecordType>()) { - const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); - const CXXDestructorDecl *DD = RD->getDestructor(); - if (DD) - CT = mergeCanThrow(CT, canCalleeThrow(*this, DE, DD)); + const FunctionDecl *OperatorDelete = DE->getOperatorDelete(); + CT = canCalleeThrow(*this, DE, OperatorDelete); + if (!OperatorDelete->isDestroyingOperatorDelete()) { + if (const auto *RD = DTy->getAsCXXRecordDecl()) { + if (const CXXDestructorDecl *DD = RD->getDestructor()) + CT = mergeCanThrow(CT, canCalleeThrow(*this, DE, DD)); + } + if (CT == CT_Can) + return CT; } - if (CT == CT_Can) - return CT; } return mergeCanThrow(CT, canSubStmtsThrow(*this, DE)); } |