The call h->do_calc from Otto::calc in test program below gives the parse error temp_test.cc: In member function `T Otto<T>::calc(VEC)': temp_test.cc:35: parse error before `;' token while the same syntax is correct when called from Hugo::calc. I cannot rule out that this might be covered by the missing feature "Two stage lookup in templates is not implemented" but I don't think so. Compiler call was "g++ -c -Wall temp_test.cc". Release: 3.0.4 Environment: System: Linux darwin 2.4.4-64GB-SMP #1 SMP Wed May 16 01:20:45 GMT 2001 i686 unknown Architecture: i686 host: i686-pc-linux-gnu build: i686-pc-linux-gnu target: i686-pc-linux-gnu configured with: ./configure How-To-Repeat: Test program temp_test.ii (the "vektor" struct can as well be replaced by vector; it was only introduced to avoid lots of preprocessor output): # 1 "temp_test.cc" template<class V> struct vektor { V a; vektor(V v) : a(v) {} }; template<class T> struct Otto; template<class T> struct Hugo { template<class VEC> T calc(VEC x) { T tmp; tmp = this->do_calc<VEC>(x); return tmp; } template<class VEC> T do_calc(const typename Otto<T>::MyTraits<T, VEC>::T2& x) { return x.a; } }; template<class T> struct Otto { template<class T0, typename T1> struct MyTraits; template<class T0> struct MyTraits<T0, vektor<T0> > { typedef vektor<T0> T2; }; template<class VEC> T calc(VEC x) { Hugo<T>* h; T tmp; tmp = h->calc<VEC>(x); tmp = h->do_calc<VEC>(x); return tmp; } }; int main() { vektor<char> c('X'); Otto<char> otto; otto.calc(c); }
Fix: Have an intermediate method that calls method from inside class (like "Hugo::calc" in test program). Possible but very unsatifying because of redundant code.
State-Changed-From-To: open->suspended State-Changed-Why: The code is not well formed, but g++ makes a right cock up of it. I've attached an amended test case which I hope helps. you need to say h->template foo<args> (...) as h is a dependant type. We can't lookup foo until instantiation time, so you must explicitly say that it will be a template. the reason 'calc' succeeds is that there is a template of that name in scope, and g++ finds that during parsing (in error) -- at instantiation time the right things happen
From: Kretschel Klaus <Klaus.Kretschel@dlr.de> To: nathan@gcc.gnu.org, Klaus.Kretschel@dlr.de, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org, nobody@gcc.gnu.org, gcc-gnats@gcc.gnu.org Cc: Subject: Re: c++/6023: [parser] wrong lookup on templated code Date: Mon, 25 Mar 2002 11:24:04 +0100 --------------019051F0024079775D80B423 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit nathan@gcc.gnu.org wrote: > Old Synopsis: Valid template code does not compile > New Synopsis: [parser] wrong lookup on templated code > > State-Changed-From-To: open->suspended > State-Changed-By: nathan > State-Changed-When: Sun Mar 24 06:06:25 2002 > State-Changed-Why: > The code is not well formed, but g++ makes a right cock > up of it. I've attached an amended test case which I > hope helps. you need to say > h->template foo<args> (...) > as h is a dependant type. We can't lookup foo until > instantiation time, so you must explicitly say that it > will be a template. the reason 'calc' succeeds is that > there is a template of that name in scope, and g++ finds > that during parsing (in error) -- at instantiation time > the right things happen > > http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6023 Thank you, that's fine. Now that I knew where to look I found it in my Stroustrup. He also explains why it gives a simple parse error, so I guess g++'s message is okay. But nobody's never seen this syntax in our department before - I guess, few people have. Klaus --------------019051F0024079775D80B423 Content-Type: text/html; charset=us-ascii Content-Transfer-Encoding: 7bit <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> nathan@gcc.gnu.org wrote: <blockquote TYPE=CITE>Old Synopsis: Valid template code does not compile <br>New Synopsis: [parser] wrong lookup on templated code <p>State-Changed-From-To: open->suspended <br>State-Changed-By: nathan <br>State-Changed-When: Sun Mar 24 06:06:25 2002 <br>State-Changed-Why: <br> The code is not well formed, but g++ makes a right cock <br> up of it. I've attached an amended test case which I <br> hope helps. you need to say <br> h->template foo<args> (...) <br> as h is a dependant type. We can't lookup foo until <br> instantiation time, so you must explicitly say that it <br> will be a template. the reason 'calc' succeeds is that <br> there is a template of that name in scope, and g++ finds <br> that during parsing (in error) -- at instantiation time <br> the right things happen <p><a href="http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6023">http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6023</a></blockquote> Thank you, that's fine. Now that I knew where to look I found it in my Stroustrup. He also <br>explains why it gives a simple parse error, so I guess g++'s message is okay. But nobody's never <br>seen this syntax in our department before - I guess, few people have. <p>Klaus</html> --------------019051F0024079775D80B423--
From: Nathanael Nerode <neroden@twcny.rr.com> To: gcc-gnats@gcc.gnu.org, gcc-bugs@gcc.gnu.org, nobody@gcc.gnu.org, Klaus.Kretschel@dlr.de Cc: Subject: Re: c++/6023... Date: Sun, 19 Jan 2003 23:48:08 -0500 With the new parser, gives the overused message /home/neroden/6023.cxx:20: error: expected primary-expression which is not very helpful. The original testcase gives worse errors: vektor<V>::vektor(V) /home/neroden/test.cxx: At global scope: /home/neroden/test.cxx:20: error: expected primary-expression /home/neroden/test.cxx:20: error: expected `)' /home/neroden/test.cxx:21: error: expected expected `;' /home/neroden/test.cxx:21: error: data member `do_calc' cannot be a member template ...and more. 'expected expected' is not appropriate, ever, incidentally; someone should file a bug about that but I'm feeling too lazy.
State-Changed-From-To: suspended->analyzed State-Changed-Why: It's still here...
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).
The accepts-invalid bug is now PR 11814 the ice-on-invalid-code bug is now PR 11815. I'm suspending this PR until the problems in PR 11814 and 11815 are solved.
And PR 16233 was filed for the diagnostic problem.
I think we can close this one.