===================================================================
@@ -1857,7 +1857,7 @@ static tree cp_parser_nested_name_specifier
static tree cp_parser_qualifying_entity
(cp_parser *, bool, bool, bool, bool, bool);
static tree cp_parser_postfix_expression
- (cp_parser *, bool, bool, bool, bool, cp_id_kind *);
+ (cp_parser *, bool, bool, bool, bool&, cp_id_kind *);
static tree cp_parser_postfix_open_square_expression
(cp_parser *, tree, bool, bool);
static tree cp_parser_postfix_dot_deref_expression
@@ -5531,14 +5531,14 @@ cp_parser_qualifying_entity (cp_parser *parser,
`&' operator. CAST_P is true if this expression is the target of a
cast.
- If MEMBER_ACCESS_ONLY_P, we only allow postfix expressions that are
- class member access expressions [expr.ref].
+ If IS_MEMBER_ACCESS is false, we are not returning a class member
+ access expression [expr.ref].
Returns a representation of the expression. */
static tree
cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
- bool member_access_only_p, bool decltype_p,
+ bool decltype_p, bool& is_member_access,
cp_id_kind * pidk_return)
{
cp_token *token;
@@ -5546,7 +5546,7 @@ cp_parser_postfix_expression (cp_parser *parser, b
enum rid keyword;
cp_id_kind idk = CP_ID_KIND_NONE;
tree postfix_expression = NULL_TREE;
- bool is_member_access = false;
+ is_member_access = false;
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
@@ -6066,10 +6066,7 @@ cp_parser_postfix_expression (cp_parser *parser, b
default:
if (pidk_return != NULL)
* pidk_return = idk;
- if (member_access_only_p)
- return is_member_access? postfix_expression : error_mark_node;
- else
- return postfix_expression;
+ return postfix_expression;
}
}
@@ -7003,9 +7000,9 @@ cp_parser_unary_expression (cp_parser *parser, boo
return expression;
}
+ bool is_member_access;
return cp_parser_postfix_expression (parser, address_p, cast_p,
- /*member_access_only_p=*/false,
- decltype_p,
+ decltype_p, is_member_access,
pidk);
}
@@ -11678,33 +11675,42 @@ cp_parser_decltype_expr (cp_parser *parser,
id_expression_or_member_access_p = true;
}
- if (!id_expression_or_member_access_p)
+ if (id_expression_or_member_access_p)
{
- /* Abort the id-expression parse. */
- cp_parser_abort_tentative_parse (parser);
+ /* We have parsed an id-expression. */
+ cp_parser_parse_definitely (parser);
+ return expr;
+ }
- /* Parsing tentatively, again. */
- cp_parser_parse_tentatively (parser);
+ /* Abort the id-expression parse. */
+ cp_parser_abort_tentative_parse (parser);
- /* Parse a class member access. */
- expr = cp_parser_postfix_expression (parser, /*address_p=*/false,
- /*cast_p=*/false, /*decltype*/true,
- /*member_access_only_p=*/true, NULL);
+ /* Parsing tentatively, again. */
+ cp_parser_parse_tentatively (parser);
- if (expr
- && expr != error_mark_node
- && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
- /* We have an id-expression. */
- id_expression_or_member_access_p = true;
- }
+ /* Parse a postfix expression. */
+ bool is_member_access;
+ expr = cp_parser_postfix_expression (parser, /*address_p=*/false,
+ /*cast_p=*/false,
+ /*decltype_p*/true,
+ is_member_access, NULL);
- if (id_expression_or_member_access_p)
- /* We have parsed the complete id-expression or member access. */
+ bool postfix_expression_ok_p =
+ (expr && expr != error_mark_node
+ && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN);
+
+ if (postfix_expression_ok_p
+ && is_member_access)
+ id_expression_or_member_access_p = true;
+
+ if (postfix_expression_ok_p)
+ /* We have parsed a member access or a different kind of valid
+ postfix expression, eg, a pseudo destructor call [expr.pseudo]
+ (c++/58633). */
cp_parser_parse_definitely (parser);
else
{
- /* Abort our attempt to parse an id-expression or member access
- expression. */
+ /* Abort our attempt to parse a postfix-expression. */
cp_parser_abort_tentative_parse (parser);
/* Parse a full expression. */
===================================================================
@@ -0,0 +1,8 @@
+// PR c++/58633
+// { dg-do compile { target c++11 } }
+
+void foo(int i)
+{
+ typedef int I;
+ decltype(i.I::~I())* p;
+}