[prev in list] [next in list] [prev in thread] [next in thread]
List: gcc-bugs
Subject: Confirmed template parsing bug.
From: Paul Derbyshire <pderbysh () usa ! net>
Date: 1999-02-28 5:27:44
[Download RAW message or body]
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
>problem.
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.
public:
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
>::value_type
>::other
>::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 |http://surf.to/pgd.net
_____________________ ____|________ Paul Derbyshire pderbysh@usa.net
Programmer & Humanist|ICQ: 10423848|
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic