c-tree.h (default_function_array_conversion): Declare.
authorJoseph Myers <joseph@codesourcery.com>
Wed, 15 Jun 2005 15:55:47 +0000 (16:55 +0100)
committerJoseph Myers <jsm28@gcc.gnu.org>
Wed, 15 Jun 2005 15:55:47 +0000 (16:55 +0100)
* c-tree.h (default_function_array_conversion): Declare.
* c-typeck.c (default_function_array_conversion): Export.  Correct
comment.
(default_conversion): Do not call
default_function_array_conversion.  Do not allow FUNCTION_TYPE.
(build_function_call): Call default_function_array_conversion on
the function.
(convert_arguments): Do not call it on the function arguments.
(build_unary_op): Do not allow ARRAY_TYPE or FUNCTION_TYPE for
TRUTH_NOT_EXPR.  Call default_function_array_conversion for taking
address of ARRAY_REF.
(build_compound_expr): Do not call
default_function_array_conversion.
(build_c_cast): Do not call default_function_array_conversion.
(convert_for_assignment): Do not call default_conversion.
(digest_init): Call default_function_array_conversion to convert
string constants and compound literals to pointers, but not
otherwise.
(output_init_element): Likewise.
(build_asm_expr): Do not call default_function_array_conversion.
(c_process_expr_stmt): Likewise.
(c_objc_common_truthvalue_conversion): Likewise.  Do not allow
FUNCTION_TYPE.
* c-parser.c (c_parser_expression_conv): New.
(c_parser_asm_operands, c_parser_expr_list): Add convert_p
argument.  All callers changed.  Call
default_function_array_conversion if convert_p.
(c_parser_initializer, c_parser_initval): Call
default_function_array_conversion except for string constants and
compound literals.
(c_parser_initelt): Call default_function_array_conversion for
ObjC expression received.
(c_parser_statement_after_labels): Call c_parser_expression_conv
for return and expression statements.
(c_parser_paren_condition, c_parser_for_statement,
c_parser_conditional_expression): Call c_parser_expression_conv.
(c_parser_expr_no_commas, c_parser_conditional_expression,
c_parser_binary_expression, c_parser_cast_expression,
c_parser_unary_expression): Call
default_function_array_conversion.

objc:
* objc-act.c (my_build_string_pointer): New.
(objc_get_class_reference, get_super_receiver): Call
my_build_string_pointer instead of my_build_string when building
function arguments.

testsuite:
* gcc.dg/noncompile/20040203-3.c: Update expected message.

From-SVN: r100984

gcc/ChangeLog
gcc/c-parser.c
gcc/c-tree.h
gcc/c-typeck.c
gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/noncompile/20040203-3.c

index b029e3d..dc88ef0 100644 (file)
@@ -1,3 +1,46 @@
+2005-06-15  Joseph S. Myers  <joseph@codesourcery.com>
+
+       * c-tree.h (default_function_array_conversion): Declare.
+       * c-typeck.c (default_function_array_conversion): Export.  Correct
+       comment.
+       (default_conversion): Do not call
+       default_function_array_conversion.  Do not allow FUNCTION_TYPE.
+       (build_function_call): Call default_function_array_conversion on
+       the function.
+       (convert_arguments): Do not call it on the function arguments.
+       (build_unary_op): Do not allow ARRAY_TYPE or FUNCTION_TYPE for
+       TRUTH_NOT_EXPR.  Call default_function_array_conversion for taking
+       address of ARRAY_REF.
+       (build_compound_expr): Do not call
+       default_function_array_conversion.
+       (build_c_cast): Do not call default_function_array_conversion.
+       (convert_for_assignment): Do not call default_conversion.
+       (digest_init): Call default_function_array_conversion to convert
+       string constants and compound literals to pointers, but not
+       otherwise.
+       (output_init_element): Likewise.
+       (build_asm_expr): Do not call default_function_array_conversion.
+       (c_process_expr_stmt): Likewise.
+       (c_objc_common_truthvalue_conversion): Likewise.  Do not allow
+       FUNCTION_TYPE.
+       * c-parser.c (c_parser_expression_conv): New.
+       (c_parser_asm_operands, c_parser_expr_list): Add convert_p
+       argument.  All callers changed.  Call
+       default_function_array_conversion if convert_p.
+       (c_parser_initializer, c_parser_initval): Call
+       default_function_array_conversion except for string constants and
+       compound literals.
+       (c_parser_initelt): Call default_function_array_conversion for
+       ObjC expression received.
+       (c_parser_statement_after_labels): Call c_parser_expression_conv
+       for return and expression statements.
+       (c_parser_paren_condition, c_parser_for_statement,
+       c_parser_conditional_expression): Call c_parser_expression_conv.
+       (c_parser_expr_no_commas, c_parser_conditional_expression,
+       c_parser_binary_expression, c_parser_cast_expression,
+       c_parser_unary_expression): Call
+       default_function_array_conversion.
+
 2005-06-15  Diego Novillo  <dnovillo@redhat.com>
 
        * tree-vrp.c (vrp_int_const_binop): Do not handle MAX_EXPR
index abb8b22..88b89e2 100644 (file)
@@ -904,7 +904,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 *,
@@ -920,7 +920,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.  */
@@ -2749,7 +2750,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
@@ -2757,7 +2758,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))
@@ -2874,7 +2875,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.value = default_function_array_conversion (ret.value);
+      return ret;
+    }
 }
 
 /* Parse a braced initializer list.  TYPE is the type specified for a
@@ -3031,6 +3039,7 @@ c_parser_initelt (c_parser *parser)
                      tree next;
                      c_parser_consume_token (parser);
                      next = c_parser_expr_no_commas (parser, NULL).value;
+                     next = default_function_array_conversion (next);
                      rec = build_compound_expr (rec, next);
                    }
                parse_message_args:
@@ -3116,7 +3125,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.value = default_function_array_conversion (init.value);
+    }
   process_init_element (init);
 }
 
@@ -3498,7 +3513,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;
@@ -3546,7 +3561,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 +3594,7 @@ c_parser_paren_condition (c_parser *parser)
     return error_mark_node;
   loc = c_parser_peek_token (parser)->location;
   cond = c_objc_common_truthvalue_conversion
-    (c_parser_expression (parser).value);
+    (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 %<)%>");
@@ -3814,7 +3829,7 @@ c_parser_for_statement (c_parser *parser)
        }
       else
        {
-         tree ocond = c_parser_expression (parser).value;
+         tree ocond = c_parser_expression_conv (parser).value;
          cond = c_objc_common_truthvalue_conversion (ocond);
          if (EXPR_P (cond))
            SET_EXPR_LOCATION (cond, loc);
@@ -3910,7 +3925,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 +3943,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 +3971,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,7 +3985,7 @@ 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)
@@ -4005,6 +4022,8 @@ c_parser_asm_operands (c_parser *parser)
          return NULL_TREE;
        }
       expr = c_parser_expression (parser).value;
+      if (convert_p)
+       expr = default_function_array_conversion (expr);
       c_lex_string_translate = 0;
       if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
        {
@@ -4110,6 +4129,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.value = default_function_array_conversion (rhs.value);
   ret.value = build_modify_expr (lhs.value, code, rhs.value);
   if (code == NOP_EXPR)
     ret.original_code = MODIFY_EXPR;
@@ -4143,6 +4163,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.value = default_function_array_conversion (cond.value);
   c_parser_consume_token (parser);
   if (c_parser_next_token_is (parser, CPP_COLON))
     {
@@ -4159,7 +4180,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
        = 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));
     }
@@ -4171,6 +4192,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
       return ret;
     }
   exp2 = c_parser_conditional_expression (parser, NULL);
+  exp2.value = default_function_array_conversion (exp2.value);
   skip_evaluation -= cond.value == truthvalue_true_node;
   ret.value = build_conditional_expr (cond.value, exp1.value, exp2.value);
   ret.original_code = ERROR_MARK;
@@ -4294,6 +4316,10 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
       default:                                                               \
        break;                                                                \
       }                                                                              \
+    stack[sp - 1].expr.value                                                 \
+      = default_function_array_conversion (stack[sp - 1].expr.value);        \
+    stack[sp].expr.value                                                     \
+      = default_function_array_conversion (stack[sp].expr.value);            \
     stack[sp - 1].expr = parser_build_binary_op (stack[sp].op,               \
                                                 stack[sp - 1].expr,          \
                                                 stack[sp].expr);             \
@@ -4394,11 +4420,15 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
       switch (ocode)
        {
        case TRUTH_ANDIF_EXPR:
+         stack[sp].expr.value
+           = default_function_array_conversion (stack[sp].expr.value);
          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
+           = default_function_array_conversion (stack[sp].expr.value);
          stack[sp].expr.value = c_objc_common_truthvalue_conversion
            (default_conversion (stack[sp].expr.value));
          skip_evaluation += stack[sp].expr.value == truthvalue_true_node;
@@ -4456,6 +4486,7 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after)
        return c_parser_postfix_expression_after_paren_type (parser,
                                                             type_name);
       expr = c_parser_cast_expression (parser, NULL).value;
+      expr = default_function_array_conversion (expr);
       ret.value = c_cast_expr (type_name, expr);
       ret.original_code = ERROR_MARK;
       return ret;
@@ -4495,26 +4526,28 @@ static struct c_expr
 c_parser_unary_expression (c_parser *parser)
 {
   int ext;
-  struct c_expr ret;
+  struct c_expr ret, op;
   switch (c_parser_peek_token (parser)->type)
     {
     case CPP_PLUS_PLUS:
       c_parser_consume_token (parser);
-      return parser_build_unary_op (PREINCREMENT_EXPR,
-                                   c_parser_cast_expression (parser, NULL));
+      op = c_parser_cast_expression (parser, NULL);
+      op.value = default_function_array_conversion (op.value);
+      return parser_build_unary_op (PREINCREMENT_EXPR, op);
     case CPP_MINUS_MINUS:
       c_parser_consume_token (parser);
-      return parser_build_unary_op (PREDECREMENT_EXPR,
-                                   c_parser_cast_expression (parser, NULL));
+      op = c_parser_cast_expression (parser, NULL);
+      op.value = default_function_array_conversion (op.value);
+      return parser_build_unary_op (PREDECREMENT_EXPR, op);
     case CPP_AND:
       c_parser_consume_token (parser);
       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.value = default_function_array_conversion (op.value);
+      ret.value = build_indirect_ref (op.value, "unary *");
       ret.original_code = ERROR_MARK;
       return ret;
     case CPP_PLUS:
@@ -4522,20 +4555,24 @@ c_parser_unary_expression (c_parser *parser)
       if (!c_dialect_objc () && !in_system_header)
        warning (OPT_Wtraditional,
                 "traditional C rejects the unary plus operator");
-      return parser_build_unary_op (CONVERT_EXPR,
-                                   c_parser_cast_expression (parser, NULL));
+      op = c_parser_cast_expression (parser, NULL);
+      op.value = default_function_array_conversion (op.value);
+      return parser_build_unary_op (CONVERT_EXPR, op);
     case CPP_MINUS:
       c_parser_consume_token (parser);
-      return parser_build_unary_op (NEGATE_EXPR,
-                                   c_parser_cast_expression (parser, NULL));
+      op = c_parser_cast_expression (parser, NULL);
+      op.value = default_function_array_conversion (op.value);
+      return parser_build_unary_op (NEGATE_EXPR, op);
     case CPP_COMPL:
       c_parser_consume_token (parser);
-      return parser_build_unary_op (BIT_NOT_EXPR,
-                                   c_parser_cast_expression (parser, NULL));
+      op = c_parser_cast_expression (parser, NULL);
+      op.value = default_function_array_conversion (op.value);
+      return parser_build_unary_op (BIT_NOT_EXPR, op);
     case CPP_NOT:
       c_parser_consume_token (parser);
-      return parser_build_unary_op (TRUTH_NOT_EXPR,
-                                   c_parser_cast_expression (parser, NULL));
+      op = c_parser_cast_expression (parser, NULL);
+      op.value = default_function_array_conversion (op.value);
+      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);
@@ -4567,14 +4604,14 @@ c_parser_unary_expression (c_parser *parser)
          return ret;
        case RID_REALPART:
          c_parser_consume_token (parser);
-         return parser_build_unary_op (REALPART_EXPR,
-                                       c_parser_cast_expression (parser,
-                                                                 NULL));
+         op = c_parser_cast_expression (parser, NULL);
+         op.value = default_function_array_conversion (op.value);
+         return parser_build_unary_op (REALPART_EXPR, op);
        case RID_IMAGPART:
          c_parser_consume_token (parser);
-         return parser_build_unary_op (IMAGPART_EXPR,
-                                       c_parser_cast_expression (parser,
-                                                                 NULL));
+         op = c_parser_cast_expression (parser, NULL);
+         op.value = default_function_array_conversion (op.value);
+         return parser_build_unary_op (IMAGPART_EXPR, op);
        default:
          return c_parser_postfix_expression (parser);
        }
@@ -5204,7 +5241,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);
@@ -5213,6 +5250,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
        case CPP_DOT:
          /* Structure element reference.  */
          c_parser_consume_token (parser);
+         expr.value = default_function_array_conversion (expr.value);
          if (c_parser_next_token_is (parser, CPP_NAME))
            ident = c_parser_peek_token (parser)->value;
          else
@@ -5229,6 +5267,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
        case CPP_DEREF:
          /* Structure element reference.  */
          c_parser_consume_token (parser);
+         expr.value = default_function_array_conversion (expr.value);
          if (c_parser_next_token_is (parser, CPP_NAME))
            ident = c_parser_peek_token (parser)->value;
          else
@@ -5246,12 +5285,14 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
        case CPP_PLUS_PLUS:
          /* Postincrement.  */
          c_parser_consume_token (parser);
+         expr.value = default_function_array_conversion (expr.value);
          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.value = default_function_array_conversion (expr.value);
          expr.value = build_unary_op (POSTDECREMENT_EXPR, expr.value, 0);
          expr.original_code = ERROR_MARK;
          break;
@@ -5278,13 +5319,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.value = default_function_array_conversion (next.value);
       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.value = default_function_array_conversion (expr.value);
+  return expr;
+}
+
+/* Parse a non-empty list of expressions.  If CONVERT_P, convert
+   functions and arrays to pointers.
 
    nonempty-expr-list:
      assignment-expression
@@ -5292,16 +5347,20 @@ 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, cur;
   expr = c_parser_expr_no_commas (parser, NULL);
+  if (convert_p)
+    expr.value = default_function_array_conversion (expr.value);
   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);
+      if (convert_p)
+       expr.value = default_function_array_conversion (expr.value);
       cur = TREE_CHAIN (cur) = build_tree_list (NULL_TREE, expr.value);
     }
   return ret;
@@ -6162,7 +6221,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
index 7af8130..e2e3bf8 100644 (file)
@@ -523,6 +523,7 @@ extern bool c_mark_addressable (tree);
 extern void c_incomplete_type_error (tree, tree);
 extern tree c_type_promotes_to (tree);
 extern tree default_conversion (tree);
+extern tree default_function_array_conversion (tree);
 extern tree composite_type (tree, tree);
 extern tree build_component_ref (tree, tree);
 extern tree build_indirect_ref (tree, const char *);
index 445193d..7dcd577 100644 (file)
@@ -80,7 +80,6 @@ static int comp_target_types (tree, tree);
 static int function_types_compatible_p (tree, tree);
 static int type_lists_compatible_p (tree, tree);
 static tree decl_constant_value_for_broken_optimization (tree);
-static tree default_function_array_conversion (tree);
 static tree lookup_field (tree, tree);
 static tree convert_arguments (tree, tree, tree, tree);
 static tree pointer_diff (tree, tree);
@@ -1263,9 +1262,9 @@ decl_constant_value_for_broken_optimization (tree decl)
 
 /* Perform the default conversion of arrays and functions to pointers.
    Return the result of converting EXP.  For any other expression, just
-   return EXP.  */
+   return EXP after removing NOPs.  */
 
-static tree
+tree
 default_function_array_conversion (tree exp)
 {
   tree orig_exp;
@@ -1410,8 +1409,7 @@ perform_integral_promotions (tree exp)
 
 
 /* Perform default promotions for C data used in expressions.
-   Arrays and functions are converted to pointers;
-   enumeral types or short or char, to int.
+   Enumeral types or short or char are converted to int.
    In addition, manifest constants symbols are replaced by their values.  */
 
 tree
@@ -1421,8 +1419,10 @@ default_conversion (tree exp)
   tree type = TREE_TYPE (exp);
   enum tree_code code = TREE_CODE (type);
 
-  if (code == FUNCTION_TYPE || code == ARRAY_TYPE)
-    return default_function_array_conversion (exp);
+  /* Functions and arrays have been converted during parsing.  */
+  gcc_assert (code != FUNCTION_TYPE);
+  if (code == ARRAY_TYPE)
+    return exp;
 
   /* Constants can be used directly unless they're not loadable.  */
   if (TREE_CODE (exp) == CONST_DECL)
@@ -1990,18 +1990,8 @@ build_function_call (tree function, tree params)
        return tem;
 
       name = DECL_NAME (function);
-
-      /* Differs from default_conversion by not setting TREE_ADDRESSABLE
-        (because calling an inline function does not mean the function
-        needs to be separately compiled).  */
-      fntype = build_type_variant (TREE_TYPE (function),
-                                  TREE_READONLY (function),
-                                  TREE_THIS_VOLATILE (function));
-      fundecl = function;
-      function = build1 (ADDR_EXPR, build_pointer_type (fntype), function);
     }
