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