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>
PR c++/38795
......
......@@ -1586,7 +1586,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);
(cp_parser *, bool, bool, bool, cp_id_kind *);
static tree cp_parser_postfix_open_square_expression
(cp_parser *, tree, bool);
static tree cp_parser_postfix_dot_deref_expression
......@@ -1596,7 +1596,7 @@ static tree cp_parser_parenthesized_expression_list
static void cp_parser_pseudo_destructor_name
(cp_parser *, tree *, tree *);
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
(cp_token *);
static tree cp_parser_new_expression
......@@ -1614,17 +1614,17 @@ static tree cp_parser_new_initializer
static tree cp_parser_delete_expression
(cp_parser *);
static tree cp_parser_cast_expression
(cp_parser *, bool, bool);
(cp_parser *, bool, bool, cp_id_kind *);
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
(cp_parser *, tree);
static tree cp_parser_assignment_expression
(cp_parser *, bool);
(cp_parser *, bool, cp_id_kind *);
static enum tree_code cp_parser_assignment_operator_opt
(cp_parser *);
static tree cp_parser_expression
(cp_parser *, bool);
(cp_parser *, bool, cp_id_kind *);
static tree cp_parser_constant_expression
(cp_parser *, bool, bool *);
static tree cp_parser_builtin_offsetof
......@@ -3251,7 +3251,7 @@ cp_parser_primary_expression (cp_parser *parser,
else
{
/* 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
enclosed in parentheses. This matters in case, for
example, the expression is of the form `A::B', since
......@@ -3354,7 +3354,7 @@ cp_parser_primary_expression (cp_parser *parser,
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
/* Now, parse the assignment-expression. */
expression = cp_parser_assignment_expression (parser,
/*cast_p=*/false);
/*cast_p=*/false, NULL);
/* Look for the `,'. */
cp_parser_require (parser, CPP_COMMA, "%<,%>");
/* Parse the type-id. */
......@@ -4399,7 +4399,8 @@ cp_parser_qualifying_entity (cp_parser *parser,
static tree
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;
enum rid keyword;
......@@ -4443,7 +4444,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
/* And the expression which is being cast. */
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, "%<)%>");
/* 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,
tree 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. */
postfix_expression = build_typeid (expression);
/* Look for the `)' token. */
......@@ -4767,6 +4768,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
}
if (BASELINK_P (fn))
{
postfix_expression
= (build_new_method_call
(instance, fn, args, NULL_TREE,
......@@ -4774,6 +4776,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL),
/*fn_p=*/NULL,
tf_warning_or_error));
}
else
postfix_expression
= finish_call_expr (postfix_expression, args,
......@@ -4862,6 +4865,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
break;
default:
if (pidk_return != NULL)
* pidk_return = idk;
if (member_access_only_p)
return is_member_access? postfix_expression : error_mark_node;
else
......@@ -4903,7 +4908,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
if (for_offsetof)
index = cp_parser_constant_expression (parser, false, NULL);
else
index = cp_parser_expression (parser, /*cast_p=*/false);
index = cp_parser_expression (parser, /*cast_p=*/false, NULL);
/* Look for the closing `]'. */
cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>");
......@@ -4956,6 +4961,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
parser->qualifying_scope = NULL_TREE;
parser->object_scope = NULL_TREE;
*idk = CP_ID_KIND_NONE;
/* Enter the scope corresponding to the type of the object
given by the POSTFIX_EXPRESSION. */
if (!dependent_p && TREE_TYPE (postfix_expression) != NULL_TREE)
......@@ -5185,7 +5191,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
*non_constant_p = true;
}
else
expr = cp_parser_assignment_expression (parser, cast_p);
expr = cp_parser_assignment_expression (parser, cast_p, NULL);
if (fold_expr_p)
expr = fold_non_dependent_expr (expr);
......@@ -5369,7 +5375,8 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
Returns a representation of the expression. */
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;
enum tree_code unary_operator;
......@@ -5506,7 +5513,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
cast_expression
= cp_parser_cast_expression (parser,
unary_operator == ADDR_EXPR,
/*cast_p=*/false);
/*cast_p=*/false, pidk);
/* Now, build an appropriate representation. */
switch (unary_operator)
{
......@@ -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,
/*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
......@@ -5813,7 +5821,7 @@ cp_parser_direct_new_declarator (cp_parser* parser)
if (!declarator)
{
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
type. DR 74 adds enumeration types. We believe that the
real intent is that these expressions be handled like the
......@@ -6001,7 +6009,8 @@ cp_parser_token_starts_cast_expression (cp_token *token)
Returns a representation of the expression. */
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 (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)
cp_parser_parse_definitely (parser);
expr = cp_parser_cast_expression (parser,
/*address_p=*/false,
/*cast_p=*/true);
/*cast_p=*/true, pidk);
/* Warn about old-style casts, if so requested. */
if (warn_old_style_cast
......@@ -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
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:
......@@ -6188,7 +6197,8 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
static tree
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_entry *sp = &stack[0];
......@@ -6199,7 +6209,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
bool overloaded_p;
/* 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;
for (;;)
......@@ -6340,12 +6350,12 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
expr = NULL_TREE;
else
/* 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 `:'. */
cp_parser_require (parser, CPP_COLON, "%<:%>");
/* 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. */
return build_x_conditional_expr (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. */
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;
......@@ -6379,7 +6390,7 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p)
else
{
/* 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
conditional-expression. */
if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
......@@ -6514,7 +6525,7 @@ cp_parser_assignment_operator_opt (cp_parser* parser)
Returns a representation of the expression. */
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;
......@@ -6524,7 +6535,7 @@ cp_parser_expression (cp_parser* parser, bool cast_p)
/* Parse the next 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
save it away. */
if (!expression)
......@@ -6603,7 +6614,7 @@ cp_parser_constant_expression (cp_parser* parser,
For example, cp_parser_initializer_clauses uses this function to
determine whether a particular assignment-expression is in fact
constant. */
expression = cp_parser_assignment_expression (parser, /*cast_p=*/false);
expression = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
/* Restore the old settings. */
parser->integral_constant_expression_p
= saved_integral_constant_expression_p;
......@@ -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
statement. */
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 `;'. */
cp_parser_consume_semicolon_at_end_of_statement (parser);
......@@ -7454,7 +7465,7 @@ cp_parser_condition (cp_parser* parser)
cp_parser_abort_tentative_parse (parser);
/* 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.
......@@ -7526,7 +7537,7 @@ cp_parser_iteration_statement (cp_parser* parser)
/* Look for the `('. */
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
/* 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. */
finish_do_stmt (expression, statement);
/* Look for the `)'. */
......@@ -7558,7 +7569,7 @@ cp_parser_iteration_statement (cp_parser* parser)
/* If there's an expression, process it. */
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);
/* Look for the `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
......@@ -7699,7 +7710,7 @@ cp_parser_jump_statement (cp_parser* parser)
expr = cp_parser_braced_list (parser, &expr_non_constant_p);
}
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
/* If the next token is a `;', then there is no
expression. */
......@@ -7720,7 +7731,7 @@ cp_parser_jump_statement (cp_parser* parser)
/* Consume the '*' token. */
cp_lexer_consume_token (parser->lexer);
/* 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
finish_goto_stmt (cp_parser_identifier (parser));
......@@ -8857,7 +8868,7 @@ cp_parser_decltype (cp_parser *parser)
/* Parse a class member access. */
expr = cp_parser_postfix_expression (parser, /*address_p=*/false,
/*cast_p=*/false,
/*member_access_only_p=*/true);
/*member_access_only_p=*/true, NULL);
if (expr
&& expr != error_mark_node
......@@ -8876,7 +8887,7 @@ cp_parser_decltype (cp_parser *parser)
cp_parser_abort_tentative_parse (parser);
/* 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. */
......@@ -14424,7 +14435,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
if (template_parm_p)
push_deferring_access_checks (dk_no_deferred);
default_argument
= cp_parser_assignment_expression (parser, /*cast_p=*/false);
= cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
if (template_parm_p)
pop_deferring_access_checks ();
/* Restore saved state. */
......@@ -16512,7 +16523,7 @@ cp_parser_throw_expression (cp_parser* parser)
expression = NULL_TREE;
else
expression = cp_parser_assignment_expression (parser,
/*cast_p=*/false);
/*cast_p=*/false, NULL);
return build_throw (expression);
}
......@@ -16604,7 +16615,7 @@ cp_parser_asm_operand_list (cp_parser* parser)
/* Look for the `('. */
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
/* Parse the expression. */
expression = cp_parser_expression (parser, /*cast_p=*/false);
expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
/* Look for the `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
......@@ -17875,7 +17886,7 @@ static tree
cp_parser_simple_cast_expression (cp_parser *parser)
{
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
......@@ -18241,7 +18252,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
cp_parser_push_lexer_for_tokens (parser, tokens);
/* 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)
parsed_arg = check_default_argument (TREE_VALUE (parm), parsed_arg);
......@@ -18362,7 +18373,7 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
looking at the unary-expression production. */
if (!expr)
expr = cp_parser_unary_expression (parser, /*address_p=*/false,
/*cast_p=*/false);
/*cast_p=*/false, NULL);
if (pack_expansion_p)
/* Build a pack expansion. */
......@@ -19090,7 +19101,7 @@ cp_parser_objc_message_receiver (cp_parser* parser)
/* An Objective-C message receiver may be either (1) a type
or (2) an expression. */
cp_parser_parse_tentatively (parser);
rcv = cp_parser_expression (parser, false);
rcv = cp_parser_expression (parser, false, NULL);
if (cp_parser_parse_definitely (parser))
return rcv;
......@@ -19142,7 +19153,7 @@ cp_parser_objc_message_args (cp_parser* parser)
maybe_unary_selector_p = false;
cp_parser_require (parser, CPP_COLON, "%<:%>");
arg = cp_parser_assignment_expression (parser, false);
arg = cp_parser_assignment_expression (parser, false, NULL);
sel_args
= chainon (sel_args,
......@@ -19157,7 +19168,7 @@ cp_parser_objc_message_args (cp_parser* parser)
tree arg;
cp_lexer_consume_token (parser->lexer);
arg = cp_parser_assignment_expression (parser, false);
arg = cp_parser_assignment_expression (parser, false, NULL);
addl_args
= chainon (addl_args,
......@@ -20057,7 +20068,7 @@ cp_parser_objc_synchronized_statement (cp_parser *parser) {
location = cp_lexer_peek_token (parser->lexer)->location;
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, "%<)%>");
/* 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) {
cp_parser_require_keyword (parser, RID_AT_THROW, "%<@throw%>");
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);
......@@ -20439,7 +20450,7 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
return list;
t = cp_parser_expression (parser, false);
t = cp_parser_expression (parser, false, NULL);
if (t == error_mark_node
|| !cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
......@@ -20596,7 +20607,7 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location
cp_lexer_consume_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)
goto resync_fail;
......@@ -20825,7 +20836,7 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
cp_parser_require_pragma_eol (parser, pragma_tok);
lhs = cp_parser_unary_expression (parser, /*address_p=*/false,
/*cast_p=*/false);
/*cast_p=*/false, NULL);
switch (TREE_CODE (lhs))
{
case ERROR_MARK:
......@@ -20882,7 +20893,7 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
}
cp_lexer_consume_token (parser->lexer);
rhs = cp_parser_expression (parser, false);
rhs = cp_parser_expression (parser, false, NULL);
if (rhs == error_mark_node)
goto saw_error;
break;
......@@ -20956,7 +20967,7 @@ cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
static tree
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;
cp_token *token;
......@@ -20982,7 +20993,7 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl)
cp_lexer_consume_token (parser->lexer);
rhs = cp_parser_binary_expression (parser, false,
PREC_RELATIONAL_EXPRESSION);
PREC_RELATIONAL_EXPRESSION, NULL);
if (rhs == error_mark_node
|| cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
{
......@@ -21009,7 +21020,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
op = (token->type == CPP_PLUS_PLUS
? PREINCREMENT_EXPR : PREDECREMENT_EXPR);
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)
return error_mark_node;
return build2 (op, TREE_TYPE (decl), decl, NULL_TREE);
......@@ -21034,13 +21045,13 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
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);
return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs);
}
lhs = cp_parser_binary_expression (parser, false,
PREC_ADDITIVE_EXPRESSION);
PREC_ADDITIVE_EXPRESSION, NULL);
token = cp_lexer_peek_token (parser->lexer);
decl_first = lhs == decl;
if (decl_first)
......@@ -21054,7 +21065,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
op = token->type == CPP_PLUS ? PLUS_EXPR : MINUS_EXPR;
cp_lexer_consume_token (parser->lexer);
rhs = cp_parser_binary_expression (parser, false,
PREC_ADDITIVE_EXPRESSION);
PREC_ADDITIVE_EXPRESSION, NULL);
token = cp_lexer_peek_token (parser->lexer);
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)
{
/* Consume '='. */
cp_lexer_consume_token (parser->lexer);
init = cp_parser_assignment_expression (parser, false);
init = cp_parser_assignment_expression (parser, false, NULL);
non_class:
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)
cp_parser_parse_definitely (parser);
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,
rhs,
tf_warning_or_error));
......@@ -21267,7 +21278,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
{
decl = NULL;
cp_parser_abort_tentative_parse (parser);
init = cp_parser_expression (parser, false);
init = cp_parser_expression (parser, false, NULL);
if (init)
{
if (TREE_CODE (init) == MODIFY_EXPR
......@@ -21384,7 +21395,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
|| CLASS_TYPE_P (TREE_TYPE (decl))))
incr = cp_parser_omp_for_incr (parser, decl);
else
incr = cp_parser_expression (parser, false);
incr = cp_parser_expression (parser, false, NULL);
}
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>
* 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