https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112341
--- Comment #4 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The trunk branch has been updated by Arsen Arsenovic <ar...@gcc.gnu.org>: https://gcc.gnu.org/g:32e678b2ed752154b2f96719e33f11a7c6417f20 commit r15-2540-g32e678b2ed752154b2f96719e33f11a7c6417f20 Author: Arsen ArsenoviÄ <ar...@aarsen.me> Date: Tue Jul 30 23:36:24 2024 +0200 c++/coroutines: only defer expanding co_{await,return,yield} if dependent [PR112341] By doing so, we can get diagnostics in template decls when we know we can. For instance, in the following: awaitable g(); template<typename> task f() { co_await g(); co_yield 1; co_return "foo"; } ... the coroutine promise type in each statement is always std::coroutine_handle<task>::promise_type, and all of the operands are not type-dependent, so we can always compute the resulting types (and expected types) of these expressions and statements. Also, when we do not know the type of the CO_AWAIT_EXPR or CO_YIELD_EXPR, we now return NULL_TREE as the type rather than unknown_type_node. This is more correct, since the type is not unknown, it just isn't determined yet. This also means we can remove the CO_AWAIT_EXPR and CO_YIELD_EXPR special-cases from type_dependent_expression_p. PR c++/112341 - error: insufficient contextual information to determine type on co_await result in function template gcc/cp/ChangeLog: PR c++/112341 * coroutines.cc (struct coroutine_info): Also cache the traits type. (ensure_coro_initialized): New function. Makes sure we have initialized the coroutine state successfully, or informs the caller should it fail to do so. Extracted from coro_promise_type_found_p. (coro_get_traits_class): New function. Gets the (cached) coroutine traits type for a given coroutine. Extracted from coro_promise_type_found_p and refactored to cache the result. (coro_promise_type_found_p): Use the two functions above. (build_template_co_await_expr): New function. Builds a CO_AWAIT_EXPR representing a CO_AWAIT_EXPR in a template declaration. (build_co_await): Use the above if processing_template_decl, and give it a proper type. (coro_dependent_p): New function. Returns true iff its argument is a type-dependent expression OR the current functions traits class is type dependent. (finish_co_await_expr): Defer expansion only in the case coro_dependent_p returns true. (finish_co_yield_expr): Ditto. (finish_co_return_stmt): Ditto. * pt.cc (type_dependent_expression_p): Do not treat CO_AWAIT/CO_YIELD specially. gcc/testsuite/ChangeLog: PR c++/112341 * g++.dg/coroutines/pr112341-2.C: New test. * g++.dg/coroutines/pr112341-3.C: New test. * g++.dg/coroutines/torture/co-yield-03-tmpl-nondependent.C: New test. * g++.dg/coroutines/pr112341.C: New test.