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.

Reply via email to