summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2022-06-03 12:35:12 -0400
committerJason Merrill <jason@redhat.com>2022-06-03 14:11:55 -0400
commit2843bfa21073dd1ac222540e189e8bcf40afc2c0 (patch)
tree0d4914cb36bd1dd9ef1878f5907043fa15684870
parentc++: constexpr empty aggr [PR105795] (diff)
c++: redeclared hidden friend [PR105761]
Here, when we see the second declaration of f we match it with the first one, copy over DECL_TEMPLATE_INFO, and then try to use it when parsing the definition, leading to confusion. PR c++/105761 gcc/cp/ChangeLog: * decl.cc (duplicate_decls): Don't copy DECL_TEMPLATE_INFO from a hidden friend. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/auto-fn64.C: New test.
-rw-r--r--gcc/cp/decl.cc12
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/auto-fn64.C12
2 files changed, 22 insertions, 2 deletions
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 269c6679ca26..f53136cc04d6 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -2655,7 +2655,13 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
2655 if (LANG_DECL_HAS_MIN (newdecl)) 2655 if (LANG_DECL_HAS_MIN (newdecl))
2656 { 2656 {
2657 DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl); 2657 DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl);
2658 if (DECL_TEMPLATE_INFO (newdecl)) 2658 if (new_defines_function
2659 && DECL_TEMPLATE_INFO (olddecl)
2660 && DECL_UNIQUE_FRIEND_P (DECL_TEMPLATE_RESULT
2661 (DECL_TI_TEMPLATE (olddecl))))
2662 /* Don't copy template info from a non-template friend declaration
2663 in a class template (PR105761). */;
2664 else if (DECL_TEMPLATE_INFO (newdecl))
2659 { 2665 {
2660 new_template_info = DECL_TEMPLATE_INFO (newdecl); 2666 new_template_info = DECL_TEMPLATE_INFO (newdecl);
2661 if (DECL_TEMPLATE_INSTANTIATION (olddecl) 2667 if (DECL_TEMPLATE_INSTANTIATION (olddecl)
@@ -2663,8 +2669,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
2663 /* Remember the presence of explicit specialization args. */ 2669 /* Remember the presence of explicit specialization args. */
2664 TINFO_USED_TEMPLATE_ID (DECL_TEMPLATE_INFO (olddecl)) 2670 TINFO_USED_TEMPLATE_ID (DECL_TEMPLATE_INFO (olddecl))
2665 = TINFO_USED_TEMPLATE_ID (new_template_info); 2671 = TINFO_USED_TEMPLATE_ID (new_template_info);
2672 DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
2666 } 2673 }
2667 DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl); 2674 else
2675 DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
2668 } 2676 }
2669 2677
2670 if (DECL_DECLARES_FUNCTION_P (newdecl)) 2678 if (DECL_DECLARES_FUNCTION_P (newdecl))
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn64.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn64.C
new file mode 100644
index 000000000000..13f3175da45b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn64.C
@@ -0,0 +1,12 @@
1// PR c++/105761
2// { dg-do compile { target c++14 } }
3// { dg-additional-options -Wno-non-template-friend }
4
5template <class T>
6class X {
7 friend auto f(X);
8};
9
10struct Y : X<long> {
11 friend auto f(X) { return 0L; }
12};