aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.cc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2022-06-06 21:49:06 -0400
committerJason Merrill <jason@redhat.com>2022-06-08 16:37:50 -0400
commit7d87790a871482e9c5142a8e885b4a5f76d197c8 (patch)
tree325dc6c6b4fc7a1911fa124eb13a61cc3907856f /gcc/cp/decl.cc
parentb6e1373bd34aebbb512a03ea9a4e3c7acd955382 (diff)
downloadgcc-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.cc16
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);
}