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
This commit is contained in:
parent
38e19e4c73
commit
46bdb9cffb
8 changed files with 205 additions and 115 deletions
|
@ -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
|
||||
|
|
141
gcc/c-parser.c
141
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
|
||||
|
|
|
@ -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 *);
|
||||
|
|
102
gcc/c-typeck.c
102
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" } */
|
||||
|
|
Loading…
Add table
Reference in a new issue