OSDN Git Service

patch for PR rtl-optimization/25130
[pf3gnuchains/gcc-fork.git] / gcc / c-parser.c
index e08f436..8469eca 100644 (file)
@@ -19,8 +19,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 /* TODO:
 
@@ -93,6 +93,9 @@ static const struct resword reswords[] =
 {
   { "_Bool",           RID_BOOL,       0 },
   { "_Complex",                RID_COMPLEX,    0 },
+  { "_Decimal32",       RID_DFLOAT32,  D_EXT },
+  { "_Decimal64",       RID_DFLOAT64,  D_EXT },
+  { "_Decimal128",      RID_DFLOAT128, D_EXT },
   { "__FUNCTION__",    RID_FUNCTION_NAME, 0 },
   { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
   { "__alignof",       RID_ALIGNOF,    0 },
@@ -239,9 +242,6 @@ c_parse_init (void)
 /* A keyword.  */
 #define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1))
 
-/* The number of token types, including C-specific ones.  */
-#define N_C_TTYPES ((int) (CPP_KEYWORD + 1))
-
 /* More information about the type of a CPP_NAME token.  */
 typedef enum c_id_kind {
   /* An ordinary identifier.  */
@@ -295,8 +295,7 @@ static void
 c_lex_one_token (c_token *token)
 {
   timevar_push (TV_LEX);
-  token->type = c_lex (&token->value);
-  token->location = input_location;
+  token->type = c_lex_with_flags (&token->value, &token->location, NULL);
   token->in_system_header = in_system_header;
   switch (token->type)
     {
@@ -465,6 +464,9 @@ c_token_starts_typename (c_token *token)
        case RID_FLOAT:
        case RID_DOUBLE:
        case RID_VOID:
+       case RID_DFLOAT32:
+       case RID_DFLOAT64:
+       case RID_DFLOAT128:
        case RID_BOOL:
        case RID_ENUM:
        case RID_STRUCT:
@@ -536,6 +538,9 @@ c_token_starts_declspecs (c_token *token)
        case RID_FLOAT:
        case RID_DOUBLE:
        case RID_VOID:
+       case RID_DFLOAT32:
+       case RID_DFLOAT64:
+       case RID_DFLOAT128:
        case RID_BOOL:
        case RID_ENUM:
        case RID_STRUCT:
@@ -639,18 +644,18 @@ c_parser_new (void)
    used.  */
 
 static void
-c_parser_error (c_parser *parser, const char *msgid)
+c_parser_error (c_parser *parser, const char *gmsgid)
 {
   c_token *token = c_parser_peek_token (parser);
   if (parser->error)
     return;
   parser->error = true;
-  if (!msgid)
+  if (!gmsgid)
     return;
   /* This diagnostic makes more sense if it is tagged to the line of
      the token we just peeked at.  */
   c_parser_set_source_position_from_token (token);
-  c_parse_error (msgid,
+  c_parse_error (gmsgid,
                 /* Because c_parse_error does not understand
                    CPP_KEYWORD, keywords are treated like
                    identifiers.  */
@@ -908,7 +913,7 @@ static void c_parser_while_statement (c_parser *);
 static void c_parser_do_statement (c_parser *);
 static void c_parser_for_statement (c_parser *);
 static tree c_parser_asm_statement (c_parser *);
-static tree c_parser_asm_operands (c_parser *);
+static tree c_parser_asm_operands (c_parser *, bool);
 static tree c_parser_asm_clobbers (c_parser *);
 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *);
 static struct c_expr c_parser_conditional_expression (c_parser *,
@@ -924,7 +929,8 @@ static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
                                                                struct c_expr);
 static struct c_expr c_parser_expression (c_parser *);
-static tree c_parser_expr_list (c_parser *);
+static struct c_expr c_parser_expression_conv (c_parser *);
+static tree c_parser_expr_list (c_parser *, bool);
 
 /* These Objective-C parser functions are only ever called when
    compiling Objective-C.  */
@@ -1399,6 +1405,9 @@ c_parser_asm_definition (c_parser *parser)
 
    type-specifier:
      typeof-specifier
+     _Decimal32
+     _Decimal64
+     _Decimal128
 
    Objective-C:
 
@@ -1497,6 +1506,9 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
        case RID_FLOAT:
        case RID_DOUBLE:
        case RID_VOID:
+       case RID_DFLOAT32:
+       case RID_DFLOAT64:
+       case RID_DFLOAT128:
        case RID_BOOL:
          if (!typespec_ok)
            goto out;
@@ -1828,6 +1840,7 @@ c_parser_struct_or_union_specifier (c_parser *parser)
       c_parser_error (parser, "expected %<{%>");
       ret.spec = error_mark_node;
       ret.kind = ctsk_tagref;
+      return ret;
     }
   ret = parser_xref_tag (code, ident);
   return ret;
@@ -1884,7 +1897,7 @@ c_parser_struct_declaration (c_parser *parser)
   specs = build_null_declspecs ();
   c_parser_declspecs (parser, specs, false, true, true);
   if (parser->error)
-    return error_mark_node;
+    return NULL_TREE;
   if (!specs->declspecs_seen_p)
     {
       c_parser_error (parser, "expected specifier-qualifier-list");
@@ -2148,7 +2161,7 @@ c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
      which is resolved in the direction of treating it as a typedef
      name.  If a close parenthesis follows, it is also an empty
      parameter list, as the syntax does not permit empty abstract
-     declarators.  Otherwise, it is a parenthesised declarator (in
+     declarators.  Otherwise, it is a parenthesized declarator (in
      which case the analysis may be repeated inside it, recursively).
 
      ??? There is an ambiguity in a parameter declaration "int
@@ -2158,7 +2171,7 @@ c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
      documenting.  At present we follow an accident of the old
      parser's implementation, whereby the first parameter must have
      some declaration specifiers other than just attributes.  Thus as
-     a parameter declaration it is treated as a parenthesised
+     a parameter declaration it is treated as a parenthesized
      parameter named x, and as an abstract declarator it is
      rejected.
 
@@ -2179,6 +2192,7 @@ c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
       struct c_declarator *inner
        = build_id_declarator (c_parser_peek_token (parser)->value);
       *seen_id = true;
+      inner->id_loc = c_parser_peek_token (parser)->location;
       c_parser_consume_token (parser);
       return c_parser_direct_declarator_inner (parser, *seen_id, inner);
     }
@@ -2357,12 +2371,13 @@ c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs)
       && c_parser_next_token_is (parser, CPP_NAME)
       && c_parser_peek_token (parser)->id_kind == C_ID_ID)
     {
-      tree list = NULL_TREE;
+      tree list = NULL_TREE, *nextp = &list;
       while (c_parser_next_token_is (parser, CPP_NAME)
             && c_parser_peek_token (parser)->id_kind == C_ID_ID)
        {
-         list = chainon (list, build_tree_list (NULL_TREE,
-                                                c_parser_peek_token (parser)->value));
+         *nextp = build_tree_list (NULL_TREE,
+                                   c_parser_peek_token (parser)->value);
+         nextp = & TREE_CHAIN (*nextp);
          c_parser_consume_token (parser);
          if (c_parser_next_token_is_not (parser, CPP_COMMA))
            break;
@@ -2463,6 +2478,7 @@ c_parser_parms_list_declarator (c_parser *parser, tree attrs)
        {
          tree new_attrs;
          c_parser_consume_token (parser);
+         mark_forward_parm_decls ();
          new_attrs = c_parser_attributes (parser);
          return c_parser_parms_list_declarator (parser, new_attrs);
        }
@@ -2713,6 +2729,9 @@ c_parser_attributes (c_parser *parser)
                case RID_FLOAT:
                case RID_DOUBLE:
                case RID_VOID:
+               case RID_DFLOAT32:
+               case RID_DFLOAT64:
+               case RID_DFLOAT128:
                case RID_BOOL:
                  ok = true;
                  break;
@@ -2750,7 +2769,7 @@ c_parser_attributes (c_parser *parser)
                {
                  c_parser_consume_token (parser);
                  attr_args = tree_cons (NULL_TREE, arg1,
-                                        c_parser_expr_list (parser));
+                                        c_parser_expr_list (parser, false));
                }
            }
          else
@@ -2758,7 +2777,7 @@ c_parser_attributes (c_parser *parser)
              if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
                attr_args = NULL_TREE;
              else
-               attr_args = c_parser_expr_list (parser);
+               attr_args = c_parser_expr_list (parser, false);
            }
          attr = build_tree_list (attr_name, attr_args);
          if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
@@ -2875,7 +2894,14 @@ c_parser_initializer (c_parser *parser)
   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
     return c_parser_braced_init (parser, NULL_TREE, false);
   else
-    return c_parser_expr_no_commas (parser, NULL);
+    {
+      struct c_expr ret;
+      ret = c_parser_expr_no_commas (parser, NULL);
+      if (TREE_CODE (ret.value) != STRING_CST
+         && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
+       ret = default_function_array_conversion (ret);
+      return ret;
+    }
 }
 
 /* Parse a braced initializer list.  TYPE is the type specified for a
@@ -3029,10 +3055,11 @@ c_parser_initelt (c_parser *parser)
                  rec = first;
                  while (c_parser_next_token_is (parser, CPP_COMMA))
                    {
-                     tree next;
+                     struct c_expr next;
                      c_parser_consume_token (parser);
-                     next = c_parser_expr_no_commas (parser, NULL).value;
-                     rec = build_compound_expr (rec, next);
+                     next = c_parser_expr_no_commas (parser, NULL);
+                     next = default_function_array_conversion (next);
+                     rec = build_compound_expr (rec, next.value);
                    }
                parse_message_args:
                  /* Now parse the objc-message-args.  */
@@ -3117,7 +3144,13 @@ c_parser_initval (c_parser *parser, struct c_expr *after)
   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
     init = c_parser_braced_init (parser, NULL_TREE, true);
   else
-    init = c_parser_expr_no_commas (parser, after);
+    {
+      init = c_parser_expr_no_commas (parser, after);
+      if (init.value != NULL_TREE
+         && TREE_CODE (init.value) != STRING_CST
+         && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
+       init = default_function_array_conversion (init);
+    }
   process_init_element (init);
 }
 
@@ -3237,7 +3270,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
       location_t loc = c_parser_peek_token (parser)->location;
       if (c_parser_next_token_is (parser, CPP_EOF))
        {
-         parser->error = true;
+         c_parser_error (parser, "expected declaration or statement");
          return;
        }
       if (c_parser_next_token_is_keyword (parser, RID_CASE)
@@ -3499,7 +3532,7 @@ c_parser_statement_after_labels (c_parser *parser)
            }
          else
            {
-             stmt = c_finish_return (c_parser_expression (parser).value);
+             stmt = c_finish_return (c_parser_expression_conv (parser).value);
              goto expect_semicolon;
            }
          break;
@@ -3547,7 +3580,7 @@ c_parser_statement_after_labels (c_parser *parser)
       break;
     default:
     expr_stmt:
-      stmt = c_finish_expr_stmt (c_parser_expression (parser).value);
+      stmt = c_finish_expr_stmt (c_parser_expression_conv (parser).value);
     expect_semicolon:
       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
       break;
@@ -3579,7 +3612,8 @@ c_parser_paren_condition (c_parser *parser)
   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
     return error_mark_node;
   loc = c_parser_peek_token (parser)->location;
-  cond = lang_hooks.truthvalue_conversion (c_parser_expression (parser).value);
+  cond = c_objc_common_truthvalue_conversion
+    (c_parser_expression_conv (parser).value);
   if (EXPR_P (cond))
     SET_EXPR_LOCATION (cond, loc);
   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
@@ -3613,7 +3647,7 @@ c_parser_if_body (c_parser *parser, bool *if_p)
     c_parser_label (parser);
   *if_p = c_parser_next_token_is_keyword (parser, RID_IF);
   if (extra_warnings && c_parser_next_token_is (parser, CPP_SEMICOLON))
-    add_stmt (build (NOP_EXPR, NULL_TREE, NULL_TREE));
+    add_stmt (build1 (NOP_EXPR, NULL_TREE, NULL_TREE));
   c_parser_statement_after_labels (parser);
   return c_end_compound_stmt (block, flag_isoc99);
 }
@@ -3676,7 +3710,7 @@ c_parser_switch_statement (c_parser *parser)
   body = c_parser_c99_block_statement (parser);
   c_finish_case (body);
   if (c_break_label)
-    add_stmt (build (LABEL_EXPR, void_type_node, c_break_label));
+    add_stmt (build1 (LABEL_EXPR, void_type_node, c_break_label));
   c_break_label = save_break;
   add_stmt (c_end_compound_stmt (block, flag_isoc99));
 }
