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;
+};

Reply via email to