On 5/30/25 3:50 PM, Iain Sandoe wrote:
Tested on x86_64-darwin (but does need the addition of the coroutine
keywords to dump_expr), OK for trunk?
Thanks,
Iain

OK.

--- 8< ---

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>
---
  gcc/cp/constexpr.cc                        |  3 ++
  gcc/testsuite/g++.dg/coroutines/pr118903.C | 40 ++++++++++++++++++++++
  2 files changed, 43 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/coroutines/pr118903.C

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 272fab32896..397d0be40df 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -11015,6 +11015,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 00000000000..a577a9a0a55
--- /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