From ac24fa46e449fbff0ff571951cfcc78b8488f6e7 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 8 Apr 2021 01:03:28 -0400 Subject: [PATCH] c++: improve specialization mismatch diagnostic [PR94529] We were telling users they needed more template<> to specialize a member template in a testcase with no member templates. Only produce that message if we actually see a member template, and also always print the candidates. gcc/cp/ChangeLog: PR c++/94529 * pt.c (determine_specialization): Improve diagnostic. gcc/testsuite/ChangeLog: PR c++/94529 * g++.dg/template/mem-spec2.C: New test. --- gcc/cp/pt.c | 11 +++++++---- gcc/testsuite/g++.dg/template/mem-spec2.C | 11 +++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/mem-spec2.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index dee8021..46b237f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2201,6 +2201,7 @@ determine_specialization (tree template_id, ++header_count; tree orig_fns = fns; + bool header_mismatch = false; if (variable_template_p (fns)) { @@ -2248,7 +2249,10 @@ determine_specialization (tree template_id, specialization but rather a template instantiation, so there is no check we can perform here. */ if (header_count && header_count != template_count + 1) - continue; + { + header_mismatch = true; + continue; + } /* Check that the number of template arguments at the innermost level for DECL is the same as for FN. */ @@ -2482,13 +2486,12 @@ determine_specialization (tree template_id, { error ("template-id %qD for %q+D does not match any template " "declaration", template_id, decl); - if (header_count && header_count != template_count + 1) + if (header_mismatch) inform (DECL_SOURCE_LOCATION (decl), "saw %d %%>, need %d for " "specializing a member function template", header_count, template_count + 1); - else - print_candidates (orig_fns); + print_candidates (orig_fns); return error_mark_node; } else if ((templates && TREE_CHAIN (templates)) diff --git a/gcc/testsuite/g++.dg/template/mem-spec2.C b/gcc/testsuite/g++.dg/template/mem-spec2.C new file mode 100644 index 0000000..bc96159 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/mem-spec2.C @@ -0,0 +1,11 @@ +// PR c++/94529 + +template +struct foo { + // the issue is const here + void bar(T& foobar) const { foobar = 0; } // { dg-message "candidate" } +}; + +template <> void +foo::bar(int& foobar) { foobar = 9; } // { dg-error "does not match" } +// { dg-bogus "member function template" "" { target *-*-* } .-1 } -- 2.7.4