diff options
author | Jason Merrill <jason@redhat.com> | 2023-04-03 18:23:58 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2023-04-03 23:20:27 -0400 |
commit | 0dfbb28a9549c2503204b0338bf550f1bff9c681 (patch) | |
tree | 5ec58c937f3e815881de0cb4ce0eaa522172eaaa | |
parent | 59b4a555c3f1c3dba376da1c4886a9ea18ad208d (diff) | |
download | gcc-0dfbb28a9549c2503204b0338bf550f1bff9c681.zip gcc-0dfbb28a9549c2503204b0338bf550f1bff9c681.tar.gz gcc-0dfbb28a9549c2503204b0338bf550f1bff9c681.tar.bz2 |
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.
-rw-r--r-- | gcc/cp/decl2.cc | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/friend25.C | 9 |
2 files changed, 14 insertions, 0 deletions
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index 2b195e9..9594be4 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 0000000..74cf5dc --- /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" } + }; +} |