OSDN Git Service

PR c++/37862
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Jan 2009 13:00:21 +0000 (13:00 +0000)
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Jan 2009 13:00:21 +0000 (13:00 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@143369 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/pr37862.C [new file with mode: 0644]

index 12c07ee..da52022 100644 (file)
@@ -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
index bf742ee..526a9a3 100644 (file)
@@ -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, "%<)%>"))
index a8c8253..4184300 100644 (file)
@@ -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 (file)
index 0000000..89b4b69
--- /dev/null
@@ -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;
+}