Tested on x86_64-darwin and powerpc64le so far, how does this look? 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. This is because lookup is called with default parameters that means class contexts are examined first. Fix this by looking in namespace context when the caller provides a namespace parameter. PR c++/120495 PR c++/115605 gcc/cp/ChangeLog: * pt.cc (lookup_template_class): Honour provided namespace contexts when looking up class templates. gcc/testsuite/ChangeLog: * g++.dg/coroutines/pr120495.C: New test. * g++.dg/pr115605.C: New test. Signed-off-by: Iain Sandoe <i...@sandoe.co.uk> --- gcc/cp/pt.cc | 3 +- gcc/testsuite/g++.dg/coroutines/pr120495.C | 55 ++++++++++++++++++++++ gcc/testsuite/g++.dg/pr115605.C | 10 ++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/coroutines/pr120495.C create mode 100644 gcc/testsuite/g++.dg/pr115605.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index c5a3abe6d8b..d2e4692dbed 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -10088,7 +10088,8 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, { if (context) push_decl_namespace (context); - templ = lookup_name (d1); + templ = lookup_name (d1, context ? LOOK_where::NAMESPACE + : LOOK_where::ALL, LOOK_want::NORMAL); templ = maybe_get_template_decl_from_type_decl (templ); if (context) pop_decl_namespace (); 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(); +} diff --git a/gcc/testsuite/g++.dg/pr115605.C b/gcc/testsuite/g++.dg/pr115605.C new file mode 100644 index 00000000000..9e342555c89 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr115605.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++20 } } + +#include <array> + +int foo() { + int const tuple_size = 5; + std::array<int, 3> array {1, 2, 3}; + auto [a, b, c] = array; + return c; +} -- 2.39.2 (Apple Git-143)