@@ -3762,6 +3796,7 @@ c_parser_for_statement (c_parser *parser)
   tree block, cond, incr, save_break, save_cont, body;
   location_t loc;
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
+  loc = c_parser_peek_token (parser)->location;
   c_parser_consume_token (parser);
   block = c_begin_compound_stmt (flag_isoc99);
   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
@@ -3814,8 +3849,8 @@ c_parser_for_statement (c_parser *parser)
        }
       else
        {
-         tree ocond = c_parser_expression (parser).value;
-         cond = lang_hooks.truthvalue_conversion (ocond);
+         tree ocond = c_parser_expression_conv (parser).value;
+         cond = c_objc_common_truthvalue_conversion (ocond);
          if (EXPR_P (cond))
            SET_EXPR_LOCATION (cond, loc);
          c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
@@ -3874,7 +3909,7 @@ c_parser_asm_statement (c_parser *parser)
   else if (c_parser_next_token_is_keyword (parser, RID_CONST)
           || c_parser_next_token_is_keyword (parser, RID_RESTRICT))
     {
-      warning ("%E qualifier ignored on asm",
+      warning (0, "%E qualifier ignored on asm",
               c_parser_peek_token (parser)->value);
       quals = NULL_TREE;
       c_parser_consume_token (parser);
@@ -3910,7 +3945,7 @@ c_parser_asm_statement (c_parser *parser)
       || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
     outputs = NULL_TREE;
   else
-    outputs = c_parser_asm_operands (parser);
+    outputs = c_parser_asm_operands (parser, false);
   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
     {
       inputs = NULL_TREE;
@@ -3928,7 +3963,7 @@ c_parser_asm_statement (c_parser *parser)
       || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
     inputs = NULL_TREE;
   else
-    inputs = c_parser_asm_operands (parser);
+    inputs = c_parser_asm_operands (parser, true);
   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
     {
       clobbers = NULL_TREE;
@@ -3956,7 +3991,9 @@ c_parser_asm_statement (c_parser *parser)
   return ret;
 }
 
-/* Parse asm operands, a GNU extension.
+/* Parse asm operands, a GNU extension.  If CONVERT_P (for inputs but
+   not outputs), apply the default conversion of functions and arrays
+   to pointers.
 
    asm-operands:
      asm-operand
@@ -3968,12 +4005,13 @@ c_parser_asm_statement (c_parser *parser)
 */
 
 static tree
-c_parser_asm_operands (c_parser *parser)
+c_parser_asm_operands (c_parser *parser, bool convert_p)
 {
   tree list = NULL_TREE;
   while (true)
     {
-      tree name, str, expr;
+      tree name, str;
+      struct c_expr expr;
       if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
        {
          c_parser_consume_token (parser);
@@ -4004,7 +4042,9 @@ c_parser_asm_operands (c_parser *parser)
          c_lex_string_translate = 0;
          return NULL_TREE;
        }
-      expr = c_parser_expression (parser).value;
+      expr = c_parser_expression (parser);
+      if (convert_p)
+       expr = default_function_array_conversion (expr);
       c_lex_string_translate = 0;
       if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
        {
@@ -4012,7 +4052,7 @@ c_parser_asm_operands (c_parser *parser)
          return NULL_TREE;
        }
       list = chainon (list, build_tree_list (build_tree_list (name, str),
-                                            expr));
+                                            expr.value));
       if (c_parser_next_token_is (parser, CPP_COMMA))
        c_parser_consume_token (parser);
       else
@@ -4110,6 +4150,7 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
     }
   c_parser_consume_token (parser);
   rhs = c_parser_expr_no_commas (parser, NULL);
+  rhs = default_function_array_conversion (rhs);
   ret.value = build_modify_expr (lhs.value, code, rhs.value);
   if (code == NOP_EXPR)
     ret.original_code = MODIFY_EXPR;
@@ -4143,6 +4184,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
   cond = c_parser_binary_expression (parser, after);
   if (c_parser_next_token_is_not (parser, CPP_QUERY))
     return cond;
+  cond = default_function_array_conversion (cond);
   c_parser_consume_token (parser);
   if (c_parser_next_token_is (parser, CPP_COLON))
     {
@@ -4150,15 +4192,16 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
        pedwarn ("ISO C forbids omitting the middle term of a ?: expression");
       /* Make sure first operand is calculated only once.  */
       exp1.value = save_expr (default_conversion (cond.value));
-      cond.value = lang_hooks.truthvalue_conversion (exp1.value);
+      cond.value = c_objc_common_truthvalue_conversion (exp1.value);
       skip_evaluation += cond.value == truthvalue_true_node;
     }
   else
     {
       cond.value
-       = lang_hooks.truthvalue_conversion (default_conversion (cond.value));
+       = c_objc_common_truthvalue_conversion
+       (default_conversion (cond.value));
       skip_evaluation += cond.value == truthvalue_false_node;
-      exp1 = c_parser_expression (parser);
+      exp1 = c_parser_expression_conv (parser);
       skip_evaluation += ((cond.value == truthvalue_true_node)
                          - (cond.value == truthvalue_false_node));
     }
@@ -4170,6 +4213,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
       return ret;
     }
   exp2 = c_parser_conditional_expression (parser, NULL);
+  exp2 = default_function_array_conversion (exp2);
   skip_evaluation -= cond.value == truthvalue_true_node;
   ret.value = build_conditional_expr (cond.value, exp1.value, exp2.value);
   ret.original_code = ERROR_MARK;
@@ -4293,6 +4337,10 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
       default:                                                               \
        break;                                                                \
       }                                                                              \
+    stack[sp - 1].expr                                                       \
+      = default_function_array_conversion (stack[sp - 1].expr);                      \
+    stack[sp].expr                                                           \
+      = default_function_array_conversion (stack[sp].expr);                  \
     stack[sp - 1].expr = parser_build_binary_op (stack[sp].op,               \
                                                 stack[sp - 1].expr,          \
                                                 stack[sp].expr);             \
@@ -4393,12 +4441,16 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
       switch (ocode)
        {
        case TRUTH_ANDIF_EXPR:
-         stack[sp].expr.value = lang_hooks.truthvalue_conversion
+         stack[sp].expr
+           = default_function_array_conversion (stack[sp].expr);
+         stack[sp].expr.value = c_objc_common_truthvalue_conversion
            (default_conversion (stack[sp].expr.value));
          skip_evaluation += stack[sp].expr.value == truthvalue_false_node;
          break;
        case TRUTH_ORIF_EXPR:
-         stack[sp].expr.value = lang_hooks.truthvalue_conversion
+         stack[sp].expr
+           = default_function_array_conversion (stack[sp].expr);
+         stack[sp].expr.value = c_objc_common_truthvalue_conversion
            (default_conversion (stack[sp].expr.value));
          skip_evaluation += stack[sp].expr.value == truthvalue_true_node;
          break;
@@ -4441,7 +4493,7 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after)
     {
       struct c_type_name *type_name;
       struct c_expr ret;
-      tree expr;
+      struct c_expr expr;
       c_parser_consume_token (parser);
       type_name = c_parser_type_name (parser);
       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
@@ -4454,8 +4506,9 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after)
       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
        return c_parser_postfix_expression_after_paren_type (parser,
                                                             type_name);
-      expr = c_parser_cast_expression (parser, NULL).value;
-      ret.value = c_cast_expr (type_name, expr);
+      expr = c_parser_cast_expression (parser, NULL);
+      expr = default_function_array_conversion (expr);
+      ret.value = c_cast_expr (type_name, expr.value);
       ret.original_code = ERROR_MARK;
       return ret;
     }
