From: Jason Merrill Date: Fri, 1 Apr 2022 20:18:31 +0000 (-0400) Subject: c++: repeated friend template [PR101894] X-Git-Tag: basepoints/gcc-13~328 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3afc7c4eeada0a04c2c4ededeb0f6ccc724a58ec;p=thirdparty%2Fgcc.git c++: repeated friend template [PR101894] Since olddecl isn't a definition, it doesn't get DECL_FRIEND_CONTEXT, so we need to copy it from newdecl when we merge the declarations. PR c++/101894 gcc/cp/ChangeLog: * decl.cc (duplicate_decls): Copy DECL_FRIEND_CONTEXT. gcc/testsuite/ChangeLog: * g++.dg/lookup/friend22.C: New test. --- diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 69f60a6dc0f1..0ff13e99595b 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -2344,6 +2344,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) for (parm = DECL_ARGUMENTS (old_result); parm; parm = DECL_CHAIN (parm)) DECL_CONTEXT (parm) = old_result; + + if (tree fc = DECL_FRIEND_CONTEXT (new_result)) + SET_DECL_FRIEND_CONTEXT (old_result, fc); } } @@ -2667,6 +2670,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) otherwise it is a DECL_FRIEND_CONTEXT. */ if (DECL_VIRTUAL_P (newdecl)) SET_DECL_THUNKS (newdecl, DECL_THUNKS (olddecl)); + else if (tree fc = DECL_FRIEND_CONTEXT (newdecl)) + SET_DECL_FRIEND_CONTEXT (olddecl, fc); } else if (VAR_P (newdecl)) { diff --git a/gcc/testsuite/g++.dg/lookup/friend22.C b/gcc/testsuite/g++.dg/lookup/friend22.C new file mode 100644 index 000000000000..f52a7d7bad56 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/friend22.C @@ -0,0 +1,7 @@ +// PR c++/101894 + +struct A +{ + template friend void foo(); + template friend void foo() {} +};