Commit cee9035d by Nick Clifton Committed by Nick Clifton

re PR c++/37862 (Parenthesised indirection alters class member access)

        PR c++/37862
        * parser.c: Pass cp_id_kind computed in
        cp_parser_postfix_dot_deref_expression to
        cp_parser_primary_expression.

        * g++.cp/parse/pr37862.C: New test.

From-SVN: r143369
parent e04a57df
2009-01-14 Nick Clifton <nickc@redhat.com>
PR c++/37862
* parser.c: Pass cp_id_kind computed in
cp_parser_postfix_dot_deref_expression to
cp_parser_primary_expression.
2009-01-13 Jakub Jelinek <jakub@redhat.com> 2009-01-13 Jakub Jelinek <jakub@redhat.com>
PR c++/38795 PR c++/38795
......
...@@ -1586,7 +1586,7 @@ static tree cp_parser_nested_name_specifier ...@@ -1586,7 +1586,7 @@ static tree cp_parser_nested_name_specifier
static tree cp_parser_qualifying_entity static tree cp_parser_qualifying_entity
(cp_parser *, bool, bool, bool, bool, bool); (cp_parser *, bool, bool, bool, bool, bool);
static tree cp_parser_postfix_expression static tree cp_parser_postfix_expression
(cp_parser *, bool, bool, bool); (cp_parser *, bool, bool, bool, cp_id_kind *);
static tree cp_parser_postfix_open_square_expression static tree cp_parser_postfix_open_square_expression
(cp_parser *, tree, bool); (cp_parser *, tree, bool);
static tree cp_parser_postfix_dot_deref_expression static tree cp_parser_postfix_dot_deref_expression
...@@ -1596,7 +1596,7 @@ static tree cp_parser_parenthesized_expression_list ...@@ -1596,7 +1596,7 @@ static tree cp_parser_parenthesized_expression_list
static void cp_parser_pseudo_destructor_name static void cp_parser_pseudo_destructor_name
(cp_parser *, tree *, tree *); (cp_parser *, tree *, tree *);
static tree cp_parser_unary_expression static tree cp_parser_unary_expression
(cp_parser *, bool, bool); (cp_parser *, bool, bool, cp_id_kind *);
static enum tree_code cp_parser_unary_operator static enum tree_code cp_parser_unary_operator
(cp_token *); (cp_token *);
static tree cp_parser_new_expression static tree cp_parser_new_expression
...@@ -1614,17 +1614,17 @@ static tree cp_parser_new_initializer ...@@ -1614,17 +1614,17 @@ static tree cp_parser_new_initializer
static tree cp_parser_delete_expression static tree cp_parser_delete_expression
(cp_parser *); (cp_parser *);
static tree cp_parser_cast_expression static tree cp_parser_cast_expression
(cp_parser *, bool, bool); (cp_parser *, bool, bool, cp_id_kind *);
static tree cp_parser_binary_expression static tree cp_parser_binary_expression
(cp_parser *, bool, enum cp_parser_prec); (cp_parser *, bool, enum cp_parser_prec, cp_id_kind *);
static tree cp_parser_question_colon_clause static tree cp_parser_question_colon_clause
(cp_parser *, tree); (cp_parser *, tree);
static tree cp_parser_assignment_expression static tree cp_parser_assignment_expression
(cp_parser *, bool); (cp_parser *, bool, cp_id_kind *);
static enum tree_code cp_parser_assignment_operator_opt static enum tree_code cp_parser_assignment_operator_opt
(cp_parser *); (cp_parser *);
static tree cp_parser_expression static tree cp_parser_expression
(cp_parser *, bool); (cp_parser *, bool, cp_id_kind *);
static tree cp_parser_constant_expression static tree cp_parser_constant_expression
(cp_parser *, bool, bool *); (cp_parser *, bool, bool *);
static tree cp_parser_builtin_offsetof static tree cp_parser_builtin_offsetof
...@@ -3251,7 +3251,7 @@ cp_parser_primary_expression (cp_parser *parser, ...@@ -3251,7 +3251,7 @@ cp_parser_primary_expression (cp_parser *parser,
else else
{ {
/* Parse the parenthesized expression. */ /* Parse the parenthesized expression. */
expr = cp_parser_expression (parser, cast_p); expr = cp_parser_expression (parser, cast_p, idk);
/* Let the front end know that this expression was /* Let the front end know that this expression was
enclosed in parentheses. This matters in case, for enclosed in parentheses. This matters in case, for
example, the expression is of the form `A::B', since example, the expression is of the form `A::B', since
...@@ -3354,7 +3354,7 @@ cp_parser_primary_expression (cp_parser *parser, ...@@ -3354,7 +3354,7 @@ cp_parser_primary_expression (cp_parser *parser,
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
/* Now, parse the assignment-expression. */ /* Now, parse the assignment-expression. */
expression = cp_parser_assignment_expression (parser, expression = cp_parser_assignment_expression (parser,
/*cast_p=*/false); /*cast_p=*/false, NULL);
/* Look for the `,'. */ /* Look for the `,'. */
cp_parser_require (parser, CPP_COMMA, "%<,%>"); cp_parser_require (parser, CPP_COMMA, "%<,%>");
/* Parse the type-id. */ /* Parse the type-id. */
...@@ -4399,7 +4399,8 @@ cp_parser_qualifying_entity (cp_parser *parser, ...@@ -4399,7 +4399,8 @@ cp_parser_qualifying_entity (cp_parser *parser,
static tree static tree
cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
bool member_access_only_p) bool member_access_only_p,
cp_id_kind * pidk_return)
{ {
cp_token *token; cp_token *token;
enum rid keyword; enum rid keyword;
...@@ -4443,7 +4444,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, ...@@ -4443,7 +4444,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
/* And the expression which is being cast. */ /* And the expression which is being cast. */
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
expression = cp_parser_expression (parser, /*cast_p=*/true); expression = cp_parser_expression (parser, /*cast_p=*/true, & idk);
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
/* Only type conversions to integral or enumeration types /* Only type conversions to integral or enumeration types
...@@ -4515,7 +4516,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, ...@@ -4515,7 +4516,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
tree expression; tree expression;
/* Look for an expression. */ /* Look for an expression. */
expression = cp_parser_expression (parser, /*cast_p=*/false); expression = cp_parser_expression (parser, /*cast_p=*/false, & idk);
/* Compute its typeid. */ /* Compute its typeid. */
postfix_expression = build_typeid (expression); postfix_expression = build_typeid (expression);
/* Look for the `)' token. */ /* Look for the `)' token. */
...@@ -4767,6 +4768,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, ...@@ -4767,6 +4768,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
} }
if (BASELINK_P (fn)) if (BASELINK_P (fn))
{
postfix_expression postfix_expression
= (build_new_method_call = (build_new_method_call
(instance, fn, args, NULL_TREE, (instance, fn, args, NULL_TREE,
...@@ -4774,6 +4776,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, ...@@ -4774,6 +4776,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL), ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL),
/*fn_p=*/NULL, /*fn_p=*/NULL,
tf_warning_or_error)); tf_warning_or_error));
}
else else
postfix_expression postfix_expression
= finish_call_expr (postfix_expression, args, = finish_call_expr (postfix_expression, args,
...@@ -4862,6 +4865,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, ...@@ -4862,6 +4865,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
break; break;
default: default:
if (pidk_return != NULL)
* pidk_return = idk;
if (member_access_only_p) if (member_access_only_p)
return is_member_access? postfix_expression : error_mark_node; return is_member_access? postfix_expression : error_mark_node;
else else
...@@ -4903,7 +4908,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, ...@@ -4903,7 +4908,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
if (for_offsetof) if (for_offsetof)
index = cp_parser_constant_expression (parser, false, NULL); index = cp_parser_constant_expression (parser, false, NULL);
else else
index = cp_parser_expression (parser, /*cast_p=*/false); index = cp_parser_expression (parser, /*cast_p=*/false, NULL);
/* Look for the closing `]'. */ /* Look for the closing `]'. */
cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>"); cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>");
...@@ -4956,6 +4961,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, ...@@ -4956,6 +4961,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
parser->qualifying_scope = NULL_TREE; parser->qualifying_scope = NULL_TREE;
parser->object_scope = NULL_TREE; parser->object_scope = NULL_TREE;
*idk = CP_ID_KIND_NONE; *idk = CP_ID_KIND_NONE;
/* Enter the scope corresponding to the type of the object /* Enter the scope corresponding to the type of the object
given by the POSTFIX_EXPRESSION. */ given by the POSTFIX_EXPRESSION. */
if (!dependent_p && TREE_TYPE (postfix_expression) != NULL_TREE) if (!dependent_p && TREE_TYPE (postfix_expression) != NULL_TREE)
...@@ -5185,7 +5191,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, ...@@ -5185,7 +5191,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
*non_constant_p = true; *non_constant_p = true;
} }
else else
expr = cp_parser_assignment_expression (parser, cast_p); expr = cp_parser_assignment_expression (parser, cast_p, NULL);
if (fold_expr_p) if (fold_expr_p)
expr = fold_non_dependent_expr (expr); expr = fold_non_dependent_expr (expr);
...@@ -5369,7 +5375,8 @@ cp_parser_pseudo_destructor_name (cp_parser* parser, ...@@ -5369,7 +5375,8 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
Returns a representation of the expression. */ Returns a representation of the expression. */
static tree static tree
cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p) cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
cp_id_kind * pidk)
{ {
cp_token *token; cp_token *token;
enum tree_code unary_operator; enum tree_code unary_operator;
...@@ -5506,7 +5513,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p) ...@@ -5506,7 +5513,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
cast_expression cast_expression
= cp_parser_cast_expression (parser, = cp_parser_cast_expression (parser,
unary_operator == ADDR_EXPR, unary_operator == ADDR_EXPR,
/*cast_p=*/false); /*cast_p=*/false, pidk);
/* Now, build an appropriate representation. */ /* Now, build an appropriate representation. */
switch (unary_operator) switch (unary_operator)
{ {
...@@ -5548,7 +5555,8 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p) ...@@ -5548,7 +5555,8 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
} }
return cp_parser_postfix_expression (parser, address_p, cast_p, return cp_parser_postfix_expression (parser, address_p, cast_p,
/*member_access_only_p=*/false); /*member_access_only_p=*/false,
pidk);
} }
/* Returns ERROR_MARK if TOKEN is not a unary-operator. If TOKEN is a /* Returns ERROR_MARK if TOKEN is not a unary-operator. If TOKEN is a
...@@ -5813,7 +5821,7 @@ cp_parser_direct_new_declarator (cp_parser* parser) ...@@ -5813,7 +5821,7 @@ cp_parser_direct_new_declarator (cp_parser* parser)
if (!declarator) if (!declarator)
{ {
cp_token *token = cp_lexer_peek_token (parser->lexer); cp_token *token = cp_lexer_peek_token (parser->lexer);
expression = cp_parser_expression (parser, /*cast_p=*/false); expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
/* The standard requires that the expression have integral /* The standard requires that the expression have integral
type. DR 74 adds enumeration types. We believe that the type. DR 74 adds enumeration types. We believe that the
real intent is that these expressions be handled like the real intent is that these expressions be handled like the
...@@ -6001,7 +6009,8 @@ cp_parser_token_starts_cast_expression (cp_token *token) ...@@ -6001,7 +6009,8 @@ cp_parser_token_starts_cast_expression (cp_token *token)
Returns a representation of the expression. */ Returns a representation of the expression. */
static tree static tree
cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p) cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
cp_id_kind * pidk)
{ {
/* If it's a `(', then we might be looking at a cast. */ /* If it's a `(', then we might be looking at a cast. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
...@@ -6076,7 +6085,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p) ...@@ -6076,7 +6085,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
cp_parser_parse_definitely (parser); cp_parser_parse_definitely (parser);
expr = cp_parser_cast_expression (parser, expr = cp_parser_cast_expression (parser,
/*address_p=*/false, /*address_p=*/false,
/*cast_p=*/true); /*cast_p=*/true, pidk);
/* Warn about old-style casts, if so requested. */ /* Warn about old-style casts, if so requested. */
if (warn_old_style_cast if (warn_old_style_cast
...@@ -6104,7 +6113,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p) ...@@ -6104,7 +6113,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
/* If we get here, then it's not a cast, so it must be a /* If we get here, then it's not a cast, so it must be a
unary-expression. */ unary-expression. */
return cp_parser_unary_expression (parser, address_p, cast_p); return cp_parser_unary_expression (parser, address_p, cast_p, pidk);
} }
/* Parse a binary expression of the general form: /* Parse a binary expression of the general form:
...@@ -6188,7 +6197,8 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p) ...@@ -6188,7 +6197,8 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
static tree static tree
cp_parser_binary_expression (cp_parser* parser, bool cast_p, cp_parser_binary_expression (cp_parser* parser, bool cast_p,
enum cp_parser_prec prec) enum cp_parser_prec prec,
cp_id_kind * pidk)
{ {
cp_parser_expression_stack stack; cp_parser_expression_stack stack;
cp_parser_expression_stack_entry *sp = &stack[0]; cp_parser_expression_stack_entry *sp = &stack[0];
...@@ -6199,7 +6209,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, ...@@ -6199,7 +6209,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
bool overloaded_p; bool overloaded_p;
/* Parse the first expression. */ /* Parse the first expression. */
lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p); lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p, pidk);
lhs_type = ERROR_MARK; lhs_type = ERROR_MARK;
for (;;) for (;;)
...@@ -6340,12 +6350,12 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr) ...@@ -6340,12 +6350,12 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
expr = NULL_TREE; expr = NULL_TREE;
else else
/* Parse the expression. */ /* Parse the expression. */
expr = cp_parser_expression (parser, /*cast_p=*/false); expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
/* The next token should be a `:'. */ /* The next token should be a `:'. */
cp_parser_require (parser, CPP_COLON, "%<:%>"); cp_parser_require (parser, CPP_COLON, "%<:%>");
/* Parse the assignment-expression. */ /* Parse the assignment-expression. */
assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false); assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
/* Build the conditional-expression. */ /* Build the conditional-expression. */
return build_x_conditional_expr (logical_or_expr, return build_x_conditional_expr (logical_or_expr,
...@@ -6366,7 +6376,8 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr) ...@@ -6366,7 +6376,8 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
Returns a representation for the expression. */ Returns a representation for the expression. */
static tree static tree
cp_parser_assignment_expression (cp_parser* parser, bool cast_p) cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
cp_id_kind * pidk)
{ {
tree expr; tree expr;
...@@ -6379,7 +6390,7 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p) ...@@ -6379,7 +6390,7 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p)
else else
{ {
/* Parse the binary expressions (logical-or-expression). */ /* Parse the binary expressions (logical-or-expression). */
expr = cp_parser_binary_expression (parser, cast_p, PREC_NOT_OPERATOR); expr = cp_parser_binary_expression (parser, cast_p, PREC_NOT_OPERATOR, pidk);
/* If the next token is a `?' then we're actually looking at a /* If the next token is a `?' then we're actually looking at a
conditional-expression. */ conditional-expression. */
if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY)) if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
...@@ -6514,7 +6525,7 @@ cp_parser_assignment_operator_opt (cp_parser* parser) ...@@ -6514,7 +6525,7 @@ cp_parser_assignment_operator_opt (cp_parser* parser)
Returns a representation of the expression. */ Returns a representation of the expression. */
static tree static tree
cp_parser_expression (cp_parser* parser, bool cast_p) cp_parser_expression (cp_parser* parser, bool cast_p, cp_id_kind * pidk)
{ {
tree expression = NULL_TREE; tree expression = NULL_TREE;
...@@ -6524,7 +6535,7 @@ cp_parser_expression (cp_parser* parser, bool cast_p) ...@@ -6524,7 +6535,7 @@ cp_parser_expression (cp_parser* parser, bool cast_p)
/* Parse the next assignment-expression. */ /* Parse the next assignment-expression. */
assignment_expression assignment_expression
= cp_parser_assignment_expression (parser, cast_p); = cp_parser_assignment_expression (parser, cast_p, pidk);
/* If this is the first assignment-expression, we can just /* If this is the first assignment-expression, we can just
save it away. */ save it away. */
if (!expression) if (!expression)
...@@ -6603,7 +6614,7 @@ cp_parser_constant_expression (cp_parser* parser, ...@@ -6603,7 +6614,7 @@ cp_parser_constant_expression (cp_parser* parser,
For example, cp_parser_initializer_clauses uses this function to For example, cp_parser_initializer_clauses uses this function to
determine whether a particular assignment-expression is in fact determine whether a particular assignment-expression is in fact
constant. */ constant. */
expression = cp_parser_assignment_expression (parser, /*cast_p=*/false); expression = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
/* Restore the old settings. */ /* Restore the old settings. */
parser->integral_constant_expression_p parser->integral_constant_expression_p
= saved_integral_constant_expression_p; = saved_integral_constant_expression_p;
...@@ -7086,7 +7097,7 @@ cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr) ...@@ -7086,7 +7097,7 @@ cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
/* If the next token is a ';', then there is no expression /* If the next token is a ';', then there is no expression
statement. */ statement. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
statement = cp_parser_expression (parser, /*cast_p=*/false); statement = cp_parser_expression (parser, /*cast_p=*/false, NULL);
/* Consume the final `;'. */ /* Consume the final `;'. */
cp_parser_consume_semicolon_at_end_of_statement (parser); cp_parser_consume_semicolon_at_end_of_statement (parser);
...@@ -7454,7 +7465,7 @@ cp_parser_condition (cp_parser* parser) ...@@ -7454,7 +7465,7 @@ cp_parser_condition (cp_parser* parser)
cp_parser_abort_tentative_parse (parser); cp_parser_abort_tentative_parse (parser);
/* Otherwise, we are looking at an expression. */ /* Otherwise, we are looking at an expression. */
return cp_parser_expression (parser, /*cast_p=*/false); return cp_parser_expression (parser, /*cast_p=*/false, NULL);
} }
/* Parse an iteration-statement. /* Parse an iteration-statement.
...@@ -7526,7 +7537,7 @@ cp_parser_iteration_statement (cp_parser* parser) ...@@ -7526,7 +7537,7 @@ cp_parser_iteration_statement (cp_parser* parser)
/* Look for the `('. */ /* Look for the `('. */
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
/* Parse the expression. */ /* Parse the expression. */
expression = cp_parser_expression (parser, /*cast_p=*/false); expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
/* We're done with the do-statement. */ /* We're done with the do-statement. */
finish_do_stmt (expression, statement); finish_do_stmt (expression, statement);
/* Look for the `)'. */ /* Look for the `)'. */
...@@ -7558,7 +7569,7 @@ cp_parser_iteration_statement (cp_parser* parser) ...@@ -7558,7 +7569,7 @@ cp_parser_iteration_statement (cp_parser* parser)
/* If there's an expression, process it. */ /* If there's an expression, process it. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
expression = cp_parser_expression (parser, /*cast_p=*/false); expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
finish_for_expr (expression, statement); finish_for_expr (expression, statement);
/* Look for the `)'. */ /* Look for the `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
...@@ -7699,7 +7710,7 @@ cp_parser_jump_statement (cp_parser* parser) ...@@ -7699,7 +7710,7 @@ cp_parser_jump_statement (cp_parser* parser)
expr = cp_parser_braced_list (parser, &expr_non_constant_p); expr = cp_parser_braced_list (parser, &expr_non_constant_p);
} }
else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
expr = cp_parser_expression (parser, /*cast_p=*/false); expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
else else
/* If the next token is a `;', then there is no /* If the next token is a `;', then there is no
expression. */ expression. */
...@@ -7720,7 +7731,7 @@ cp_parser_jump_statement (cp_parser* parser) ...@@ -7720,7 +7731,7 @@ cp_parser_jump_statement (cp_parser* parser)
/* Consume the '*' token. */ /* Consume the '*' token. */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
/* Parse the dependent expression. */ /* Parse the dependent expression. */
finish_goto_stmt (cp_parser_expression (parser, /*cast_p=*/false)); finish_goto_stmt (cp_parser_expression (parser, /*cast_p=*/false, NULL));
} }
else else
finish_goto_stmt (cp_parser_identifier (parser)); finish_goto_stmt (cp_parser_identifier (parser));
...@@ -8857,7 +8868,7 @@ cp_parser_decltype (cp_parser *parser) ...@@ -8857,7 +8868,7 @@ cp_parser_decltype (cp_parser *parser)
/* Parse a class member access. */ /* Parse a class member access. */
expr = cp_parser_postfix_expression (parser, /*address_p=*/false, expr = cp_parser_postfix_expression (parser, /*address_p=*/false,
/*cast_p=*/false, /*cast_p=*/false,
/*member_access_only_p=*/true); /*member_access_only_p=*/true, NULL);
if (expr if (expr
&& expr != error_mark_node && expr != error_mark_node
...@@ -8876,7 +8887,7 @@ cp_parser_decltype (cp_parser *parser) ...@@ -8876,7 +8887,7 @@ cp_parser_decltype (cp_parser *parser)
cp_parser_abort_tentative_parse (parser); cp_parser_abort_tentative_parse (parser);
/* Parse a full expression. */ /* Parse a full expression. */
expr = cp_parser_expression (parser, /*cast_p=*/false); expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
} }
/* Go back to evaluating expressions. */ /* Go back to evaluating expressions. */
...@@ -14424,7 +14435,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p) ...@@ -14424,7 +14435,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
if (template_parm_p) if (template_parm_p)
push_deferring_access_checks (dk_no_deferred); push_deferring_access_checks (dk_no_deferred);
default_argument default_argument
= cp_parser_assignment_expression (parser, /*cast_p=*/false); = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
if (template_parm_p) if (template_parm_p)
pop_deferring_access_checks (); pop_deferring_access_checks ();
/* Restore saved state. */ /* Restore saved state. */
...@@ -16512,7 +16523,7 @@ cp_parser_throw_expression (cp_parser* parser) ...@@ -16512,7 +16523,7 @@ cp_parser_throw_expression (cp_parser* parser)
expression = NULL_TREE; expression = NULL_TREE;
else else
expression = cp_parser_assignment_expression (parser, expression = cp_parser_assignment_expression (parser,
/*cast_p=*/false); /*cast_p=*/false, NULL);
return build_throw (expression); return build_throw (expression);
} }
...@@ -16604,7 +16615,7 @@ cp_parser_asm_operand_list (cp_parser* parser) ...@@ -16604,7 +16615,7 @@ cp_parser_asm_operand_list (cp_parser* parser)
/* Look for the `('. */ /* Look for the `('. */
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
/* Parse the expression. */ /* Parse the expression. */
expression = cp_parser_expression (parser, /*cast_p=*/false); expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
/* Look for the `)'. */ /* Look for the `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
...@@ -17875,7 +17886,7 @@ static tree ...@@ -17875,7 +17886,7 @@ static tree
cp_parser_simple_cast_expression (cp_parser *parser) cp_parser_simple_cast_expression (cp_parser *parser)
{ {
return cp_parser_cast_expression (parser, /*address_p=*/false, return cp_parser_cast_expression (parser, /*address_p=*/false,
/*cast_p=*/false); /*cast_p=*/false, NULL);
} }
/* Parse a functional cast to TYPE. Returns an expression /* Parse a functional cast to TYPE. Returns an expression
...@@ -18241,7 +18252,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) ...@@ -18241,7 +18252,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
cp_parser_push_lexer_for_tokens (parser, tokens); cp_parser_push_lexer_for_tokens (parser, tokens);
/* Parse the assignment-expression. */ /* Parse the assignment-expression. */
parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false); parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
if (!processing_template_decl) if (!processing_template_decl)
parsed_arg = check_default_argument (TREE_VALUE (parm), parsed_arg); parsed_arg = check_default_argument (TREE_VALUE (parm), parsed_arg);
...@@ -18362,7 +18373,7 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword) ...@@ -18362,7 +18373,7 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
looking at the unary-expression production. */ looking at the unary-expression production. */
if (!expr) if (!expr)
expr = cp_parser_unary_expression (parser, /*address_p=*/false, expr = cp_parser_unary_expression (parser, /*address_p=*/false,
/*cast_p=*/false); /*cast_p=*/false, NULL);
if (pack_expansion_p) if (pack_expansion_p)
/* Build a pack expansion. */ /* Build a pack expansion. */
...@@ -19090,7 +19101,7 @@ cp_parser_objc_message_receiver (cp_parser* parser) ...@@ -19090,7 +19101,7 @@ cp_parser_objc_message_receiver (cp_parser* parser)
/* An Objective-C message receiver may be either (1) a type /* An Objective-C message receiver may be either (1) a type
or (2) an expression. */ or (2) an expression. */
cp_parser_parse_tentatively (parser); cp_parser_parse_tentatively (parser);
rcv = cp_parser_expression (parser, false); rcv = cp_parser_expression (parser, false, NULL);
if (cp_parser_parse_definitely (parser)) if (cp_parser_parse_definitely (parser))
return rcv; return rcv;
...@@ -19142,7 +19153,7 @@ cp_parser_objc_message_args (cp_parser* parser) ...@@ -19142,7 +19153,7 @@ cp_parser_objc_message_args (cp_parser* parser)
maybe_unary_selector_p = false; maybe_unary_selector_p = false;
cp_parser_require (parser, CPP_COLON, "%<:%>"); cp_parser_require (parser, CPP_COLON, "%<:%>");
arg = cp_parser_assignment_expression (parser, false); arg = cp_parser_assignment_expression (parser, false, NULL);
sel_args sel_args
= chainon (sel_args, = chainon (sel_args,
...@@ -19157,7 +19168,7 @@ cp_parser_objc_message_args (cp_parser* parser) ...@@ -19157,7 +19168,7 @@ cp_parser_objc_message_args (cp_parser* parser)
tree arg; tree arg;
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
arg = cp_parser_assignment_expression (parser, false); arg = cp_parser_assignment_expression (parser, false, NULL);
addl_args addl_args
= chainon (addl_args, = chainon (addl_args,
...@@ -20057,7 +20068,7 @@ cp_parser_objc_synchronized_statement (cp_parser *parser) { ...@@ -20057,7 +20068,7 @@ cp_parser_objc_synchronized_statement (cp_parser *parser) {
location = cp_lexer_peek_token (parser->lexer)->location; location = cp_lexer_peek_token (parser->lexer)->location;
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
lock = cp_parser_expression (parser, false); lock = cp_parser_expression (parser, false, NULL);
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
/* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST /* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST
...@@ -20082,7 +20093,7 @@ cp_parser_objc_throw_statement (cp_parser *parser) { ...@@ -20082,7 +20093,7 @@ cp_parser_objc_throw_statement (cp_parser *parser) {
cp_parser_require_keyword (parser, RID_AT_THROW, "%<@throw%>"); cp_parser_require_keyword (parser, RID_AT_THROW, "%<@throw%>");
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
expr = cp_parser_assignment_expression (parser, false); expr = cp_parser_assignment_expression (parser, false, NULL);
cp_parser_consume_semicolon_at_end_of_statement (parser); cp_parser_consume_semicolon_at_end_of_statement (parser);
...@@ -20439,7 +20450,7 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list, ...@@ -20439,7 +20450,7 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
return list; return list;
t = cp_parser_expression (parser, false); t = cp_parser_expression (parser, false, NULL);
if (t == error_mark_node if (t == error_mark_node
|| !cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) || !cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
...@@ -20596,7 +20607,7 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location ...@@ -20596,7 +20607,7 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
token = cp_lexer_peek_token (parser->lexer); token = cp_lexer_peek_token (parser->lexer);
t = cp_parser_assignment_expression (parser, false); t = cp_parser_assignment_expression (parser, false, NULL);
if (t == error_mark_node) if (t == error_mark_node)
goto resync_fail; goto resync_fail;
...@@ -20825,7 +20836,7 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok) ...@@ -20825,7 +20836,7 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
cp_parser_require_pragma_eol (parser, pragma_tok); cp_parser_require_pragma_eol (parser, pragma_tok);
lhs = cp_parser_unary_expression (parser, /*address_p=*/false, lhs = cp_parser_unary_expression (parser, /*address_p=*/false,
/*cast_p=*/false); /*cast_p=*/false, NULL);
switch (TREE_CODE (lhs)) switch (TREE_CODE (lhs))
{ {
case ERROR_MARK: case ERROR_MARK:
...@@ -20882,7 +20893,7 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok) ...@@ -20882,7 +20893,7 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
} }
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
rhs = cp_parser_expression (parser, false); rhs = cp_parser_expression (parser, false, NULL);
if (rhs == error_mark_node) if (rhs == error_mark_node)
goto saw_error; goto saw_error;
break; break;
...@@ -20956,7 +20967,7 @@ cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok) ...@@ -20956,7 +20967,7 @@ cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
static tree static tree
cp_parser_omp_for_cond (cp_parser *parser, tree decl) cp_parser_omp_for_cond (cp_parser *parser, tree decl)
{ {
tree lhs = cp_parser_cast_expression (parser, false, false), rhs; tree lhs = cp_parser_cast_expression (parser, false, false, NULL), rhs;
enum tree_code op; enum tree_code op;
cp_token *token; cp_token *token;
...@@ -20982,7 +20993,7 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl) ...@@ -20982,7 +20993,7 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl)
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
rhs = cp_parser_binary_expression (parser, false, rhs = cp_parser_binary_expression (parser, false,
PREC_RELATIONAL_EXPRESSION); PREC_RELATIONAL_EXPRESSION, NULL);
if (rhs == error_mark_node if (rhs == error_mark_node
|| cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
{ {
...@@ -21009,7 +21020,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl) ...@@ -21009,7 +21020,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
op = (token->type == CPP_PLUS_PLUS op = (token->type == CPP_PLUS_PLUS
? PREINCREMENT_EXPR : PREDECREMENT_EXPR); ? PREINCREMENT_EXPR : PREDECREMENT_EXPR);
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
lhs = cp_parser_cast_expression (parser, false, false); lhs = cp_parser_cast_expression (parser, false, false, NULL);
if (lhs != decl) if (lhs != decl)
return error_mark_node; return error_mark_node;
return build2 (op, TREE_TYPE (decl), decl, NULL_TREE); return build2 (op, TREE_TYPE (decl), decl, NULL_TREE);
...@@ -21034,13 +21045,13 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl) ...@@ -21034,13 +21045,13 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
if (op != NOP_EXPR) if (op != NOP_EXPR)
{ {
rhs = cp_parser_assignment_expression (parser, false); rhs = cp_parser_assignment_expression (parser, false, NULL);
rhs = build2 (op, TREE_TYPE (decl), decl, rhs); rhs = build2 (op, TREE_TYPE (decl), decl, rhs);
return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs); return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs);
} }
lhs = cp_parser_binary_expression (parser, false, lhs = cp_parser_binary_expression (parser, false,
PREC_ADDITIVE_EXPRESSION); PREC_ADDITIVE_EXPRESSION, NULL);
token = cp_lexer_peek_token (parser->lexer); token = cp_lexer_peek_token (parser->lexer);
decl_first = lhs == decl; decl_first = lhs == decl;
if (decl_first) if (decl_first)
...@@ -21054,7 +21065,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl) ...@@ -21054,7 +21065,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
op = token->type == CPP_PLUS ? PLUS_EXPR : MINUS_EXPR; op = token->type == CPP_PLUS ? PLUS_EXPR : MINUS_EXPR;
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
rhs = cp_parser_binary_expression (parser, false, rhs = cp_parser_binary_expression (parser, false,
PREC_ADDITIVE_EXPRESSION); PREC_ADDITIVE_EXPRESSION, NULL);
token = cp_lexer_peek_token (parser->lexer); token = cp_lexer_peek_token (parser->lexer);
if (token->type == CPP_PLUS || token->type == CPP_MINUS || decl_first) if (token->type == CPP_PLUS || token->type == CPP_MINUS || decl_first)
{ {
...@@ -21224,7 +21235,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) ...@@ -21224,7 +21235,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
{ {
/* Consume '='. */ /* Consume '='. */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
init = cp_parser_assignment_expression (parser, false); init = cp_parser_assignment_expression (parser, false, NULL);
non_class: non_class:
if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE) if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
...@@ -21257,7 +21268,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) ...@@ -21257,7 +21268,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
cp_parser_parse_definitely (parser); cp_parser_parse_definitely (parser);
cp_parser_require (parser, CPP_EQ, "%<=%>"); cp_parser_require (parser, CPP_EQ, "%<=%>");
rhs = cp_parser_assignment_expression (parser, false); rhs = cp_parser_assignment_expression (parser, false, NULL);
finish_expr_stmt (build_x_modify_expr (decl, NOP_EXPR, finish_expr_stmt (build_x_modify_expr (decl, NOP_EXPR,
rhs, rhs,
tf_warning_or_error)); tf_warning_or_error));
...@@ -21267,7 +21278,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) ...@@ -21267,7 +21278,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
{ {
decl = NULL; decl = NULL;
cp_parser_abort_tentative_parse (parser); cp_parser_abort_tentative_parse (parser);
init = cp_parser_expression (parser, false); init = cp_parser_expression (parser, false, NULL);
if (init) if (init)
{ {
if (TREE_CODE (init) == MODIFY_EXPR if (TREE_CODE (init) == MODIFY_EXPR
...@@ -21384,7 +21395,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) ...@@ -21384,7 +21395,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
|| CLASS_TYPE_P (TREE_TYPE (decl)))) || CLASS_TYPE_P (TREE_TYPE (decl))))
incr = cp_parser_omp_for_incr (parser, decl); incr = cp_parser_omp_for_incr (parser, decl);
else else
incr = cp_parser_expression (parser, false); incr = cp_parser_expression (parser, false, NULL);
} }
if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
......
2009-01-14 Nick Clifton <nickc@redhat.com>
PR c++/37862
* g++.cp/parse/pr37862.C: New test.
2009-01-14 Julian Brown <julian@codesourcery.com> 2009-01-14 Julian Brown <julian@codesourcery.com>
* gcc.target/arm/eabi1.c (__eabi_uread4, __eabi_uwrite4) * gcc.target/arm/eabi1.c (__eabi_uread4, __eabi_uwrite4)
......
// { dg-do run }
#include <stdlib.h>
class A {
public:
virtual void get (void) { }
};
class B : public A {
public:
void get (void) { abort (); }
};
class C : public B { };
int main (void)
{
C c;
C * p = &c;
p->A::get ();
(p->A::get) (); // The C++ parser used to resolve this to B::get()
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment