diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -614,6 +614,14 @@ // 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(E), D)) { + if (auto *FD = dyn_cast(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, 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(S.CurContext)->getLocation(),