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" }