Hi,

this ICE during error recovery exposes a rather more general weakness: we should never call cp_lexer_peek_nth_token (*, 2) when a previous cp_lexer_peek_token returns CPP_EOF.

The fix seems easy, just reshape a bit the condition and delay the latter. It should also be a net, albeit minor, performance win: in general we don't want to call cp_lexer_peek_nth_token (which is out of line) unnecessarily.

Tested x86_64-linux.

Thanks,
Paolo.

///////////////////////
/cp
2016-05-17  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/69793
        * parser.c (cp_parser_template_id): Don't call cp_lexer_peek_nth_token
        when the previous cp_lexer_peek_token returns CPP_EOF.

/testsuite
2016-05-17  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/69793
        * g++.dg/template/crash123.C: New.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 236338)
+++ cp/parser.c (working copy)
@@ -14835,11 +14835,11 @@ cp_parser_template_id (cp_parser *parser,
   /* If we find the sequence `[:' after a template-name, it's probably
      a digraph-typo for `< ::'. Substitute the tokens and check if we can
      parse correctly the argument list.  */
-  next_token = cp_lexer_peek_token (parser->lexer);
-  next_token_2 = cp_lexer_peek_nth_token (parser->lexer, 2);
-  if (next_token->type == CPP_OPEN_SQUARE
+  if (((next_token = cp_lexer_peek_token (parser->lexer))->type
+       == CPP_OPEN_SQUARE)
       && next_token->flags & DIGRAPH
-      && next_token_2->type == CPP_COLON
+      && ((next_token_2 = cp_lexer_peek_nth_token (parser->lexer, 2))->type
+         == CPP_COLON)
       && !(next_token_2->flags & PREV_WHITE))
     {
       cp_parser_parse_tentatively (parser);
Index: testsuite/g++.dg/template/crash123.C
===================================================================
--- testsuite/g++.dg/template/crash123.C        (revision 0)
+++ testsuite/g++.dg/template/crash123.C        (working copy)
@@ -0,0 +1,4 @@
+// PR c++/69793
+
+class fpos;
+template < state > bool operator!= (fpos,; operator!= // { dg-error 
"declared|expected|type" }

Reply via email to