diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 07e17f9f71072e..436743564c2586 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -2509,7 +2509,7 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings( // Check for throw out of non-throwing function. if (!Diags.isIgnored(diag::warn_throw_in_noexcept_func, D->getBeginLoc())) if (const FunctionDecl *FD = dyn_cast(D)) - if (S.getLangOpts().CPlusPlus && isNoexcept(FD)) + if (S.getLangOpts().CPlusPlus && !fscope->isCoroutine() && isNoexcept(FD)) checkThrowInNonThrowingFunc(S, FD, AC); // Emit unsafe buffer usage warnings and fixits. diff --git a/clang/test/SemaCXX/warn-throw-out-noexcept-coro.cpp b/clang/test/SemaCXX/warn-throw-out-noexcept-coro.cpp new file mode 100644 index 00000000000000..4d52bdca7ca93c --- /dev/null +++ b/clang/test/SemaCXX/warn-throw-out-noexcept-coro.cpp @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -std=c++20 %s -fcxx-exceptions -fsyntax-only -Wexceptions -verify -fdeclspec + +#include "Inputs/std-coroutine.h" + +// expected-no-diagnostics + +template +struct promise; + +template +struct task { + using promise_type = promise; + + explicit task(promise_type& p) { throw 1; p.return_val = this; } + + task(const task&) = delete; + + T value; +}; + +template +struct promise { + task get_return_object() { return task{*this}; } + + std::suspend_never initial_suspend() const noexcept { return {}; } + + std::suspend_never final_suspend() const noexcept { return {}; } + + template + void return_value(U&& val) { return_val->value = static_cast(val); } + + void unhandled_exception() { throw 1; } + + task* return_val; +}; + +task a_ShouldNotDiag(const int a, const int b) { + if (b == 0) + throw b; + + co_return a / b; +} + +task b_ShouldNotDiag(const int a, const int b) noexcept { + if (b == 0) + throw b; + + co_return a / b; +} + +const auto c_ShouldNotDiag = [](const int a, const int b) -> task { + if (b == 0) + throw b; + + co_return a / b; +}; + +const auto d_ShouldNotDiag = [](const int a, const int b) noexcept -> task { + if (b == 0) + throw b; + + co_return a / b; +};