OSDN Git Service

gcc/cp/
[pf3gnuchains/gcc-fork.git] / gcc / cp / parser.c
index 5be2318..4dec792 100644 (file)
@@ -77,6 +77,8 @@ typedef struct cp_token GTY (())
      KEYWORD is RID_MAX) iff this name was looked up and found to be
      ambiguous.  An error has already been reported.  */
   BOOL_BITFIELD ambiguous_p : 1;
+  /* The location at which this token was found.  */
+  location_t location;
   /* The value associated with this token, if any.  */
   union cp_token_value {
     /* Used for CPP_NESTED_NAME_SPECIFIER and CPP_TEMPLATE_ID.  */
@@ -84,8 +86,6 @@ typedef struct cp_token GTY (())
     /* Use for all other tokens.  */
     tree GTY((tag ("0"))) value;
   } GTY((desc ("(%1.type == CPP_TEMPLATE_ID) || (%1.type == CPP_NESTED_NAME_SPECIFIER)"))) u;
-  /* The location at which this token was found.  */
-  location_t location;
 } cp_token;
 
 /* We use a stack of token pointer for saving token sets.  */
@@ -95,8 +95,7 @@ DEF_VEC_ALLOC_P (cp_token_position,heap);
 
 static cp_token eof_token =
 {
-  CPP_EOF, RID_MAX, 0, PRAGMA_NONE, false, 0, { NULL },
-  0
+  CPP_EOF, RID_MAX, 0, PRAGMA_NONE, false, 0, 0, { NULL }
 };
 
 /* The cp_lexer structure represents the C++ lexer.  It is responsible
@@ -310,8 +309,7 @@ cp_lexer_new_main (void)
 
   /* Subsequent preprocessor diagnostics should use compiler
      diagnostic functions to get the compiler source location.  */
-  cpp_get_options (parse_in)->client_diagnostic = true;
-  cpp_get_callbacks (parse_in)->error = cp_cpp_error;
+  done_lexing = true;
 
   gcc_assert (lexer->next_token->type != CPP_PURGED);
   return lexer;
@@ -1616,7 +1614,7 @@ static tree cp_parser_delete_expression
 static tree cp_parser_cast_expression
   (cp_parser *, bool, bool, cp_id_kind *);
 static tree cp_parser_binary_expression
-  (cp_parser *, bool, enum cp_parser_prec, cp_id_kind *);
+  (cp_parser *, bool, bool, enum cp_parser_prec, cp_id_kind *);
 static tree cp_parser_question_colon_clause
   (cp_parser *, tree);
 static tree cp_parser_assignment_expression
@@ -1734,6 +1732,10 @@ static tree cp_parser_declarator_id
   (cp_parser *, bool);
 static tree cp_parser_type_id
   (cp_parser *);
+static tree cp_parser_template_type_arg
+  (cp_parser *);
+static tree cp_parser_type_id_1
+  (cp_parser *, bool);
 static void cp_parser_type_specifier_seq
   (cp_parser *, bool, cp_decl_specifier_seq *);
 static tree cp_parser_parameter_declaration_clause
@@ -1911,7 +1913,7 @@ static tree cp_parser_maybe_treat_template_as_class
 static bool cp_parser_check_declarator_template_parameters
   (cp_parser *, cp_declarator *, location_t);
 static bool cp_parser_check_template_parameters
-  (cp_parser *, unsigned, location_t);
+  (cp_parser *, unsigned, location_t, cp_declarator *);
 static tree cp_parser_simple_cast_expression
   (cp_parser *);
 static tree cp_parser_global_scope_opt
@@ -2621,6 +2623,8 @@ cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser)
          /* Stop if this is an unnested '}', or closes the outermost
             nesting level.  */
          nesting_depth--;
+         if (nesting_depth < 0)
+           return;
          if (!nesting_depth)
            nesting_depth = -1;
          break;
