[clang] 3661595 - [Coroutines] Special handle __builtin_coro_resume for final_suspend nothrow check
Xun Li via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 25 10:49:57 PDT 2020
Author: Xun Li
Date: 2020-06-25T10:49:50-07:00
New Revision: 366159566df3a980d3e34f3ec9609e77cdb4df8b
URL: https://github.com/llvm/llvm-project/commit/366159566df3a980d3e34f3ec9609e77cdb4df8b
DIFF: https://github.com/llvm/llvm-project/commit/366159566df3a980d3e34f3ec9609e77cdb4df8b.diff
LOG: [Coroutines] Special handle __builtin_coro_resume for final_suspend nothrow check
Summary:
In https://reviews.llvm.org/D82029 we added the conformance check that the expression co_await promise.final_suspend() should not potentially throw.
As part of this expression, in cases when the await_suspend() method of the final suspend awaiter returns a handle, __builtin_coro_resume could be called on the handle to immediately resume that coroutine.
__builtin_coro_resume is not declared with noexcept and it shouldn't. We need to special check this case here.
Reviewers: modocache, lewissbaker, junparser
Reviewed By: lewissbaker
Subscribers: modocache, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D82415
Added:
Modified:
clang/lib/Sema/SemaCoroutine.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index c8ca247aae83..6262f4b117d3 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -614,6 +614,17 @@ static void checkNoThrow(Sema &S, const Stmt *E,
// In the case of dtor, the call to dtor is implicit and hence we should
// pass nullptr to canCalleeThrow.
if (Sema::canCalleeThrow(S, IsDtor ? nullptr : cast<Expr>(E), D)) {
+ if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
+ // co_await promise.final_suspend() could end up calling
+ // __builtin_coro_resume for symmetric transfer if await_suspend()
+ // returns a handle. In that case, even __builtin_coro_resume is not
+ // declared as noexcept and may throw, it does not throw _into_ the
+ // coroutine that just suspended, but rather throws back out from
+ // whoever called coroutine_handle::resume(), hence we claim that
+ // logically it does not throw.
+ if (FD->getBuiltinID() == Builtin::BI__builtin_coro_resume)
+ return;
+ }
if (ThrowingDecls.empty()) {
// First time seeing an error, emit the error message.
S.Diag(cast<FunctionDecl>(S.CurContext)->getLocation(),
More information about the cfe-commits
mailing list