diff options
author | Jason Merrill <jason@redhat.com> | 2022-06-06 21:49:06 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2022-06-08 16:37:50 -0400 |
commit | 7d87790a871482e9c5142a8e885b4a5f76d197c8 (patch) | |
tree | 325dc6c6b4fc7a1911fa124eb13a61cc3907856f /gcc/cp/decl.cc | |
parent | b6e1373bd34aebbb512a03ea9a4e3c7acd955382 (diff) | |
download | gcc-7d87790a871482e9c5142a8e885b4a5f76d197c8.zip gcc-7d87790a871482e9c5142a8e885b4a5f76d197c8.tar.gz gcc-7d87790a871482e9c5142a8e885b4a5f76d197c8.tar.bz2 |
c++: redeclared hidden friend take 2 [PR105852]
My previous patch for 105761 avoided copying DECL_TEMPLATE_INFO from a
friend to a later definition, but in this testcase we have first a
non-friend declaration and then a definition, and we need to avoid copying
in that case as well. But we do still want to set new_template_info to
avoid GC trouble.
With this change, the modules dump correctly identifies ::foo as a
non-template function in tpl-friend-2_a.C.
Along the way I noticed that the duplicate_decls handling of
DECL_UNIQUE_FRIEND_P was backwards for templates, where we don't clobber
DECL_LANG_SPECIFIC (olddecl) with DECL_LANG_SPECIFIC (newdecl) like we do
for non-templates.
PR c++/105852
PR c++/105761
gcc/cp/ChangeLog:
* decl.cc (duplicate_decls): Avoid copying template info
from non-templated friend even if newdecl isn't a definition.
Correct handling of DECL_UNIQUE_FRIEND_P on templates.
* pt.cc (non_templated_friend_p): New.
* cp-tree.h (non_templated_friend_p): Declare it.
gcc/testsuite/ChangeLog:
* g++.dg/modules/tpl-friend-2_a.C: Adjust expected dump.
* g++.dg/template/friend74.C: New test.
Diffstat (limited to 'gcc/cp/decl.cc')
-rw-r--r-- | gcc/cp/decl.cc | 16 |
1 files changed, 6 insertions, 10 deletions
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 7add82a..3e86995 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -2294,8 +2294,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) merge_default_template_args (new_parms, old_parms, /*class_p=*/false); } - if (!DECL_UNIQUE_FRIEND_P (old_result)) - DECL_UNIQUE_FRIEND_P (new_result) = false; + if (!DECL_UNIQUE_FRIEND_P (new_result)) + DECL_UNIQUE_FRIEND_P (old_result) = false; check_default_args (newdecl); @@ -2654,13 +2654,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) if (LANG_DECL_HAS_MIN (newdecl)) { DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl); - if (new_defines_function - && DECL_TEMPLATE_INFO (olddecl) - && DECL_UNIQUE_FRIEND_P (DECL_TEMPLATE_RESULT - (DECL_TI_TEMPLATE (olddecl)))) - /* Don't copy template info from a non-template friend declaration - in a class template (PR105761). */; - else if (DECL_TEMPLATE_INFO (newdecl)) + if (DECL_TEMPLATE_INFO (newdecl)) { new_template_info = DECL_TEMPLATE_INFO (newdecl); if (DECL_TEMPLATE_INSTANTIATION (olddecl) @@ -2668,8 +2662,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) /* Remember the presence of explicit specialization args. */ TINFO_USED_TEMPLATE_ID (DECL_TEMPLATE_INFO (olddecl)) = TINFO_USED_TEMPLATE_ID (new_template_info); - DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl); } + + if (non_templated_friend_p (olddecl)) + /* Don't copy tinfo from a non-templated friend (PR105761). */; else DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl); } |