@@ -3144,6 +3148,12 @@ cp_parser_primary_expression (cp_parser *parser,
     case CPP_WCHAR:
     case CPP_NUMBER:
       token = cp_lexer_consume_token (parser->lexer);
+      if (TREE_CODE (token->u.value) == FIXED_CST)
+       {
+         error ("%Hfixed-point types not supported in C++",
+                &token->location);
+         return error_mark_node;
+       }
       /* Floating-point literals are only allowed in an integral
         constant expression if they are cast to an integral or
         enumeration type.  */
@@ -3896,7 +3906,9 @@ cp_parser_unqualified_id (cp_parser* parser,
                /* We couldn't find a type with this name, so just accept
                   it and check for a match at instantiation time.  */
                type_decl = cp_parser_identifier (parser);
-               return build_nt (BIT_NOT_EXPR, type_decl);
+               if (type_decl != error_mark_node)
+                 type_decl = build_nt (BIT_NOT_EXPR, type_decl);
+               return type_decl;
              }
          }
        /* If an error occurred, assume that the name of the
@@ -4724,15 +4736,17 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
              }
 
            koenig_p = false;
-           if (idk == CP_ID_KIND_UNQUALIFIED)
+           if (idk == CP_ID_KIND_UNQUALIFIED
+               || idk == CP_ID_KIND_TEMPLATE_ID)
              {
                if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
                  {
                    if (args)
                      {
                        koenig_p = true;
-                       postfix_expression
-                         = perform_koenig_lookup (postfix_expression, args);
+                       if (!any_type_dependent_arguments_p (args))
+                         postfix_expression
+                           = perform_koenig_lookup (postfix_expression, args);
                      }
                    else
                      postfix_expression
@@ -4754,8 +4768,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                    if (!DECL_FUNCTION_MEMBER_P (fn))
                      {
                        koenig_p = true;
-                       postfix_expression
-                         = perform_koenig_lookup (postfix_expression, args);
+                       if (!any_type_dependent_arguments_p (args))
+                         postfix_expression
+                           = perform_koenig_lookup (postfix_expression, args);
                      }
                  }
              }
@@ -4815,9 +4830,6 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                                    koenig_p,
                                    tf_warning_or_error);
 
-            if (warn_disallowed_functions)
-              warn_if_disallowed_function_p (postfix_expression);
-
            /* The POSTFIX_EXPRESSION is certainly no longer an id.  */
            idk = CP_ID_KIND_NONE;
          }
@@ -5766,7 +5778,7 @@ cp_parser_new_type_id (cp_parser* parser, tree *nelts)
        new_declarator = NULL;
     }
 
-  type = groktypename (&type_specifier_seq, new_declarator);
+  type = groktypename (&type_specifier_seq, new_declarator, false);
   return type;
 }
 
@@ -6207,6 +6219,7 @@ 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,
+                            bool no_toplevel_fold_p,
                             enum cp_parser_prec prec,
                             cp_id_kind * pidk)
 {
@@ -6289,6 +6302,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
          goto get_rhs;
 
         pop:
+         lookahead_prec = new_prec;
          /* If the stack is not empty, we have parsed into LHS the right side
             (`4' in the example above) of an expression we had suspended.
             We can use the information on the stack to recover the LHS (`3')
@@ -6313,8 +6327,14 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
         pass the correct tree_code unless the unary expression was
         surrounded by parentheses.
       */
-      lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type,
-                              &overloaded_p, tf_warning_or_error);
+      if (no_toplevel_fold_p
+         && lookahead_prec <= prec
+         && sp == stack
+         && TREE_CODE_CLASS (tree_type) == tcc_comparison)
+       lhs = build2 (tree_type, boolean_type_node, lhs, rhs);
+      else
+       lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type,
+                                &overloaded_p, tf_warning_or_error);
       lhs_type = tree_type;
 
       /* If the binary operator required the use of an overloaded operator,
@@ -6400,7 +6420,8 @@ 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, pidk);
+      expr = cp_parser_binary_expression (parser, cast_p, false,
+                                         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))
@@ -9192,7 +9213,11 @@ cp_parser_mem_initializer (cp_parser* parser)
       mem_initializer_id = NULL_TREE;
     }
   else
-    mem_initializer_id = cp_parser_mem_initializer_id (parser);
+    {
+      mem_initializer_id = cp_parser_mem_initializer_id (parser);
+      if (mem_initializer_id == error_mark_node)
+       return mem_initializer_id;
+    }
   member = expand_member_init (mem_initializer_id);
   if (member && !DECL_P (member))
     in_base_initializer = 1;
@@ -10311,7 +10336,7 @@ cp_parser_template_name (cp_parser* parser,
          && !template_keyword_p
          && parser->scope && TYPE_P (parser->scope)
          && check_dependency_p
-         && dependent_type_p (parser->scope)
+         && dependent_scope_p (parser->scope)
          /* Do not do this for dtors (or ctors), since they never
             need the template keyword before their name.  */
          && !constructor_name_p (identifier, parser->scope))