-  else
-    function = default_conversion (function);
+  function = default_function_array_conversion (function);
 
   /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
      expressions, like those used for ObjC messenger dispatches.  */
@@ -2163,8 +2153,6 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl)
 
       STRIP_TYPE_NOPS (val);
 
-      val = default_function_array_conversion (val);
-
       val = require_complete_type (val);
 
       if (type != 0)
@@ -2589,13 +2577,9 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
       break;
 
     case TRUTH_NOT_EXPR:
-      /* ??? Why do most validation here but that for non-lvalue arrays
-        in c_objc_common_truthvalue_conversion?  */
       if (typecode != INTEGER_TYPE
          && typecode != REAL_TYPE && typecode != POINTER_TYPE
-         && typecode != COMPLEX_TYPE
-         /* These will convert to a pointer.  */
-         && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE)
+         && typecode != COMPLEX_TYPE)
        {
          error ("wrong type argument to unary exclamation mark");
          return error_mark_node;
@@ -2736,7 +2720,9 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
        {
          if (!c_mark_addressable (TREE_OPERAND (arg, 0)))
            return error_mark_node;
-         return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0),
+         return build_binary_op (PLUS_EXPR,
+                                 default_function_array_conversion
+                                   (TREE_OPERAND (arg, 0)),
                                  TREE_OPERAND (arg, 1), 1);
        }
 
