https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44283
Eric Gallager <egallager at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |error-recovery Status|UNCONFIRMED |NEW Last reconfirmed| |2017-08-18 CC| |egallager at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #2 from Eric Gallager <egallager at gcc dot gnu.org> --- (In reply to Jonathan Wakely from comment #0) > namespace NS > { > typedef int X; > > template<typename T> void f(X f, T t) { } > } > > template void f(X, int); // (1) > > template void f(int, char); // (2) > > > The code is invalid, the explicit instantiations should be inside NS or > should be qualified e.g. > template void NS::func(X, int); > > But the diagnostic for instantiation (1) is unhelpful: > > bug.cc:8:17: error: variable or field 'f' declared void > bug.cc:8:16: error: expected ';' before '(' token > > This is closely related to Bug 16663 but the diagnostic for (2) implies it > might be possible to improve things without fixing bug 16663, as this is > much better: > > bug.cc:10:26: error: 'f' is not a template function > > Is it possible to give the same "is not a template function" diagnostic for > (1)? The message is now: $ /usr/local/bin/g++ -c -Wall -Wextra -pedantic 44283.cc 44283.cc:8:17: error: variable or field ‘f’ declared void template void f(X, int); // (1) ^ 44283.cc:8:16: error: expected ‘;’ before ‘(’ token template void f(X, int); // (1) ^ 44283.cc:10:26: error: ‘f’ is not a template function template void f(int, char); // (2) ^ $ so it has the "is not a template function" diagnostic now, but it could still probably be improved. > > Comeau does significantly better, reporting: > identifier "X" is undefined > and > "f" is not a class or function template name in the current scope > > > > If the invalid instantiation is for a class template the diagnostic is fine: > > namespace NS > { > template<typename T> struct S; > } > > template struct S<X>; > > bug2.cc:6:17: error: 'S' is not a template > bug2.cc:6:19: error: 'X' was not declared in this scope > bug2.cc:6:17: error: explicit instantiation of non-template type 'S' > > The only improvement I would make would be to add something like "in this > scope" to the first error. > With carets, this is now: $ /usr/local/bin/g++ -c -Wall -Wextra -pedantic 44283_2.cc 44283_2.cc:6:17: error: ‘S’ is not a class template template struct S<X>; ^ 44283_2.cc:6:19: error: ‘X’ was not declared in this scope template struct S<X>; ^ 44283_2.cc:6:17: error: explicit instantiation of non-template type ‘S’ template struct S<X>; ^ $ (note the addition of the word 'class') > > Here's another bad diagnostic for instantiating a template function, which > doesn't have any undeclared type: > > namespace NS > { > template<int N> void g() { } > } > > template void g<0>(); > > bug3.cc:6:15: error: variable or field 'g' declared void > bug3.cc:6:16: error: expected ';' before '<' token > > Surely it's possible to say "g is not a template function" when the compiler > sees "template ... g<...>" ? > This is still bad even with carets: $ /usr/local/bin/g++ -c -Wall -Wextra -pedantic 44283_3.cc 44283_3.cc:6:15: error: variable or field ‘g’ declared void template void g<0>(); ^ 44283_3.cc:6:16: error: expected ‘;’ before ‘<’ token template void g<0>(); ^ $ > Comeau is much better again: > > "ComeauTest.c", line 6: error: g is not a template, > Should it be XX::g?, where XX is some namespace? > Did you #include the right header? > template void g<0>(); > ^ > > "ComeauTest.c", line 6: error: invalid explicit instantiation declaration > template void g<0>(); > ^ So, confirmed that the errors could be improved.