@@ -10525,7 +10550,7 @@ cp_parser_template_argument (cp_parser* parser)
 
      Therefore, we try a type-id first.  */
   cp_parser_parse_tentatively (parser);
-  argument = cp_parser_type_id (parser);
+  argument = cp_parser_template_type_arg (parser);
   /* If there was no error parsing the type-id but the next token is a
      '>>', our behavior depends on which dialect of C++ we're
      parsing. In C++98, we probably found a typo for '> >'. But there
@@ -10713,7 +10738,7 @@ cp_parser_template_argument (cp_parser* parser)
      was the only alternative that matched (albeit with a '>' after
      it). We can assume it's just a typo from the user, and a
      diagnostic will then be issued.  */
-  return cp_parser_type_id (parser);
+  return cp_parser_template_type_arg (parser);
 }
 
 /* Parse an explicit-instantiation.
@@ -10870,7 +10895,6 @@ cp_parser_explicit_specialization (cp_parser* parser)
   if (!begin_specialization ())
     {
       end_specialization ();
-      cp_parser_skip_to_end_of_block_or_statement (parser);
       return;
     }
 
@@ -11568,7 +11592,11 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
        type = make_typename_type (parser->scope, decl,
                                   typename_type,
                                   /*complain=*/tf_error);
-      else
+      /* If the `typename' keyword is in effect and DECL is not a type
+        decl. Then type is non existant.   */
+      else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL)
+        type = NULL_TREE; 
+      else 
        type = TREE_TYPE (decl);
     }
 
@@ -11739,7 +11767,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
             there were no qualifying templates.  */
          if (!cp_parser_check_template_parameters (parser,
                                                    /*num_templates=*/0,
-                                                   token->location))
+                                                   token->location,
+                                                   /*declarator=*/NULL))
            return error_mark_node;
          type = xref_tag (tag_type, identifier, ts, template_p);
        }
@@ -11908,6 +11937,7 @@ cp_parser_enum_specifier (cp_parser* parser)
   if (cp_parser_allow_gnu_extensions_p (parser))
     {
       tree trailing_attr = cp_parser_attributes_opt (parser);
+      trailing_attr = chainon (trailing_attr, attributes);
       cplus_decl_attributes (&type,
                             trailing_attr,
                             (int) ATTR_FLAG_TYPE_IN_PLACE);
@@ -11984,6 +12014,11 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type)
   else
     value = NULL_TREE;
 
+  /* If we are processing a template, make sure the initializer of the
+     enumerator doesn't contain any bare template parameter pack.  */
+  if (check_for_bare_parameter_packs (value))
+    value = error_mark_node;
+
   /* Create the enumerator.  */
   build_enumerator (identifier, value, type);
 }
@@ -13255,6 +13290,13 @@ cp_parser_direct_declarator (cp_parser* parser,
                                                 &non_constant_p);
              if (!non_constant_p)
                bounds = fold_non_dependent_expr (bounds);
+             else if (processing_template_decl)
+               {
+                 /* Remember this wasn't a constant-expression.  */
+                 bounds = build_nop (TREE_TYPE (bounds), bounds);
+                 TREE_SIDE_EFFECTS (bounds) = 1;
+               }
+
              /* Normally, the array bound must be an integral constant
                 expression.  However, as an extension, we allow VLAs
                 in function scopes.  */
