Author: Deniz Evrenci Date: 2023-02-28T11:41:07+01:00 New Revision: f332498f9880d276890562fb861a375a13bfd9d9
URL: https://github.com/llvm/llvm-project/commit/f332498f9880d276890562fb861a375a13bfd9d9 DIFF: https://github.com/llvm/llvm-project/commit/f332498f9880d276890562fb861a375a13bfd9d9.diff LOG: [Clang] Do not emit exception diagnostics from coroutines and coroutine lambdas All exceptions thrown in coroutine bodies are caught and unhandled_exception member of the coroutine promise type is called. In accordance with the existing rules of diagnostics related to exceptions thrown in functions marked noexcept, even if the promise type's constructor, get_return_object, or unhandled_exception throws, diagnostics should not be emitted. Fixes #48797. Differential Revision: https://reviews.llvm.org/D144352 Added: clang/test/SemaCXX/warn-throw-out-noexcept-coro.cpp Modified: clang/lib/Sema/AnalysisBasedWarnings.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 07e17f9f71072..436743564c258 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<FunctionDecl>(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 0000000000000..4d52bdca7ca93 --- /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 <typename T> +struct promise; + +template <typename T> +struct task { + using promise_type = promise<T>; + + explicit task(promise_type& p) { throw 1; p.return_val = this; } + + task(const task&) = delete; + + T value; +}; + +template <typename T> +struct promise { + task<T> get_return_object() { return task{*this}; } + + std::suspend_never initial_suspend() const noexcept { return {}; } + + std::suspend_never final_suspend() const noexcept { return {}; } + + template <typename U> + void return_value(U&& val) { return_val->value = static_cast<U&&>(val); } + + void unhandled_exception() { throw 1; } + + task<T>* return_val; +}; + +task<int> a_ShouldNotDiag(const int a, const int b) { + if (b == 0) + throw b; + + co_return a / b; +} + +task<int> 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<int> { + if (b == 0) + throw b; + + co_return a / b; +}; + +const auto d_ShouldNotDiag = [](const int a, const int b) noexcept -> task<int> { + if (b == 0) + throw b; + + co_return a / b; +}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits