Tested x86_64-pc-linux-gnu, applying to trunk. -- 8< --
Here limit_bad_template_recursion avoids instantiating foo, and then we wrongly warn that it isn't defined, because as a non-template (but templated) friend DECL_TEMPLATE_INSTANTIATION is false. gcc/cp/ChangeLog: * decl2.cc (c_parse_final_cleanups): Also check DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION. gcc/testsuite/ChangeLog: * g++.dg/diagnostic/used-inline1.C: New test. --- gcc/cp/decl2.cc | 3 ++- gcc/testsuite/g++.dg/diagnostic/used-inline1.C | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/diagnostic/used-inline1.C diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index e9ae979896c..c67e3e0c15f 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -5559,7 +5559,8 @@ c_parse_final_cleanups (void) && !(header_module_p () && (DECL_DEFAULTED_FN (decl) || decl_tls_wrapper_p (decl))) /* Don't complain if the template was defined. */ - && !(DECL_TEMPLATE_INSTANTIATION (decl) + && !((DECL_TEMPLATE_INSTANTIATION (decl) + || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)) && DECL_INITIAL (DECL_TEMPLATE_RESULT (template_for_substitution (decl)))) && warning_at (DECL_SOURCE_LOCATION (decl), 0, diff --git a/gcc/testsuite/g++.dg/diagnostic/used-inline1.C b/gcc/testsuite/g++.dg/diagnostic/used-inline1.C new file mode 100644 index 00000000000..ce4882eb994 --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/used-inline1.C @@ -0,0 +1,12 @@ +template <class T> struct A { + friend void foo(A*) { } // { dg-bogus "never defined" } + void bar() { + baz(this); // { dg-error "baz" } + foo(this); + } +}; + +int main() +{ + A<int>().bar(); +} base-commit: b222122d4e93de2238041a01b1886c7dfd9944da -- 2.46.0