@@ -3115,9 +3101,6 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
 tree
 build_compound_expr (tree expr1, tree expr2)
 {
-  /* Convert arrays and functions to pointers.  */
-  expr2 = default_function_array_conversion (expr2);
-
   if (!TREE_SIDE_EFFECTS (expr1))
     {
       /* The left-hand operand of a comma expression is like an expression
@@ -3189,7 +3172,6 @@ build_c_cast (tree type, tree expr)
   else if (TREE_CODE (type) == UNION_TYPE)
     {
       tree field;
-      value = default_function_array_conversion (value);
 
       for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
        if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)),
@@ -3217,14 +3199,9 @@ build_c_cast (tree type, tree expr)
     {
       tree otype, ovalue;
 
-      /* If casting to void, avoid the error that would come
-        from default_conversion in the case of a non-lvalue array.  */
       if (type == void_type_node)
        return build1 (CONVERT_EXPR, type, value);
 
-      /* Convert functions and arrays to pointers,
-        but don't convert any other types.  */
-      value = default_function_array_conversion (value);
       otype = TREE_TYPE (value);
 
       /* Optionally warn about potentially worrisome casts.  */
@@ -3558,10 +3535,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
 
   STRIP_TYPE_NOPS (rhs);
 
-  if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
-      || TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE)
-    rhs = default_conversion (rhs);
-  else if (optimize && TREE_CODE (rhs) == VAR_DECL)
+  if (optimize && TREE_CODE (rhs) == VAR_DECL
+          && TREE_CODE (TREE_TYPE (rhs)) != ARRAY_TYPE)
     rhs = decl_constant_value_for_broken_optimization (rhs);
 
   rhstype = TREE_TYPE (rhs);
@@ -4373,15 +4348,13 @@ digest_init (tree type, tree init, bool strict_string, int require_constant)
          || (code == POINTER_TYPE
              && TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
              && comptypes (TREE_TYPE (TREE_TYPE (inside_init)),
-                           TREE_TYPE (type)))
-         || (code == POINTER_TYPE
-             && TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE
-             && comptypes (TREE_TYPE (inside_init),
                            TREE_TYPE (type)))))
     {
       if (code == POINTER_TYPE)
        {
-         inside_init = default_function_array_conversion (inside_init);
+         if (TREE_CODE (inside_init) == STRING_CST
+             || TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
+           inside_init = default_function_array_conversion (inside_init);
 
          if (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE)
            {
@@ -4448,9 +4421,9 @@ digest_init (tree type, tree init, bool strict_string, int require_constant)
       || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
       || code == VECTOR_TYPE)
     {
-      /* Note that convert_for_assignment calls default_conversion
-        for arrays and functions.  We must not call it in the
-        case where inside_init is a null pointer constant.  */
+      if (TREE_CODE (init) == STRING_CST
+         || TREE_CODE (init) == COMPOUND_LITERAL_EXPR)
+       init = default_function_array_conversion (init);
       inside_init
        = convert_for_assignment (type, init, ic_init,
                                  NULL_TREE, NULL_TREE, 0);
@@ -5800,14 +5773,15 @@ output_init_element (tree value, bool strict_string, tree type, tree field,
       constructor_erroneous = 1;
       return;
     }
-  if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
-      || (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
-         && !(TREE_CODE (value) == STRING_CST
-              && TREE_CODE (type) == ARRAY_TYPE
-              && INTEGRAL_TYPE_P (TREE_TYPE (type)))
-         && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)),
-                        TYPE_MAIN_VARIANT (type))))
-    value = default_conversion (value);
+  if (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
+      && (TREE_CODE (value) == STRING_CST
+         || TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
+      && !(TREE_CODE (value) == STRING_CST
+          && TREE_CODE (type) == ARRAY_TYPE
+          && INTEGRAL_TYPE_P (TREE_TYPE (type)))
+      && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)),
+                    TYPE_MAIN_VARIANT (type)))
+    value = default_function_array_conversion (value);
 
   if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR
       && require_constant_value && !flag_isoc99 && pending)
@@ -6519,9 +6493,6 @@ build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
       TREE_VALUE (tail) = output;
     }
 
-  /* Perform default conversions on array and function inputs.
-     Don't do this for other types as it would screw up operands
-     expected to be in memory.  */
   for (i = 0, tail = inputs; tail; ++i, tail = TREE_CHAIN (tail))
     {
       tree input;
@@ -6529,8 +6500,6 @@ build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
       constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
       input = TREE_VALUE (tail);
 
-      input = default_function_array_conversion (input);
-
       if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0,
                                  oconstraints, &allows_mem, &allows_reg))
        {
@@ -7084,13 +7053,6 @@ c_process_expr_stmt (tree expr)
   if (!expr)
     return NULL_TREE;
 
-  /* Do default conversion if safe and possibly important,
-     in case within ({...}).  */
-  if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
-       && (flag_isoc99 || lvalue_p (expr)))
-      || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE)
-    expr = default_conversion (expr);
-
   if (warn_sequence_point)
     verify_sequence_points (expr);
 
