From 0dfbb28a9549c2503204b0338bf550f1bff9c681 Mon Sep 17 00:00:00 2001 From: Jason Merrill <jason@redhat.com> Date: Mon, 3 Apr 2023 18:23:58 -0400 Subject: [PATCH] c++: friend template matching [PR107484] Here friend matching tries to find a matching non-template friend and fails, so we mark the friend as a template specialization to be determined later. Then cplus_decl_attributes tries again to find a matching function and gets confused by DECL_TEMPLATE_INSTANTIATION without DECL_TEMPLATE_INFO. But it doesn't make sense for find_last_decl to be trying to match anything with DECL_USE_TEMPLATE set; those are matched elsewhere. PR c++/107484 gcc/cp/ChangeLog: * decl2.cc (find_last_decl): Return early if DECL_USE_TEMPLATE. gcc/testsuite/ChangeLog: * g++.dg/lookup/friend25.C: New test. --- gcc/cp/decl2.cc | 5 +++++ gcc/testsuite/g++.dg/lookup/friend25.C | 9 +++++++++ 2 files changed, 14 insertions(+) create mode 100644 gcc/testsuite/g++.dg/lookup/friend25.C diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index 2b195e999975..9594be4092c3 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -1613,6 +1613,11 @@ find_last_decl (tree decl) if (tree name = DECL_P (decl) ? DECL_NAME (decl) : NULL_TREE) { + /* Template specializations are matched elsewhere. */ + if (DECL_LANG_SPECIFIC (decl) + && DECL_USE_TEMPLATE (decl)) + return NULL_TREE; + /* Look up the declaration in its scope. */ tree pushed_scope = NULL_TREE; if (tree ctype = DECL_CONTEXT (decl)) diff --git a/gcc/testsuite/g++.dg/lookup/friend25.C b/gcc/testsuite/g++.dg/lookup/friend25.C new file mode 100644 index 000000000000..74cf5dc34319 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/friend25.C @@ -0,0 +1,9 @@ +// PR c++/107484 + +namespace qualified_friend_no_match { + void f(int); + template<typename T> void f(T*); + struct X { + friend void qualified_friend_no_match::f(double); // { dg-error "does not match any template" } + }; +} -- GitLab