Hi!

As discussed in the PR, () isn't valid unary expression, so
((type ()) () needs to be parsed as a function call instead.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
approved by Jason in the PR, committed to trunk.

2013-02-07  Jakub Jelinek  <ja...@redhat.com>

        PR c++/56239
        * parser.c (cp_parser_token_starts_cast_expression): Renamed to...
        (cp_parser_tokens_start_cast_expression): ... this.  Change parameter
        to cp_parser *, call cp_lexer_peek_token first.  For CPP_OPEN_PAREN,
        return true only if 2nd token isn't CPP_CLOSE_PAREN.
        (cp_parser_cast_expression): Adjust caller.

        * g++.dg/parse/pr56239.C: New test.

--- gcc/cp/parser.c.jj  2013-02-07 08:59:50.000000000 +0100
+++ gcc/cp/parser.c     2013-02-07 13:53:16.169450209 +0100
@@ -7091,8 +7091,9 @@ cp_parser_delete_expression (cp_parser*
    otherwise.  */
 
 static bool
-cp_parser_token_starts_cast_expression (cp_token *token)
+cp_parser_tokens_start_cast_expression (cp_parser *parser)
 {
+  cp_token *token = cp_lexer_peek_token (parser->lexer);
   switch (token->type)
     {
     case CPP_COMMA:
@@ -7133,6 +7134,12 @@ cp_parser_token_starts_cast_expression (
     case CPP_EOF:
       return false;
 
+    case CPP_OPEN_PAREN:
+      /* In ((type ()) () the last () isn't a valid cast-expression,
+        so the whole must be parsed as postfix-expression.  */
+      return cp_lexer_peek_nth_token (parser->lexer, 2)->type
+            != CPP_CLOSE_PAREN;
+
       /* '[' may start a primary-expression in obj-c++.  */
     case CPP_OPEN_SQUARE:
       return c_dialect_objc ();
@@ -7225,8 +7232,7 @@ cp_parser_cast_expression (cp_parser *pa
         parenthesized ctor such as `(T ())' that looks like a cast to
         function returning T.  */
       if (!cp_parser_error_occurred (parser)
-         && cp_parser_token_starts_cast_expression (cp_lexer_peek_token
-                                                    (parser->lexer)))
+         && cp_parser_tokens_start_cast_expression (parser))
        {
          cp_parser_parse_definitely (parser);
          expr = cp_parser_cast_expression (parser,
--- gcc/testsuite/g++.dg/parse/pr56239.C.jj     2013-02-07 13:56:04.628448688 
+0100
+++ gcc/testsuite/g++.dg/parse/pr56239.C        2013-02-07 13:55:14.000000000 
+0100
@@ -0,0 +1,13 @@
+// PR c++/56239
+// { dg-do compile }
+
+struct S
+{
+  int operator () () { return 0; }
+};
+
+int
+main ()
+{
+  return (S ()) ();
+}

        Jakub

Reply via email to