https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112288
--- Comment #12 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Patrick Palka <ppa...@gcc.gnu.org>: https://gcc.gnu.org/g:30dd420a06ad7d2adf4a672d176caee632f8168a commit r15-2120-g30dd420a06ad7d2adf4a672d176caee632f8168a Author: Patrick Palka <ppa...@redhat.com> Date: Wed Jul 17 21:02:52 2024 -0400 c++: prev declared hidden tmpl friend inst [PR112288] When partially instantiating a previously declared hidden template friend definition (at class template scope) such as slot_allocated in the first testcase below, tsubst_friend_function needs to go through all existing specializations thereof and make them point to the new definition. But when the previous declaration was also at class template scope, old_decl is not the most general template, instead it's the partial instantiation, and since instantiations are relative to the most general template, old_decl's DECL_TEMPLATE_INSTANTIATIONS is empty. So we to consistently use the most general template here. And when adjusting DECL_TI_ARGS to match, only the innermost template arguments should be preserved; the outer ones should correspond to the new definition. Otherwise we fail a checking-only sanity check in instantiate_decl in the first testcase, and in the second/third we end up emitting multiple definitions of the template friend instantiation, resulting in a link failure. PR c++/112288 gcc/cp/ChangeLog: * pt.cc (tsubst_friend_function): When adjusting existing specializations after defining a previously declared template friend, consider the most general template and correct DECL_TI_ARGS adjustment. gcc/testsuite/ChangeLog: * g++.dg/template/friend80.C: New test. * g++.dg/template/friend81.C: New test. * g++.dg/template/friend81a.C: New test. Reviewed-by: Jason Merrill <ja...@redhat.com>