@@ -4494,67 +4547,53 @@ static struct c_expr
 c_parser_unary_expression (c_parser *parser)
 {
   int ext;
-  struct c_expr ret;
-  ret.original_code = ERROR_MARK;
+  struct c_expr ret, op;
   switch (c_parser_peek_token (parser)->type)
     {
     case CPP_PLUS_PLUS:
       c_parser_consume_token (parser);
-      ret.value
-       = build_unary_op (PREINCREMENT_EXPR,
-                         c_parser_cast_expression (parser, NULL).value, 0);
-      overflow_warning (ret.value);
-      return ret;
+      op = c_parser_cast_expression (parser, NULL);
+      op = default_function_array_conversion (op);
+      return parser_build_unary_op (PREINCREMENT_EXPR, op);
     case CPP_MINUS_MINUS:
       c_parser_consume_token (parser);
-      ret.value
-       = build_unary_op (PREDECREMENT_EXPR,
-                         c_parser_cast_expression (parser, NULL).value, 0);
-      overflow_warning (ret.value);
-      return ret;
+      op = c_parser_cast_expression (parser, NULL);
+      op = default_function_array_conversion (op);
+      return parser_build_unary_op (PREDECREMENT_EXPR, op);
     case CPP_AND:
       c_parser_consume_token (parser);
-      ret.value
-       = build_unary_op (ADDR_EXPR,
-                         c_parser_cast_expression (parser, NULL).value, 0);
-      overflow_warning (ret.value);
-      return ret;
+      return parser_build_unary_op (ADDR_EXPR,
+                                   c_parser_cast_expression (parser, NULL));
     case CPP_MULT:
       c_parser_consume_token (parser);
-      ret.value
-       = build_indirect_ref (c_parser_cast_expression (parser, NULL).value,
-                             "unary *");
+      op = c_parser_cast_expression (parser, NULL);
+      op = default_function_array_conversion (op);
+      ret.value = build_indirect_ref (op.value, "unary *");
+      ret.original_code = ERROR_MARK;
       return ret;
     case CPP_PLUS:
       c_parser_consume_token (parser);
-      if (!c_dialect_objc () && warn_traditional && !in_system_header)
-       warning ("traditional C rejects the unary plus operator");
-      ret.value
-       = build_unary_op (CONVERT_EXPR,
-                         c_parser_cast_expression (parser, NULL).value, 0);
-      overflow_warning (ret.value);
-      return ret;
+      if (!c_dialect_objc () && !in_system_header)
+       warning (OPT_Wtraditional,
+                "traditional C rejects the unary plus operator");
+      op = c_parser_cast_expression (parser, NULL);
+      op = default_function_array_conversion (op);
+      return parser_build_unary_op (CONVERT_EXPR, op);
     case CPP_MINUS:
       c_parser_consume_token (parser);
-      ret.value
-       = build_unary_op (NEGATE_EXPR,
-                         c_parser_cast_expression (parser, NULL).value, 0);
-      overflow_warning (ret.value);
-      return ret;
+      op = c_parser_cast_expression (parser, NULL);
+      op = default_function_array_conversion (op);
+      return parser_build_unary_op (NEGATE_EXPR, op);
     case CPP_COMPL:
       c_parser_consume_token (parser);
-      ret.value
-       = build_unary_op (BIT_NOT_EXPR,
-                         c_parser_cast_expression (parser, NULL).value, 0);
-      overflow_warning (ret.value);
-      return ret;
+      op = c_parser_cast_expression (parser, NULL);
+      op = default_function_array_conversion (op);
+      return parser_build_unary_op (BIT_NOT_EXPR, op);
     case CPP_NOT:
       c_parser_consume_token (parser);
-      ret.value
-       = build_unary_op (TRUTH_NOT_EXPR,
-                         c_parser_cast_expression (parser, NULL).value, 0);
-      overflow_warning (ret.value);
-      return ret;
+      op = c_parser_cast_expression (parser, NULL);
+      op = default_function_array_conversion (op);
+      return parser_build_unary_op (TRUTH_NOT_EXPR, op);
     case CPP_AND_AND:
       /* Refer to the address of a label as a pointer.  */
       c_parser_consume_token (parser);
@@ -4563,14 +4602,14 @@ c_parser_unary_expression (c_parser *parser)
          ret.value = finish_label_address_expr
            (c_parser_peek_token (parser)->value);
          c_parser_consume_token (parser);
-         return ret;
        }
       else
        {
          c_parser_error (parser, "expected identifier");
          ret.value = error_mark_node;
-         return ret;
        }
+       ret.original_code = ERROR_MARK;
+       return ret;
     case CPP_KEYWORD:
       switch (c_parser_peek_token (parser)->keyword)
        {
@@ -4586,18 +4625,14 @@ c_parser_unary_expression (c_parser *parser)
          return ret;
        case RID_REALPART:
          c_parser_consume_token (parser);
-         ret.value
-           = build_unary_op (REALPART_EXPR,
-                             c_parser_cast_expression (parser, NULL).value,
-                             0);
-         return ret;
+         op = c_parser_cast_expression (parser, NULL);
+         op = default_function_array_conversion (op);
+         return parser_build_unary_op (REALPART_EXPR, op);
        case RID_IMAGPART:
          c_parser_consume_token (parser);
-         ret.value
-           = build_unary_op (IMAGPART_EXPR,
-                             c_parser_cast_expression (parser, NULL).value,
-                             0);
-         return ret;
+         op = c_parser_cast_expression (parser, NULL);
+         op = default_function_array_conversion (op);
+         return parser_build_unary_op (IMAGPART_EXPR, op);
        default:
          return c_parser_postfix_expression (parser);
        }
@@ -5018,7 +5053,6 @@ c_parser_postfix_expression (c_parser *parser)
            tree c;
 
            c = fold (e1.value);
-           STRIP_NOPS (c);
            if (TREE_CODE (c) != INTEGER_CST)
              error ("first argument to %<__builtin_choose_expr%> not"
                     " a constant");
@@ -5228,7 +5262,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
          if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
            exprlist = NULL_TREE;
          else
-           exprlist = c_parser_expr_list (parser);
+           exprlist = c_parser_expr_list (parser, true);
          c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
                                     "expected %<)%>");
          expr.value = build_function_call (expr.value, exprlist);
