Hi,
this ICE on valid happens in the cp_parser_abort_tentative_parse called
at the end of cp_parser_decltype_expr. I started seriously looking into
it when I noticed that a variant of the testcase not using variadic
templates is fine, thus I concentrated on
cp_parser_parameter_declaration and noticed an inconsistency in the
following comment and the code implementing it:
/* After seeing a decl-specifier-seq, if the next token is not a
- "(", there is no possibility that the code is a valid
+ "(" nor '...', there is no possibility that the code is a valid
expression. Therefore, if parsing tentatively, we commit at
this point. */
clearly in the case at issue of decl-specifier-seq followed by ellipsis
we may be parsing a perfectly valid declaration.
Tested x86_64-linux, as usual.
Thanks,
Paolo.
////////////////////////
/cp
2013-06-05 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/51908
* parser.c (cp_parser_parameter_declaration): Do not commit to
tentative parse after a decl-specifier-seq followed by ellipsis.
/testsuite
2013-06-05 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/51908
* g++.dg/cpp0x/variadic144.C: New.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 199675)
+++ cp/parser.c (working copy)
@@ -17887,7 +17887,7 @@ cp_parser_parameter_declaration (cp_parser *parser
parser->default_arg_ok_p = false;
/* After seeing a decl-specifier-seq, if the next token is not a
- "(", there is no possibility that the code is a valid
+ "(" nor '...', there is no possibility that the code is a valid
expression. Therefore, if parsing tentatively, we commit at
this point. */
if (!parser->in_template_argument_list_p
@@ -17901,7 +17901,8 @@ cp_parser_parameter_declaration (cp_parser *parser
&& !parser->in_type_id_in_expr_p
&& cp_parser_uncommitted_to_tentative_parse_p (parser)
&& cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)
- && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_ELLIPSIS))
cp_parser_commit_to_tentative_parse (parser);
/* Parse the declarator. */
declarator_token_start = token;
Index: testsuite/g++.dg/cpp0x/variadic144.C
===================================================================
--- testsuite/g++.dg/cpp0x/variadic144.C (revision 0)
+++ testsuite/g++.dg/cpp0x/variadic144.C (working copy)
@@ -0,0 +1,8 @@
+// PR c++/51908
+// { dg-do compile { target c++11 } }
+
+struct foo
+{
+ template <typename Ret, typename... Args>
+ operator decltype(static_cast<Ret (*)(Args...)>(nullptr)) () const;
+};