On 6/2/25 6:28 PM, Iain Sandoe wrote:
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.
This is good, but I'd also expect namespace context to take priority
over innermost_non_namespace_value just above?
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;
+}