@@ -5237,6 +5271,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
        case CPP_DOT:
          /* Structure element reference.  */
          c_parser_consume_token (parser);
+         expr = default_function_array_conversion (expr);
          if (c_parser_next_token_is (parser, CPP_NAME))
            ident = c_parser_peek_token (parser)->value;
          else
@@ -5253,6 +5288,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
        case CPP_DEREF:
          /* Structure element reference.  */
          c_parser_consume_token (parser);
+         expr = default_function_array_conversion (expr);
          if (c_parser_next_token_is (parser, CPP_NAME))
            ident = c_parser_peek_token (parser)->value;
          else
@@ -5270,12 +5306,14 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
        case CPP_PLUS_PLUS:
          /* Postincrement.  */
          c_parser_consume_token (parser);
+         expr = default_function_array_conversion (expr);
          expr.value = build_unary_op (POSTINCREMENT_EXPR, expr.value, 0);
          expr.original_code = ERROR_MARK;
          break;
        case CPP_MINUS_MINUS:
          /* Postdecrement.  */
          c_parser_consume_token (parser);
+         expr = default_function_array_conversion (expr);
          expr.value = build_unary_op (POSTDECREMENT_EXPR, expr.value, 0);
          expr.original_code = ERROR_MARK;
          break;
@@ -5302,13 +5340,27 @@ c_parser_expression (c_parser *parser)
       struct c_expr next;
       c_parser_consume_token (parser);
       next = c_parser_expr_no_commas (parser, NULL);
