https://gcc.gnu.org/g:0ae77a05c416c9f750cb87f1bef0800651168b7e

commit r16-1059-g0ae77a05c416c9f750cb87f1bef0800651168b7e
Author: Iain Sandoe <i...@sandoe.co.uk>
Date:   Fri May 30 20:09:40 2025 +0100

    c++: Emit an error for attempted constexpr co_await [PR118903].
    
    We checked that the coroutine expressions were not suitable for
    constexpr, but did not emit and error when needed.
    
            PR c++/118903
    
    gcc/cp/ChangeLog:
    
            * constexpr.cc (potential_constant_expression_1): Emit
            an error when co_await et. al. are used in constexpr
            contexts.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/coroutines/pr118903.C: New test.
    
    Signed-off-by: Iain Sandoe <i...@sandoe.co.uk>

Diff:
---
 gcc/cp/constexpr.cc                        |  3 +++
 gcc/testsuite/g++.dg/coroutines/pr118903.C | 40 ++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 61481c6f7a02..3a87e73a4d0f 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -11024,6 +11024,9 @@ potential_constant_expression_1 (tree t, bool 
want_rval, bool strict, bool now,
     case CO_AWAIT_EXPR:
     case CO_YIELD_EXPR:
     case CO_RETURN_EXPR:
+      if (flags & tf_error)
+       constexpr_error (cp_expr_loc_or_loc (t, input_location), fundef_p,
+                        "%qE is not a constant expression", t);
       return false;
 
     /* Assume a TU-local entity is not constant, we'll error later when
diff --git a/gcc/testsuite/g++.dg/coroutines/pr118903.C 
b/gcc/testsuite/g++.dg/coroutines/pr118903.C
new file mode 100644
index 000000000000..a577a9a0a552
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr118903.C
@@ -0,0 +1,40 @@
+// { dg-additional-options "-fsyntax-only" }
+
+#include <coroutine>
+
+struct awaitable {
+    constexpr bool await_ready() {
+        return true;
+    }
+    void await_suspend(std::coroutine_handle<void>) {
+
+    }
+    constexpr int await_resume() {
+        return 42;
+    }
+};
+
+struct super_simple_coroutine {
+    struct promise_type {
+        constexpr auto initial_suspend() {
+            return std::suspend_never();
+        }
+        constexpr auto final_suspend() const noexcept {
+            return std::suspend_never();
+        }
+        constexpr void unhandled_exception() {
+            // do nothing
+        }
+        constexpr auto get_return_object() {
+            return super_simple_coroutine{};
+        }
+        constexpr void return_void() {
+        }
+    };
+};
+
+auto fib (float f) -> super_simple_coroutine {
+    // if `co_await` is part of BodyStatement of a function
+    // it makes it coroutine
+    constexpr int x = co_await awaitable{}; // { dg-error {'co_await 
awaitable..' is not a constant expression} }
+}

Reply via email to