From f14c820769ea23e8fee897c654e56ccc65aa3cca Mon Sep 17 00:00:00 2001 From: jsm28 Date: Wed, 15 Jun 2005 15:55:47 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@100984 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 43 ++++++++ gcc/c-parser.c | 141 +++++++++++++++++++-------- gcc/c-tree.h | 1 + gcc/c-typeck.c | 102 +++++++------------ gcc/objc/ChangeLog | 7 ++ gcc/objc/objc-act.c | 20 +++- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gcc.dg/noncompile/20040203-3.c | 2 +- 8 files changed, 205 insertions(+), 115 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b029e3ded45..dc88ef01348 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,46 @@ +2005-06-15 Joseph S. Myers + + * 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 * tree-vrp.c (vrp_int_const_binop): Do not handle MAX_EXPR diff --git a/gcc/c-parser.c b/gcc/c-parser.c index abb8b229132..88b89e2804f 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -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 diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 7af8130a426..e2e3bf8b26c 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -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 *); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 445193d9802..7dcd577f538 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -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; } diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index a36cce89cd6..d9eb3d15f8d 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,10 @@ +2005-06-15 Joseph S. Myers + + * 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 * objc-act.c (volatilized_hash): Avoid warnings on 64-bit diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 95a848924ed..3329318ef2a 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 30cc6469cb9..adcfe2dd5ad 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2005-06-15 Joseph S. Myers + + * gcc.dg/noncompile/20040203-3.c: Update expected message. + 2005-06-15 David Ung * gcc.target/mips/mips16e-extends.c: New test for testing the diff --git a/gcc/testsuite/gcc.dg/noncompile/20040203-3.c b/gcc/testsuite/gcc.dg/noncompile/20040203-3.c index bd57c4dfe43..5b90c3ee844 100644 --- a/gcc/testsuite/gcc.dg/noncompile/20040203-3.c +++ b/gcc/testsuite/gcc.dg/noncompile/20040203-3.c @@ -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" } */ -- 2.11.0