@@ -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,
@@ -0,0 +1,13 @@
+// PR c++/56239
+// { dg-do compile }
+
+struct S
+{
+ int operator () () { return 0; }
+};
+
+int
+main ()
+{
+ return (S ()) ();
+}