@@ -13736,7 +13778,7 @@ cp_parser_declarator_id (cp_parser* parser, bool optional_p)
    Returns the TYPE specified.  */
 
 static tree
-cp_parser_type_id (cp_parser* parser)
+cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg)
 {
   cp_decl_specifier_seq type_specifier_seq;
   cp_declarator *abstract_declarator;
@@ -13765,7 +13807,18 @@ cp_parser_type_id (cp_parser* parser)
       return error_mark_node;
     }
   
-  return groktypename (&type_specifier_seq, abstract_declarator);
+  return groktypename (&type_specifier_seq, abstract_declarator,
+                      is_template_arg);
+}
+
+static tree cp_parser_type_id (cp_parser *parser)
+{
+  return cp_parser_type_id_1 (parser, false);
+}
+
+static tree cp_parser_template_type_arg (cp_parser *parser)
+{
+  return cp_parser_type_id_1 (parser, true);
 }
 
 /* Parse a type-specifier-seq.
@@ -14897,10 +14950,8 @@ cp_parser_class_name (cp_parser *parser,
 static tree
 cp_parser_class_specifier (cp_parser* parser)
 {
-  cp_token *token;
   tree type;
   tree attributes = NULL_TREE;
-  int has_trailing_semicolon;
   bool nested_name_specifier_p;
   unsigned saved_num_template_parameter_lists;
   bool saved_in_function_body;
@@ -14978,10 +15029,6 @@ cp_parser_class_specifier (cp_parser* parser)
 
   /* Look for the trailing `}'.  */
   cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
-  /* We get better error messages by noticing a common problem: a
-     missing trailing `;'.  */
-  token = cp_lexer_peek_token (parser->lexer);
-  has_trailing_semicolon = (token->type == CPP_SEMICOLON);
   /* Look for trailing attributes to apply to this class.  */
   if (cp_parser_allow_gnu_extensions_p (parser))
     attributes = cp_parser_attributes_opt (parser);
@@ -15352,7 +15399,8 @@ cp_parser_class_head (cp_parser* parser,
   /* Make sure that the right number of template parameters were
      present.  */
   if (!cp_parser_check_template_parameters (parser, num_templates,
-                                           type_start_token->location))
+                                           type_start_token->location,
+                                           /*declarator=*/NULL))
     {
       /* If something went wrong, there is no point in even trying to
         process the class-definition.  */
@@ -15997,7 +16045,13 @@ cp_parser_pure_specifier (cp_parser* parser)
   if (!cp_parser_require (parser, CPP_EQ, "%<=%>"))
     return error_mark_node;
   /* Look for the `0' token.  */
-  token = cp_lexer_consume_token (parser->lexer);
+  token = cp_lexer_peek_token (parser->lexer);
+
+  if (token->type == CPP_EOF
+      || token->type == CPP_PRAGMA_EOL)
+    return error_mark_node;
+
+  cp_lexer_consume_token (parser->lexer);
 
   /* Accept = default or = delete in c++0x mode.  */
   if (token->keyword == RID_DEFAULT
@@ -17004,35 +17058,11 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
         cannot look up the name if the scope is not a class type; it
         might, for example, be a template type parameter.  */
       dependent_p = (TYPE_P (parser->scope)
-                    && !(parser->in_declarator_p
-                         && currently_open_class (parser->scope))
-                    && dependent_type_p (parser->scope));
+                    && dependent_scope_p (parser->scope));
       if ((check_dependency || !CLASS_TYPE_P (parser->scope))
-          && dependent_p)
-       {
-         if (tag_type)
-           {
-             tree type;
-
-             /* The resolution to Core Issue 180 says that `struct
-                A::B' should be considered a type-name, even if `A'
-                is dependent.  */
-             type = make_typename_type (parser->scope, name, tag_type,
-                                        /*complain=*/tf_error);
-             decl = TYPE_NAME (type);
-           }
-         else if (is_template
-                  && (cp_parser_next_token_ends_template_argument_p (parser)
-                      || cp_lexer_next_token_is (parser->lexer,
-                                                 CPP_CLOSE_PAREN)))
-           decl = make_unbound_class_template (parser->scope,
-                                               name, NULL_TREE,
-                                               /*complain=*/tf_error);
-         else
-           decl = build_qualified_name (/*type=*/NULL_TREE,
-                                        parser->scope, name,
-                                        is_template);
-       }
+         && dependent_p)
+       /* Defer lookup.  */
+       decl = error_mark_node;
       else
        {
          tree pushed_scope = NULL_TREE;
@@ -17053,14 +17083,42 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
                                        /*complain=*/true);
 
          /* If we have a single function from a using decl, pull it out.  */
-         if (decl
-             && TREE_CODE (decl) == OVERLOAD
+         if (TREE_CODE (decl) == OVERLOAD
              && !really_overloaded_fn (decl))
            decl = OVL_FUNCTION (decl);
 
          if (pushed_scope)
            pop_scope (pushed_scope);
        }
+
+      /* If the scope is a dependent type and either we deferred lookup or
+        we did lookup but didn't find the name, rememeber the name.  */
+      if (decl == error_mark_node && TYPE_P (parser->scope)
+         && dependent_type_p (parser->scope))
+       {
+         if (tag_type)
+           {
+             tree type;
+
+             /* The resolution to Core Issue 180 says that `struct
+                A::B' should be considered a type-name, even if `A'
+                is dependent.  */
+             type = make_typename_type (parser->scope, name, tag_type,
+                                        /*complain=*/tf_error);
+             decl = TYPE_NAME (type);
+           }
+         else if (is_template
+                  && (cp_parser_next_token_ends_template_argument_p (parser)
+                      || cp_lexer_next_token_is (parser->lexer,
+                                                 CPP_CLOSE_PAREN)))
+           decl = make_unbound_class_template (parser->scope,
+                                               name, NULL_TREE,
+                                               /*complain=*/tf_error);
+         else
+           decl = build_qualified_name (/*type=*/NULL_TREE,
+                                        parser->scope, name,
+                                        is_template);
+       }
       parser->qualifying_scope = parser->scope;
       parser->object_scope = NULL_TREE;
     }
@@ -17251,9 +17309,9 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
           additional level of template parameters.  */
        ++num_templates;
 
-      return cp_parser_check_template_parameters (parser,
-                                                 num_templates,
-                                                 declarator_location);
+      return cp_parser_check_template_parameters 
+       (parser, num_templates, declarator_location, declarator);
+
 
     case cdk_function:
     case cdk_array:
@@ -17274,30 +17332,38 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
 
 /* NUM_TEMPLATES were used in the current declaration.  If that is
    invalid, return FALSE and issue an error messages.  Otherwise,
-   return TRUE.  */
+   return TRUE.  If DECLARATOR is non-NULL, then we are checking a
+   declarator and we can print more accurate diagnostics.  */
 
 static bool
 cp_parser_check_template_parameters (cp_parser* parser,
                                     unsigned num_templates,
-                                    location_t location)
+                                    location_t location,
+                                    cp_declarator *declarator)
 {
+  /* If there are the same number of template classes and parameter
+     lists, that's OK.  */
+  if (parser->num_template_parameter_lists == num_templates)
+    return true;
+  /* If there are more, but only one more, then we are referring to a
+     member template.  That's OK too.  */
+  if (parser->num_template_parameter_lists == num_templates + 1)
+    return true;
   /* If there are more template classes than parameter lists, we have
      something like:
 
        template <class T> void S<T>::R<T>::f ();  */
   if (parser->num_template_parameter_lists < num_templates)
     {
-      error ("%Htoo few template-parameter-lists", &location);
+      if (declarator)
+       error_at (location, "specializing member %<%T::%E%> "
+                 "requires %<template<>%> syntax", 
+                 declarator->u.id.qualifying_scope,
+                 declarator->u.id.unqualified_name);
+      else 
+       error_at (location, "too few template-parameter-lists");
       return false;
     }
-  /* If there are the same number of template classes and parameter
-     lists, that's OK.  */
-  if (parser->num_template_parameter_lists == num_templates)
-    return true;
-  /* If there are more, but only one more, then we are referring to a
-     member template.  That's OK too.  */
-  if (parser->num_template_parameter_lists == num_templates + 1)
-      return true;
   /* Otherwise, there are too many template parameter lists.  We have
      something like:
 
@@ -18267,6 +18333,11 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
 
       /* Parse the assignment-expression.  */
       parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
+      if (parsed_arg == error_mark_node)
+       {
+         cp_parser_pop_lexer (parser);
+         continue;
+       }
 
       if (!processing_template_decl)
        parsed_arg = check_default_argument (TREE_VALUE (parm), parsed_arg);
@@ -20981,41 +21052,39 @@ 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, NULL), rhs;
-  enum tree_code op;
-  cp_token *token;
+  tree cond = cp_parser_binary_expression (parser, false, true,
+                                          PREC_NOT_OPERATOR, NULL);
+  bool overloaded_p;
 
-  if (lhs != decl)
+  if (cond == error_mark_node
+      || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
     {
       cp_parser_skip_to_end_of_statement (parser);
       return error_mark_node;
     }
 
-  token = cp_lexer_peek_token (parser->lexer);
-  op = binops_by_token [token->type].tree_type;
-  switch (op)
+  switch (TREE_CODE (cond))
     {
-    case LT_EXPR:
-    case LE_EXPR:
     case GT_EXPR:
     case GE_EXPR:
+    case LT_EXPR:
+    case LE_EXPR:
       break;
     default:
-      cp_parser_skip_to_end_of_statement (parser);
       return error_mark_node;
     }
 
-  cp_lexer_consume_token (parser->lexer);
-  rhs = cp_parser_binary_expression (parser, false,
-                                    PREC_RELATIONAL_EXPRESSION, NULL);
-  if (rhs == error_mark_node
-      || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
-    {
-      cp_parser_skip_to_end_of_statement (parser);
-      return error_mark_node;
-    }
+  /* If decl is an iterator, preserve LHS and RHS of the relational
+     expr until finish_omp_for.  */
+  if (decl
+      && (type_dependent_expression_p (decl)
+         || CLASS_TYPE_P (TREE_TYPE (decl))))
+    return cond;
 
-  return build2 (op, boolean_type_node, lhs, rhs);
+  return build_x_binary_op (TREE_CODE (cond),
+                           TREE_OPERAND (cond, 0), ERROR_MARK,
+                           TREE_OPERAND (cond, 1), ERROR_MARK,
+                           &overloaded_p, tf_warning_or_error);
 }
 
 /* Helper function, to parse omp for increment expression.  */
@@ -21064,7 +21133,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
       return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs);
     }
 
-  lhs = cp_parser_binary_expression (parser, false,
+  lhs = cp_parser_binary_expression (parser, false, false,
                                     PREC_ADDITIVE_EXPRESSION, NULL);
   token = cp_lexer_peek_token (parser->lexer);
   decl_first = lhs == decl;
@@ -21078,7 +21147,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,
+      rhs = cp_parser_binary_expression (parser, false, false,
                                         PREC_ADDITIVE_EXPRESSION, NULL);
       token = cp_lexer_peek_token (parser->lexer);
       if (token->type == CPP_PLUS || token->type == CPP_MINUS || decl_first)
@@ -21387,16 +21456,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
 
       cond = NULL;
       if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
-       {
-         /* If decl is an iterator, preserve LHS and RHS of the relational
-            expr until finish_omp_for.  */
-         if (decl
-             && (type_dependent_expression_p (decl)
-                 || CLASS_TYPE_P (TREE_TYPE (decl))))
-           cond = cp_parser_omp_for_cond (parser, decl);
-         else
-           cond = cp_parser_condition (parser);
-       }
+       cond = cp_parser_omp_for_cond (parser, decl);
       cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
 
       incr = NULL;