Tested on x86_64-darwin, OK for trunk? thanks Iain --- 8< ---
Using lookup_template_class () directly on the coroutine_handle identifier fails in the reported test because the using TYPE_DECL is found. Fix this by looking up the std::coroutine_handle template specifically and then instantiating that. PR c++/120495 gcc/cp/ChangeLog: * coroutines.cc (instantiate_coro_handle_for_promise_type): Lookup the coroutine handle template specifically and then instantiate that. gcc/testsuite/ChangeLog: * g++.dg/coroutines/pr120495.C: New test. Signed-off-by: Iain Sandoe <i...@sandoe.co.uk> --- gcc/cp/coroutines.cc | 17 ++++--- gcc/testsuite/g++.dg/coroutines/pr120495.C | 55 ++++++++++++++++++++++ 2 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/coroutines/pr120495.C diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 42f719ddde1..7ea1ad7c3aa 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -609,16 +609,21 @@ get_handle_type_from_address (location_t kw, tree handle_type) static tree instantiate_coro_handle_for_promise_type (location_t kw, tree promise_type) { + /* Look up the template. */ + tree handle_type = find_coro_handle_template_decl (kw); + if (!handle_type) + return NULL_TREE; + /* So now build up a type list for the template, one entry, the promise. */ tree targ = make_tree_vec (1); TREE_VEC_ELT (targ, 0) = promise_type; - tree handle_type - = lookup_template_class (coro_handle_identifier, targ, - /* in_decl=*/NULL_TREE, - /* context=*/std_node, - tf_warning_or_error); - if (handle_type == error_mark_node) + /* Instantiate for the promise type. */ + handle_type + = lookup_template_class (handle_type, targ, /*in_decl*/NULL_TREE, + /*context*/std_node, tf_warning_or_error); + + if (!handle_type || handle_type == error_mark_node) { error_at (kw, "cannot instantiate a %<coroutine handle%> for" " promise type %qT", promise_type); diff --git a/gcc/testsuite/g++.dg/coroutines/pr120495.C b/gcc/testsuite/g++.dg/coroutines/pr120495.C new file mode 100644 index 00000000000..f59c34a8676 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr120495.C @@ -0,0 +1,55 @@ +// { dg-additional-options "-fsyntax-only" } + +#include <coroutine> +#include <exception> + +struct fire_and_forget { +}; + +template <typename... Args> +struct std::coroutine_traits<fire_and_forget, Args...> +{ + struct promise_type + { + fire_and_forget get_return_object() const noexcept + { + return{}; + } + + void return_void() const noexcept + { + } + + suspend_never initial_suspend() const noexcept + { + return{}; + } + + suspend_never final_suspend() const noexcept + { + return{}; + } + + void unhandled_exception() const noexcept + { + std::terminate(); + } + }; +}; + +struct foo +{ + fire_and_forget bar() + { + co_await std::suspend_always{ }; + } + +private: + // The line below triggered the error. + using coroutine_handle = std::coroutine_handle<>; +}; + +int main() +{ + foo{}.bar(); +} -- 2.39.2 (Apple Git-143)