@@ -8107,12 +8069,11 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
 
 
 /* Convert EXPR to be a truth-value, validating its type for this
-   purpose.  Passes EXPR to default_function_array_conversion.  */
+   purpose.  */
 
 tree
 c_objc_common_truthvalue_conversion (tree expr)
 {
-  expr = default_function_array_conversion (expr);
   switch (TREE_CODE (TREE_TYPE (expr)))
     {
     case ARRAY_TYPE:
@@ -8127,6 +8088,9 @@ c_objc_common_truthvalue_conversion (tree expr)
       error ("used union type value where scalar is required");
       return error_mark_node;
 
+    case FUNCTION_TYPE:
+      gcc_unreachable ();
+
     default:
       break;
     }
index a36cce8..d9eb3d1 100644 (file)
@@ -1,3 +1,10 @@
+2005-06-15  Joseph S. Myers  <joseph@codesourcery.com>
+
+       * objc-act.c (my_build_string_pointer): New.
+       (objc_get_class_reference, get_super_receiver): Call
+       my_build_string_pointer instead of my_build_string when building
+       function arguments.
+
 2005-05-25  Mike Stump  <mrs@mrs.kithrup.com>
 
        * objc-act.c (volatilized_hash): Avoid warnings on 64-bit
index 95a8489..3329318 100644 (file)
@@ -1722,6 +1722,16 @@ my_build_string (int len, const char *str)
   return fix_string_type (build_string (len, str));
 }
 
+/* Build a string with contents STR and length LEN and convert it to a
+   pointer.  */
+
+static tree
+my_build_string_pointer (int len, const char *str)
+{
+  tree string = my_build_string (len, str);
+  tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
+  return build1 (ADDR_EXPR, ptrtype, string);
+}
 
 static hashval_t
 string_hash (const void *ptr)
@@ -2699,8 +2709,9 @@ objc_get_class_reference (tree ident)
       add_class_reference (ident);
 
       params = build_tree_list (NULL_TREE,
-                               my_build_string (IDENTIFIER_LENGTH (ident) + 1,
-                                                IDENTIFIER_POINTER (ident)));
+                               my_build_string_pointer
+                               (IDENTIFIER_LENGTH (ident) + 1,
+                                IDENTIFIER_POINTER (ident)));
 
       assemble_external (objc_get_class_decl);
       return build_function_call (objc_get_class_decl, params);
@@ -8641,8 +8652,9 @@ get_super_receiver (void)
                  (super_class,
                   build_tree_list
                   (NULL_TREE,
-                   my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
-                                    IDENTIFIER_POINTER (super_name))));
+                   my_build_string_pointer
+                   (IDENTIFIER_LENGTH (super_name) + 1,
+                    IDENTIFIER_POINTER (super_name))));
            }
 
          super_expr
index 30cc646..adcfe2d 100644 (file)
@@ -1,3 +1,7 @@
+2005-06-15  Joseph S. Myers  <joseph@codesourcery.com>
+
+       * gcc.dg/noncompile/20040203-3.c: Update expected message.
+
 2005-06-15  David Ung  <davidu@mips.com>
 
        * gcc.target/mips/mips16e-extends.c: New test for testing the
index bd57c4d..5b90c3e 100644 (file)
@@ -12,5 +12,5 @@ int bug_or(void) { return (f().c || 1); }  /* { dg-error "array that cannot be c
 int bug_and(void) { return (f().c && 1); }  /* { dg-error "array that cannot be converted" } */
 int bug_cond(void) { return (f().c ? 1 : 0); }  /* { dg-error "array that cannot be converted" } */
 int bug_cond2(void) { return (f().c ? : 0); }  /* { dg-error "array that cannot be converted" } */
-int bug_not(void) { return !f().c; }  /* { dg-error "array that cannot be converted" } */
+int bug_not(void) { return !f().c; }  /* { dg-error "wrong type argument to unary exclamation mark" } */
 int bug_bool(void) { return (_Bool) f().c; }  /* { dg-error "array that cannot be converted" } */