]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: prev declared hidden tmpl friend inst, cont [PR119807]
authorPatrick Palka <ppalka@redhat.com>
Tue, 15 Apr 2025 13:06:40 +0000 (09:06 -0400)
committerPatrick Palka <ppalka@redhat.com>
Tue, 15 Apr 2025 13:06:40 +0000 (09:06 -0400)
commit369461d0749790f1291f76096064d583d2547934
treeb7d8f3c6d4aeababe6c63a9857eb9a4caed08e74
parentf5ed7d19c965de9ccb158d77e929b17459bf65b5
c++: prev declared hidden tmpl friend inst, cont [PR119807]

When remapping existing specializations of a hidden template friend from
a previous declaration to the new definition, we must remap only those
specializations that match this new definition, but currently we
remap all specializations (since they all appear in the same
DECL_TEMPLATE_INSTANTIATIONS list of the most general template).

Concretely, in the first testcase below, we form two specializations of
the friend A::f, one with arguments {{0},{bool}} and another with
arguments {{1},{bool}}.  Later when instantiating B, we need to remap
these specializations.  During the B<0> instantiation we only want to
remap the first specialization, and during the B<1> instantiation only
the second specialization, but currently we remap both specializations
twice.

tsubst_friend_function needs to determine if an existing specialization
matches the shape of the new definition, which is tricky in general,
e.g. if the outer template parameters may not match up.  Fortunately we
don't have to reinvent the wheel here since is_specialization_of_friend
seems to do exactly what we need.  We can check this unconditionally,
but I think it's only necessary when dealing with specializations formed
from a class template scope previous declaration, hence the
TMPL_ARGS_HAVE_MULTIPLE_LEVELS check.

PR c++/119807
PR c++/112288

gcc/cp/ChangeLog:

* pt.cc (tsubst_friend_function): Skip remapping an
existing specialization if it doesn't match the shape of
the new friend definition.

gcc/testsuite/ChangeLog:

* g++.dg/template/friend86.C: New test.
* g++.dg/template/friend87.C: New test.

Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/pt.cc
gcc/testsuite/g++.dg/template/friend86.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/friend87.C [new file with mode: 0644]