diff options
author | Joseph Myers <joseph@codesourcery.com> | 2005-06-15 16:55:47 +0100 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2005-06-15 16:55:47 +0100 |
commit | 46bdb9cffb6b1cd45bc8032f9b1d7e9e101ba7b0 (patch) | |
tree | 1872e122192fae90234ef8f17d82cd485d62d6cf /gcc/c-parser.c | |
parent | 38e19e4c73b8614fb094c5c36abdd7da47a26a50 (diff) | |
download | gcc-46bdb9cffb6b1cd45bc8032f9b1d7e9e101ba7b0.zip gcc-46bdb9cffb6b1cd45bc8032f9b1d7e9e101ba7b0.tar.gz gcc-46bdb9cffb6b1cd45bc8032f9b1d7e9e101ba7b0.tar.bz2 |
c-tree.h (default_function_array_conversion): Declare.
* 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
Diffstat (limited to 'gcc/c-parser.c')
-rw-r--r-- | gcc/c-parser.c | 141 |
1 files changed, 100 insertions, 41 deletions
diff --git a/gcc/c-parser.c b/gcc/c-parser.c index abb8b229..88b89e2 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 |