aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2009-01-14 13:00:21 +0000
committerNick Clifton <nickc@gcc.gnu.org>2009-01-14 13:00:21 +0000
commitcee9035de585c97d1cff64f54cc454315e1dd2f6 (patch)
treeb6a98eb8122abe24e77e3961c271a00b815aa8c6 /gcc
parente04a57df1b19e2ae511f354a09552ac5e170a9a3 (diff)
downloadgcc-cee9035de585c97d1cff64f54cc454315e1dd2f6.zip
gcc-cee9035de585c97d1cff64f54cc454315e1dd2f6.tar.gz
gcc-cee9035de585c97d1cff64f54cc454315e1dd2f6.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/parser.c135
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/parse/pr37862.C25
4 files changed, 110 insertions, 62 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 12c07ee..da52022 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+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
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index bf742eea..526a9a3 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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, "%<)%>"))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a8c8253..4184300 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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)
diff --git a/gcc/testsuite/g++.dg/parse/pr37862.C b/gcc/testsuite/g++.dg/parse/pr37862.C
new file mode 100644
index 0000000..89b4b69
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr37862.C
@@ -0,0 +1,25 @@
+// { 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;
+}