Patchwork [committed] Fix parsing of ((type ()) () (PR c++/56239)

login
register
mail settings
Submitter Jakub Jelinek
Date Feb. 7, 2013, 5:41 p.m.
Message ID <20130207174150.GH4385@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/218972/
State New
Headers show

Comments

Jakub Jelinek - Feb. 7, 2013, 5:41 p.m.
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  <jakub@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.


	Jakub

Patch

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