Bug 6023 - Unhelpful error message with forgotten "template"
Summary: Unhelpful error message with forgotten "template"
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.0.4
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid, diagnostic
Depends on: 16233 11814 11815
Blocks:
  Show dependency treegraph
 
Reported: 2002-03-21 02:06 UTC by klaus.kretschel
Modified: 2017-11-20 09:54 UTC (History)
4 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2005-12-11 21:54:14


Attachments
6023.ii (138 bytes, text/x-c++)
2003-05-21 15:16 UTC, klaus.kretschel
Details

Note You need to log in before you can comment on or make changes to this bug.
Description klaus.kretschel 2002-03-21 02:06:01 UTC
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);
}
Comment 1 klaus.kretschel 2002-03-21 02:06:01 UTC
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.
Comment 2 Nathan Sidwell 2002-03-24 06:06:25 UTC
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
Comment 3 klaus.kretschel 2002-03-25 11:24:04 UTC
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>&nbsp;&nbsp;&nbsp; The code is not well formed, but g++ makes a right
 cock
 <br>&nbsp;&nbsp;&nbsp; up of it. I've attached an amended test case which
 I
 <br>&nbsp;&nbsp;&nbsp; hope helps. you need to say
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h->template foo&lt;args>
 (...)
 <br>&nbsp;&nbsp;&nbsp; as h is a dependant type. We can't lookup foo until
 <br>&nbsp;&nbsp;&nbsp; instantiation time, so you must explicitly say that
 it
 <br>&nbsp;&nbsp;&nbsp; will be a template. the reason 'calc' succeeds is
 that
 <br>&nbsp;&nbsp;&nbsp; there is a template of that name in scope, and g++
 finds
 <br>&nbsp;&nbsp;&nbsp; that during parsing (in error) -- at instantiation
 time
 <br>&nbsp;&nbsp;&nbsp; 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&amp;database=gcc&amp;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&nbsp;
 is okay. But nobody's never
 <br>seen this syntax in our department before - I guess, few people have.
 <p>Klaus</html>
 
 --------------019051F0024079775D80B423--
 
Comment 4 Nathanael C. Nerode 2003-01-19 23:48:08 UTC
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.
Comment 5 Nathanael C. Nerode 2003-01-20 04:49:29 UTC
State-Changed-From-To: suspended->analyzed
State-Changed-Why: It's still here...
Comment 6 Volker Reichelt 2003-08-05 23:08:52 UTC
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).
Comment 7 Volker Reichelt 2003-08-05 23:23:00 UTC
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.
Comment 8 Andrew Pinski 2004-06-27 17:55:15 UTC
And PR 16233 was filed for the diagnostic problem.
Comment 9 Paolo Carlini 2017-11-20 09:54:29 UTC
I think we can close this one.