[clang] f332498 - [Clang] Do not emit exception diagnostics from coroutines and coroutine lambdas

Nikita Popov via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 28 02:41:16 PST 2023


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;
+};


        


More information about the cfe-commits mailing list