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;
+}

Reply via email to