This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Confirmed template parsing bug.

At 07:07 PM 2/27/99 PST, you wrote:
>> The following declaration gets a "parse error before '<'" that appears to
>> be spurious:
>> static X &transform (const BinOp &op,
>>                      X &x,
>>                      typename math_traits<
>>                        typename X::rebind<
>>                          typename __ref_remover<
>>                            typename BinOp::second_argument_type
>>                          >::value_type
>>                        >::other
>>                      >::pass_type y) throw ();
>You may well have found a bug, but without a complete program (where are
>X, math_traits, rebind, etc defined?) no one will be able to debug the

math_traits has been declared at that point as template <class T> struct
math_traits; and X and BinOp are template args to a template struct of
which the above is a static member function. In instantiations of this
struct it is expected that the X have a member type rebind such as

template <class T>
class foo { // to be used as X above.
  template <class U>
  struct rebind { typedef foo<U> other; }

rather like in the standard C++ library allocators.

However, the problem seems disinclined to reproduce easily. A largeish
source experiences the spurious error, but the following snippet which is
contextually equivalent to what I have somehow compiles smoothly with -W
-Wall -Werror -O1:

template <class T>
struct math_traits;

template <class T>
struct __ref_remover {
  typedef T value_type;

template <class T>
struct __ref_remover<const T &> {
  typedef T value_type;

template <class X, class BinOp>
struct foo {
  static X &transform (const BinOp &op,
                       X &x,
                       typename math_traits<
                         typename X::rebind<
                           typename __ref_remover<
                             typename BinOp::second_argument_type
                       >::pass_type y) throw ();

Since the same snippet bombs in one case and works in another when either
it is or is not well-formed, this definitely looks like a parse bug.

Stranger yet, if I insert the following line in my sources above where the
problematic static function is declared, the inserted line catches the same
parse error.

typename math_traits<T>::pass_type foo (void) throw ();

As there is only one '<' I am forced to conclude that it is objecting to
"typename math_traits<T>::pass_type" which makes no sense, since the only
possible errors this code should be able to produce are
* math_traits undeclared (if it is) or
* T undeclared
and what I get instead is "parse error before '<'".

Moreover, I deliberately didn't declare T in the scope of the inserted
line. It causes the sameparse error. If T is declared, the same parse error
occurs. Therefore T doesn't even factor into this.
So the problem fragment reduces to 'math_traits<argument>' which is
invariably either well-formed or erroneous in the well-defined manner of
math_traits being undeclared.

So there are only two possibilities:
1. A Mandelbug that causes the compiler to barf on legitimate
   template instance names under unspecified and complex
   circumstances. Or,
2. A bug that causes it to output a bogus parse error message instead
   of a real undeclared name error message under unspecified and
   complex conditions.

Either of these is a parser bug, one in parsing itself and one in the
generating of the correct error message for an error.

   .*.  "Clouds are not spheres, mountains are not cones, coastlines are not
-()  <  circles, and bark is not smooth, nor does lightning travel in a
   `*'  straight line."    -------------------------------------------------
        -- B. Mandelbrot  |
_____________________ ____|________     Paul Derbyshire
Programmer & Humanist|ICQ: 10423848|

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]