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

Reply via email to