This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/6023] Unhelpful error message with forgotten "template"
- From: "reichelt at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 5 Aug 2003 23:08:54 -0000
- Subject: [Bug c++/6023] Unhelpful error message with forgotten "template"
- References: <20020321020601.6023.klaus.kretschel@dlr.de>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=6023
------- Additional Comments From reichelt at gcc dot gnu dot org 2003-08-05 23:08 -------
Actually the original testcase misses the template keyword *three* times:
As Nathan already explained in line 34 and 35 (right after "->"):
tmp = h->calc<VEC>(x);
tmp = h->do_calc<VEC>(x);
And it's missing in line 19 (right before "MyTraits"):
T do_calc(const typename Otto<T>::MyTraits<T, VEC>::T2& x)
Let's have a look at each of the missing templates:
1) As pointed out by Nathan, line 34 is accepted by gcc in error.
This can be demonstrated with the following code snippet,
which compiles, but shouldn't (i.e. we have an accepts-invalid bug
- it affects all versions since gcc 2.95.x):
-------------------------------------------
template <typename> struct A
{
template <typename> void foo();
};
template <typename T> struct B
{
template <int> void foo()
{
A<T>* p;
p->foo<int>();
}
};
-------------------------------------------
If one removes "template <int>" the compiler issues an error which
proves Nathan's analysis.
2) Line 35: Nothing fancy here - we get a sensible error message
(which might not be optimal, but it's not misleading either).
3) Line 19: This is another accepts-invalid bug for gcc 2.95.x - 3.3.x,
but that is fixed on mainline, i.e. we get an error message.
But as pointed out by Nathanael, the error message is a mess.
The good news is that the duplicate "expected" got fixed.
The bad news, however, is that we now even get an ICE after the error
message:
bug.cc:19: error: expected primary-expression
bug.cc:19: error: expected primary-expression
bug.cc:19: error: `::T2' has not been declared
bug.cc:19: error: `x' was not declared in this scope
bug.cc:20: error: ISO C++ forbids initialization of member `do_calc'
bug.cc:20: error: making `do_calc' static
bug.cc:20: error: expected `;'
bug.cc:20: error: template declaration of `T Hugo<T>::do_calc'
bug.cc: In member function `T Hugo<T>::calc(VEC)':
bug.cc:14: internal compiler error: in cp_parser_template_id, at
cp/parser.c:
7516
Please submit a full bug report, [etc.]
This is rewarded with three keywords: "ice-on-invalid-code",
"error-recovery" (since the ICE happens after a error message),
and "diagnostic" (since the error message is not very helpful -
we are missing just one "template", remember).
Here's a shorter testcase that also demonstrates the problem:
-------------------------------------------
template <typename> struct A;
template <typename T> struct B
{
template <int> void foo(const typename A<T>::X<T,T>::Y&);
template <typename U> void bar(U x) { foo<0>(x); }
};
-------------------------------------------
The corresponding error message is:
bug.cc:5: error: expected primary-expression
bug.cc:5: error: expected primary-expression
bug.cc:5: error: `::Y' has not been declared
bug.cc:5: error: expected primary-expression
bug.cc:5: error: variable or field `foo' declared void
bug.cc:5: error: ISO C++ forbids initialization of member `foo'
bug.cc:5: error: making `foo' static
bug.cc:5: error: ISO C++ forbids in-class initialization of non-const
static
member `foo'
bug.cc:5: error: template declaration of `int B<T>::foo'
bug.cc: In member function `void B<T>::bar(U)':
bug.cc:6: internal compiler error: in cp_parser_template_id, at
cp/parser.c:
7516
Please submit a full bug report, [etc.]
By varying the declaration of foo (i.e. removing "&", "const", or "::Y"
one can change the error message a little.
Since all this is a little too much for one PR, I'm going to spin off two
smaller ones for the accepts-invalid in 1) and the mainline problems in 3).
The accepts-invalid stuff in 3) for gcc 2.95.x - 3.3.x will not be fixed on
the 3.3 branch (since it's not a regression and already fixed in mainline).