From 3afc7c4eeada0a04c2c4ededeb0f6ccc724a58ec Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 1 Apr 2022 16:18:31 -0400 Subject: [PATCH] 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. --- gcc/cp/decl.cc | 5 +++++ gcc/testsuite/g++.dg/lookup/friend22.C | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 gcc/testsuite/g++.dg/lookup/friend22.C 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() {} +}; -- 2.47.2