+      next = default_function_array_conversion (next);
       expr.value = build_compound_expr (expr.value, next.value);
       expr.original_code = COMPOUND_EXPR;
     }
   return expr;
 }
 
-/* Parse a non-empty list of expressions.
+/* Parse an expression and convert functions or arrays to
+   pointers.  */
+
+static struct c_expr
+c_parser_expression_conv (c_parser *parser)
+{
+  struct c_expr expr;
+  expr = c_parser_expression (parser);
+  expr = default_function_array_conversion (expr);
+  return expr;
+}
+
+/* Parse a non-empty list of expressions.  If CONVERT_P, convert
+   functions and arrays to pointers.
 
    nonempty-expr-list:
      assignment-expression
@@ -5316,17 +5368,21 @@ c_parser_expression (c_parser *parser)
 */
 
 static tree
-c_parser_expr_list (c_parser *parser)
+c_parser_expr_list (c_parser *parser, bool convert_p)
 {
   struct c_expr expr;
-  tree ret;
+  tree ret, cur;
   expr = c_parser_expr_no_commas (parser, NULL);
-  ret = build_tree_list (NULL_TREE, expr.value);
+  if (convert_p)
+    expr = default_function_array_conversion (expr);
+  ret = cur = build_tree_list (NULL_TREE, expr.value);
   while (c_parser_next_token_is (parser, CPP_COMMA))
     {
       c_parser_consume_token (parser);
       expr = c_parser_expr_no_commas (parser, NULL);
-      ret = chainon (ret, build_tree_list (NULL_TREE, expr.value));
+      if (convert_p)
+       expr = default_function_array_conversion (expr);
+      cur = TREE_CHAIN (cur) = build_tree_list (NULL_TREE, expr.value);
     }
   return ret;
 }
