This is the mail archive of the gcc-patches@gcc.gnu.org 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]
Other format: [Raw text]

[C++ PATCH] Fix PR/9154 (a trunk regression)


Hello,

the following patch fixes PR/9154 by modifying the new parser to identify
the ">>" token within a template argument list as a typo from the user for
"> >", as it was done on the previous parser. This is done by loosely
accepting CPP_RSHIFT as terminator of a (type) template argument, and later
detecting it within cp_parser_template_id and emitting a proper diagnostic.

We could have done even better if there were a way to push artificial tokens
within the lexer. In that case, we would have been able to push an
additional CPP_GREATER when detecting a CPP_RSHIFT, thus allowing to
continue parsing correctly.

This patch has been bootstrapped on i686-pc-cygwin (languages c, c++, java)
and tested with a "make check-g++" with no new regressions. OK for mainline?

Giovanni Bajo



2003-06-20  Giovanni Bajo  <giovannibajo@libero.it>

        PR c++/9154
        * parser.c (cp_parser_template_id): Detect when CPP_RSHIFT is
        used to terminate an argument list, and emit proper diagnostic.
        (cp_parser_template_argument): Loosely accept CPP_RSHIFT as
        a terminator for a type parameter.

2003-06-20  Giovanni Bajo  <giovannibajo@libero.it>

        PR c++/9154
        * g++.dg/parse/error6.C: New test.



Index: parser.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.63
diff -c -w -p -r1.63 parser.c
*** parser.c    25 May 2003 12:59:22 -0000      1.63
--- parser.c    20 Jun 2003 13:45:01 -0000
*************** cp_parser_template_id (cp_parser *parser
*** 7973,7980 ****
--- 7975,7991 ----
      arguments = NULL_TREE;
    else
      arguments = cp_parser_template_argument_list (parser);
+
+   /* If there is a '>>', it is probably a typo from the user, report it */
+   if (cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT))
+   {
+     error ("'>>' should be '> >' within a template argument list");
+     cp_lexer_consume_token (parser->lexer);
+   }
+   else
      /* Look for the `>' that ends the template-argument-list.  */
      cp_parser_require (parser, CPP_GREATER, "`>'");
+
    /* The `>' token might be a greater-than operator again now.  */
    parser->greater_than_is_operator_p
      = saved_greater_than_is_operator_p;
*************** cp_parser_template_argument (cp_parser*
*** 8220,8228 ****
    cp_parser_parse_tentatively (parser);
    argument = cp_parser_type_id (parser);
    /* If the next token isn't a `,' or a `>', then this argument wasn't
!      really finished.  */
    if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)
!       && cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER))
      cp_parser_error (parser, "expected template-argument");
    /* If that worked, we're done.  */
    if (cp_parser_parse_definitely (parser))
--- 8231,8241 ----
    cp_parser_parse_tentatively (parser);
    argument = cp_parser_type_id (parser);
    /* If the next token isn't a `,' or a `>', then this argument wasn't
!      really finished. '>>' is probably a typo (the user meant '> >'), just
!      pretend it is valid for now, it will be detected later. */
    if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)
!       && cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER)
!       && cp_lexer_next_token_is_not (parser->lexer, CPP_RSHIFT))
      cp_parser_error (parser, "expected template-argument");
    /* If that worked, we're done.  */
    if (cp_parser_parse_definitely (parser))


// { dg-do compile }
// Origin: <tilps at hotmail dot com>
// c++/9154: poor error message for ">>" vs "> >" in template argument list

template <class A>
class a {};

int main()
{
  a<a<int>> blah;  // { dg-error "" "should be '> >' within" }
}


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