> On 2 Jun 2025, at 17:10, Andrew Pinski <pins...@gmail.com> wrote:
> 
> On Mon, Jun 2, 2025 at 8:17 AM Jason Merrill <ja...@redhat.com> wrote:
>> 
>> On 6/2/25 5:13 AM, Iain Sandoe wrote:
>>> 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.
>> 
>> Hmm, this seems like a longstanding (since the implementation of
>> namespaces in r19631) bug in lookup_template_class; if context is a
>> namespace, I'd expect that to bypass any local declaration.

Ah good, that was actually my expectation too.

> Yes and this was mentioned while I was fixing PR 115605
> (https://inbox.sourceware.org/gcc-patches/5d1efe6a-d2f2-4b37-aa92-ce3a73739...@redhat.com/).
> I didn't get some time to look into changing that yet.
> 
> Iain, if you look into fixing lookup_template_class, check the
> testcases for PR 115605 at the same time too.

OK.. I can take a look (we need a solution somehow) - although I have some 
concerns about fallout.
Iain

> 
> Thanks,
> Andrew
> 
> 
>> 
>>> 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();
>>> +}

Reply via email to