@@ -5350,7 +5406,7 @@ c_parser_expr_list (c_parser *parser)
 
    "@interface identifier (" must start "@interface identifier (
    identifier ) ...": objc-methodprotolist in the first production may
-   not start with a parenthesised identifier as a declarator of a data
+   not start with a parenthesized identifier as a declarator of a data
    definition with no declaration specifiers if the objc-superclass,
    objc-protocol-refs and objc-class-instance-variables are omitted.  */
 
@@ -5686,6 +5742,11 @@ c_parser_objc_method_definition (c_parser *parser)
       if (pedantic)
        pedwarn ("extra semicolon in method definition specified");
     }
+  if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
+    {
+      c_parser_error (parser, "expected %<{%>");
+      return;
+    }
   objc_pq_context = 0;
   objc_start_method_definition (decl);
   add_stmt (c_parser_compound_statement (parser));
@@ -5791,6 +5852,8 @@ c_parser_objc_method_decl (c_parser *parser)
   tree type = NULL_TREE;
   tree sel;
   tree parms = NULL_TREE;
+  bool ellipsis = false;
+
   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
     {
       c_parser_consume_token (parser);
@@ -5805,7 +5868,6 @@ c_parser_objc_method_decl (c_parser *parser)
     {
       tree tsel = sel;
       tree list = NULL_TREE;
-      bool ellipsis;
       while (true)
        {
          tree atype = NULL_TREE, id, keyworddecl;
@@ -5835,7 +5897,6 @@ c_parser_objc_method_decl (c_parser *parser)
         method parameters follow the C syntax, and may include '...'
         to denote a variable number of arguments.  */
       parms = make_node (TREE_LIST);
-      ellipsis = false;
       while (c_parser_next_token_is (parser, CPP_COMMA))
        {
          struct c_parm *parm;
@@ -5852,10 +5913,9 @@ c_parser_objc_method_decl (c_parser *parser)
          parms = chainon (parms,
                           build_tree_list (NULL_TREE, grokparm (parm)));
        }
-      TREE_OVERFLOW (parms) = ellipsis;
       sel = list;
     }
-  return objc_build_method_signature (type, sel, parms);
+  return objc_build_method_signature (type, sel, parms, ellipsis);
 }
 
 /* Parse an objc-type-name.
@@ -6187,7 +6247,7 @@ c_parser_objc_message_args (c_parser *parser)
 static tree
 c_parser_objc_keywordexpr (c_parser *parser)
 {
-  tree list = c_parser_expr_list (parser);
+  tree list = c_parser_expr_list (parser, true);
   if (TREE_CHAIN (list) == NULL_TREE)
     {
       /* Just return the expression, remove a level of