https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125555

--- Comment #7 from Patrick Palka <ppalka at gcc dot gnu.org> ---
(In reply to Leander Schulten from comment #6)
> I asked claude back then when creating the issue and it came up with 
> 
> diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
> index d81db520bab83..1329c6e646b43 100644
> --- a/gcc/cp/module.cc
> +++ b/gcc/cp/module.cc
> @@ -15449,7 +15449,18 @@ depset::hash::add_specializations (bool decl_p)
>             else if (is_friend)
>               {
>                 if (TI_TEMPLATE (ti) != entry->tmpl
> -                   || !template_args_equal (TI_ARGS (ti), entry->tmpl))
> +                   && template_args_equal (TI_ARGS (ti), entry->args))
> +                 /* SPEC is an implicit instantiation of a hidden friend
> +                    template.  It is keyed in the specialization table to
> +                    the most general template (ENTRY->TMPL), but it was
> +                    produced from the per-class pseudo-instantiation of the
> +                    friend (TI_TEMPLATE).  This is a genuine specialization
> +                    that importers must be able to merge with equivalent
> +                    instantiations of their own, so record it as an ordinary
> +                    specialization rather than dropping it as a friend clone
> +                    (PR c++/125552).  */
> +                 is_friend = false;
> +               else
>                   goto template_friend;
>               }
>           }
> with tests and commit msg:
> https://github.com/autoantwort/gcc/commit/
> 44074a193ddc506296b47c1fc1d05d772f8ff871
Interesting! It seems to cleanly pass the modules testsuite too.

I think the template_args_equal check is redundant because if TI_TEMPLATE (ti)
and entry->tmpl are the same then we should be able to assume the args are the
same. So we could remove the template_args_equal check, or convert it to a
checking_assert.  Other than that the justification seems sound.  The
TI_TEMPLATE (ti) != entry->tmpl check effectively distinguishes between partial
and full instantiations of a template friend (of a class template).  So
concretely for comment #2's operator== we continue to treat the {{int},{_Iter}}
specialization as a friend "clone" and not record it, while treating the
{{int},{__normal_iterator<int>}} specialization as an ordinary specialization
and setting is_friend=false, which makes sense to me.

Jason, what do you think?

Reply via email to