From: Jason Merrill Date: Mon, 3 Apr 2023 22:23:58 +0000 (-0400) Subject: c++: friend template matching [PR107484] X-Git-Tag: basepoints/gcc-14~215 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0dfbb28a9549c2503204b0338bf550f1bff9c681;p=thirdparty%2Fgcc.git 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. --- 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 void f(T*); + struct X { + friend void qualified_friend_no_match::f(double); // { dg-error "does not match any template" } + }; +}