aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-04-08 01:03:28 -0400
committerJason Merrill <jason@redhat.com>2021-04-08 07:58:40 -0400
commitac24fa46e449fbff0ff571951cfcc78b8488f6e7 (patch)
treedd9ddd62074c1c4746200d8dd58a3ffe66292122
parent2cd5333d16419f596d07a830bb3f1c40fa8a7b5c (diff)
downloadgcc-ac24fa46e449fbff0ff571951cfcc78b8488f6e7.zip
gcc-ac24fa46e449fbff0ff571951cfcc78b8488f6e7.tar.gz
gcc-ac24fa46e449fbff0ff571951cfcc78b8488f6e7.tar.bz2
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.
-rw-r--r--gcc/cp/pt.c11
-rw-r--r--gcc/testsuite/g++.dg/template/mem-spec2.C11
2 files changed, 18 insertions, 4 deletions
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 %<template<>%>, 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 <class T>
+struct foo {
+ // the issue is const here
+ void bar(T& foobar) const { foobar = 0; } // { dg-message "candidate" }
+};
+
+template <> void
+foo<int>::bar(int& foobar) { foobar = 9; } // { dg-error "does not match" }
+// { dg-bogus "member function template" "" { target *-*-* } .-1 }