aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaExceptionSpec.cpp
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2024-12-05 14:26:33 -0500
committerGitHub <noreply@github.com>2024-12-05 14:26:33 -0500
commit91354fb1469620cc92c4bf1a11444b2e7f13d54d (patch)
treeeb3adc0df314375c442983d24c2d16536942272c /clang/lib/Sema/SemaExceptionSpec.cpp
parent2214e02378185cec51eedb68c028342c8c19740b (diff)
downloadllvm-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.cpp17
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));
}