c-tree.h (default_function_array_conversion): Take and return struct c_expr.
* c-tree.h (default_function_array_conversion): Take and return struct c_expr. * c-typeck.c (default_function_array_conversion): Split into array_to_pointer_conversion and function_to_pointer_conversion. Take and return struct c_expr. (array_to_pointer_conversion): Do not handle type qualifiers or COMPOUND_EXPRs specially. (build_function_call): Call function_to_pointer_conversion for function designators. (build_unary_op): Call array_to_pointer_conversion, not default_function_array_conversion. (digest_init, output_init_element): Likewise. * c-parser.c: All callers of default_function_array_conversion changed. From-SVN: r101440
This commit is contained in:
parent
a81408c939
commit
f2a71bbcb2
4 changed files with 178 additions and 141 deletions
|
@ -1,3 +1,20 @@
|
|||
2005-06-29 Joseph S. Myers <joseph@codesourcery.com>
|
||||
|
||||
* c-tree.h (default_function_array_conversion): Take and return
|
||||
struct c_expr.
|
||||
* c-typeck.c (default_function_array_conversion): Split into
|
||||
array_to_pointer_conversion and function_to_pointer_conversion.
|
||||
Take and return struct c_expr.
|
||||
(array_to_pointer_conversion): Do not handle type qualifiers or
|
||||
COMPOUND_EXPRs specially.
|
||||
(build_function_call): Call function_to_pointer_conversion for
|
||||
function designators.
|
||||
(build_unary_op): Call array_to_pointer_conversion, not
|
||||
default_function_array_conversion.
|
||||
(digest_init, output_init_element): Likewise.
|
||||
* c-parser.c: All callers of default_function_array_conversion
|
||||
changed.
|
||||
|
||||
2005-06-29 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* config/darwin.c (machopic_select_section): constant ObjC string
|
||||
|
|
|
@ -2880,7 +2880,7 @@ c_parser_initializer (c_parser *parser)
|
|||
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);
|
||||
ret = default_function_array_conversion (ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -3036,11 +3036,11 @@ c_parser_initelt (c_parser *parser)
|
|||
rec = first;
|
||||
while (c_parser_next_token_is (parser, CPP_COMMA))
|
||||
{
|
||||
tree next;
|
||||
struct c_expr next;
|
||||
c_parser_consume_token (parser);
|
||||
next = c_parser_expr_no_commas (parser, NULL).value;
|
||||
next = c_parser_expr_no_commas (parser, NULL);
|
||||
next = default_function_array_conversion (next);
|
||||
rec = build_compound_expr (rec, next);
|
||||
rec = build_compound_expr (rec, next.value);
|
||||
}
|
||||
parse_message_args:
|
||||
/* Now parse the objc-message-args. */
|
||||
|
@ -3130,7 +3130,7 @@ c_parser_initval (c_parser *parser, struct c_expr *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);
|
||||
init = default_function_array_conversion (init);
|
||||
}
|
||||
process_init_element (init);
|
||||
}
|
||||
|
@ -3990,7 +3990,8 @@ c_parser_asm_operands (c_parser *parser, bool convert_p)
|
|||
tree list = NULL_TREE;
|
||||
while (true)
|
||||
{
|
||||
tree name, str, expr;
|
||||
tree name, str;
|
||||
struct c_expr expr;
|
||||
if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
|
||||
{
|
||||
c_parser_consume_token (parser);
|
||||
|
@ -4021,7 +4022,7 @@ c_parser_asm_operands (c_parser *parser, bool convert_p)
|
|||
c_lex_string_translate = 0;
|
||||
return NULL_TREE;
|
||||
}
|
||||
expr = c_parser_expression (parser).value;
|
||||
expr = c_parser_expression (parser);
|
||||
if (convert_p)
|
||||
expr = default_function_array_conversion (expr);
|
||||
c_lex_string_translate = 0;
|
||||
|
@ -4031,7 +4032,7 @@ c_parser_asm_operands (c_parser *parser, bool convert_p)
|
|||
return NULL_TREE;
|
||||
}
|
||||
list = chainon (list, build_tree_list (build_tree_list (name, str),
|
||||
expr));
|
||||
expr.value));
|
||||
if (c_parser_next_token_is (parser, CPP_COMMA))
|
||||
c_parser_consume_token (parser);
|
||||
else
|
||||
|
@ -4129,7 +4130,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);
|
||||
rhs = default_function_array_conversion (rhs);
|
||||
ret.value = build_modify_expr (lhs.value, code, rhs.value);
|
||||
if (code == NOP_EXPR)
|
||||
ret.original_code = MODIFY_EXPR;
|
||||
|
@ -4163,7 +4164,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);
|
||||
cond = default_function_array_conversion (cond);
|
||||
c_parser_consume_token (parser);
|
||||
if (c_parser_next_token_is (parser, CPP_COLON))
|
||||
{
|
||||
|
@ -4192,7 +4193,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);
|
||||
exp2 = default_function_array_conversion (exp2);
|
||||
skip_evaluation -= cond.value == truthvalue_true_node;
|
||||
ret.value = build_conditional_expr (cond.value, exp1.value, exp2.value);
|
||||
ret.original_code = ERROR_MARK;
|
||||
|
@ -4316,10 +4317,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 \
|
||||
= default_function_array_conversion (stack[sp - 1].expr); \
|
||||
stack[sp].expr \
|
||||
= default_function_array_conversion (stack[sp].expr); \
|
||||
stack[sp - 1].expr = parser_build_binary_op (stack[sp].op, \
|
||||
stack[sp - 1].expr, \
|
||||
stack[sp].expr); \
|
||||
|
@ -4420,15 +4421,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
|
||||
= default_function_array_conversion (stack[sp].expr);
|
||||
stack[sp].expr.value = c_objc_common_truthvalue_conversion
|
||||
(default_conversion (stack[sp].expr.value));
|
||||
skip_evaluation += stack[sp].expr.value == truthvalue_false_node;
|
||||
break;
|
||||
case TRUTH_ORIF_EXPR:
|
||||
stack[sp].expr.value
|
||||
= default_function_array_conversion (stack[sp].expr.value);
|
||||
stack[sp].expr
|
||||
= default_function_array_conversion (stack[sp].expr);
|
||||
stack[sp].expr.value = c_objc_common_truthvalue_conversion
|
||||
(default_conversion (stack[sp].expr.value));
|
||||
skip_evaluation += stack[sp].expr.value == truthvalue_true_node;
|
||||
|
@ -4472,7 +4473,7 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after)
|
|||
{
|
||||
struct c_type_name *type_name;
|
||||
struct c_expr ret;
|
||||
tree expr;
|
||||
struct c_expr expr;
|
||||
c_parser_consume_token (parser);
|
||||
type_name = c_parser_type_name (parser);
|
||||
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
|
||||
|
@ -4485,9 +4486,9 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after)
|
|||
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
|
||||
return c_parser_postfix_expression_after_paren_type (parser,
|
||||
type_name);
|
||||
expr = c_parser_cast_expression (parser, NULL).value;
|
||||
expr = c_parser_cast_expression (parser, NULL);
|
||||
expr = default_function_array_conversion (expr);
|
||||
ret.value = c_cast_expr (type_name, expr);
|
||||
ret.value = c_cast_expr (type_name, expr.value);
|
||||
ret.original_code = ERROR_MARK;
|
||||
return ret;
|
||||
}
|
||||
|
@ -4532,12 +4533,12 @@ c_parser_unary_expression (c_parser *parser)
|
|||
case CPP_PLUS_PLUS:
|
||||
c_parser_consume_token (parser);
|
||||
op = c_parser_cast_expression (parser, NULL);
|
||||
op.value = default_function_array_conversion (op.value);
|
||||
op = default_function_array_conversion (op);
|
||||
return parser_build_unary_op (PREINCREMENT_EXPR, op);
|
||||
case CPP_MINUS_MINUS:
|
||||
c_parser_consume_token (parser);
|
||||
op = c_parser_cast_expression (parser, NULL);
|
||||
op.value = default_function_array_conversion (op.value);
|
||||
op = default_function_array_conversion (op);
|
||||
return parser_build_unary_op (PREDECREMENT_EXPR, op);
|
||||
case CPP_AND:
|
||||
c_parser_consume_token (parser);
|
||||
|
@ -4546,7 +4547,7 @@ c_parser_unary_expression (c_parser *parser)
|
|||
case CPP_MULT:
|
||||
c_parser_consume_token (parser);
|
||||
op = c_parser_cast_expression (parser, NULL);
|
||||
op.value = default_function_array_conversion (op.value);
|
||||
op = default_function_array_conversion (op);
|
||||
ret.value = build_indirect_ref (op.value, "unary *");
|
||||
ret.original_code = ERROR_MARK;
|
||||
return ret;
|
||||
|
@ -4556,22 +4557,22 @@ c_parser_unary_expression (c_parser *parser)
|
|||
warning (OPT_Wtraditional,
|
||||
"traditional C rejects the unary plus operator");
|
||||
op = c_parser_cast_expression (parser, NULL);
|
||||
op.value = default_function_array_conversion (op.value);
|
||||
op = default_function_array_conversion (op);
|
||||
return parser_build_unary_op (CONVERT_EXPR, op);
|
||||
case CPP_MINUS:
|
||||
c_parser_consume_token (parser);
|
||||
op = c_parser_cast_expression (parser, NULL);
|
||||
op.value = default_function_array_conversion (op.value);
|
||||
op = default_function_array_conversion (op);
|
||||
return parser_build_unary_op (NEGATE_EXPR, op);
|
||||
case CPP_COMPL:
|
||||
c_parser_consume_token (parser);
|
||||
op = c_parser_cast_expression (parser, NULL);
|
||||
op.value = default_function_array_conversion (op.value);
|
||||
op = default_function_array_conversion (op);
|
||||
return parser_build_unary_op (BIT_NOT_EXPR, op);
|
||||
case CPP_NOT:
|
||||
c_parser_consume_token (parser);
|
||||
op = c_parser_cast_expression (parser, NULL);
|
||||
op.value = default_function_array_conversion (op.value);
|
||||
op = default_function_array_conversion (op);
|
||||
return parser_build_unary_op (TRUTH_NOT_EXPR, op);
|
||||
case CPP_AND_AND:
|
||||
/* Refer to the address of a label as a pointer. */
|
||||
|
@ -4605,12 +4606,12 @@ c_parser_unary_expression (c_parser *parser)
|
|||
case RID_REALPART:
|
||||
c_parser_consume_token (parser);
|
||||
op = c_parser_cast_expression (parser, NULL);
|
||||
op.value = default_function_array_conversion (op.value);
|
||||
op = default_function_array_conversion (op);
|
||||
return parser_build_unary_op (REALPART_EXPR, op);
|
||||
case RID_IMAGPART:
|
||||
c_parser_consume_token (parser);
|
||||
op = c_parser_cast_expression (parser, NULL);
|
||||
op.value = default_function_array_conversion (op.value);
|
||||
op = default_function_array_conversion (op);
|
||||
return parser_build_unary_op (IMAGPART_EXPR, op);
|
||||
default:
|
||||
return c_parser_postfix_expression (parser);
|
||||
|
@ -5250,7 +5251,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);
|
||||
expr = default_function_array_conversion (expr);
|
||||
if (c_parser_next_token_is (parser, CPP_NAME))
|
||||
ident = c_parser_peek_token (parser)->value;
|
||||
else
|
||||
|
@ -5267,7 +5268,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);
|
||||
expr = default_function_array_conversion (expr);
|
||||
if (c_parser_next_token_is (parser, CPP_NAME))
|
||||
ident = c_parser_peek_token (parser)->value;
|
||||
else
|
||||
|
@ -5285,14 +5286,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 = default_function_array_conversion (expr);
|
||||
expr.value = build_unary_op (POSTINCREMENT_EXPR, expr.value, 0);
|
||||
expr.original_code = ERROR_MARK;
|
||||
break;
|
||||
case CPP_MINUS_MINUS:
|
||||
/* Postdecrement. */
|
||||
c_parser_consume_token (parser);
|
||||
expr.value = default_function_array_conversion (expr.value);
|
||||
expr = default_function_array_conversion (expr);
|
||||
expr.value = build_unary_op (POSTDECREMENT_EXPR, expr.value, 0);
|
||||
expr.original_code = ERROR_MARK;
|
||||
break;
|
||||
|
@ -5319,7 +5320,7 @@ 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);
|
||||
next = default_function_array_conversion (next);
|
||||
expr.value = build_compound_expr (expr.value, next.value);
|
||||
expr.original_code = COMPOUND_EXPR;
|
||||
}
|
||||
|
@ -5334,7 +5335,7 @@ c_parser_expression_conv (c_parser *parser)
|
|||
{
|
||||
struct c_expr expr;
|
||||
expr = c_parser_expression (parser);
|
||||
expr.value = default_function_array_conversion (expr.value);
|
||||
expr = default_function_array_conversion (expr);
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
@ -5353,14 +5354,14 @@ c_parser_expr_list (c_parser *parser, bool convert_p)
|
|||
tree ret, cur;
|
||||
expr = c_parser_expr_no_commas (parser, NULL);
|
||||
if (convert_p)
|
||||
expr.value = default_function_array_conversion (expr.value);
|
||||
expr = default_function_array_conversion (expr);
|
||||
ret = cur = build_tree_list (NULL_TREE, expr.value);
|
||||
while (c_parser_next_token_is (parser, CPP_COMMA))
|
||||
{
|
||||
c_parser_consume_token (parser);
|
||||
expr = c_parser_expr_no_commas (parser, NULL);
|
||||
if (convert_p)
|
||||
expr.value = default_function_array_conversion (expr.value);
|
||||
expr = default_function_array_conversion (expr);
|
||||
cur = TREE_CHAIN (cur) = build_tree_list (NULL_TREE, expr.value);
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -523,7 +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 struct c_expr default_function_array_conversion (struct c_expr);
|
||||
extern tree composite_type (tree, tree);
|
||||
extern tree build_component_ref (tree, tree);
|
||||
extern tree build_indirect_ref (tree, const char *);
|
||||
|
|
221
gcc/c-typeck.c
221
gcc/c-typeck.c
|
@ -1259,103 +1259,116 @@ decl_constant_value_for_broken_optimization (tree decl)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Convert the array expression EXP to a pointer. */
|
||||
static tree
|
||||
array_to_pointer_conversion (tree exp)
|
||||
{
|
||||
tree orig_exp = exp;
|
||||
tree type = TREE_TYPE (exp);
|
||||
tree adr;
|
||||
tree restype = TREE_TYPE (type);
|
||||
tree ptrtype;
|
||||
|
||||
gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
|
||||
|
||||
STRIP_TYPE_NOPS (exp);
|
||||
|
||||
if (TREE_NO_WARNING (orig_exp))
|
||||
TREE_NO_WARNING (exp) = 1;
|
||||
|
||||
ptrtype = build_pointer_type (restype);
|
||||
|
||||
if (TREE_CODE (exp) == INDIRECT_REF)
|
||||
return convert (ptrtype, TREE_OPERAND (exp, 0));
|
||||
|
||||
if (TREE_CODE (exp) == VAR_DECL)
|
||||
{
|
||||
/* We are making an ADDR_EXPR of ptrtype. This is a valid
|
||||
ADDR_EXPR because it's the best way of representing what
|
||||
happens in C when we take the address of an array and place
|
||||
it in a pointer to the element type. */
|
||||
adr = build1 (ADDR_EXPR, ptrtype, exp);
|
||||
if (!c_mark_addressable (exp))
|
||||
return error_mark_node;
|
||||
TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */
|
||||
return adr;
|
||||
}
|
||||
|
||||
/* This way is better for a COMPONENT_REF since it can
|
||||
simplify the offset for a component. */
|
||||
adr = build_unary_op (ADDR_EXPR, exp, 1);
|
||||
return convert (ptrtype, adr);
|
||||
}
|
||||
|
||||
/* Convert the function expression EXP to a pointer. */
|
||||
static tree
|
||||
function_to_pointer_conversion (tree exp)
|
||||
{
|
||||
tree orig_exp = exp;
|
||||
|
||||
gcc_assert (TREE_CODE (TREE_TYPE (exp)) == FUNCTION_TYPE);
|
||||
|
||||
STRIP_TYPE_NOPS (exp);
|
||||
|
||||
if (TREE_NO_WARNING (orig_exp))
|
||||
TREE_NO_WARNING (exp) = 1;
|
||||
|
||||
return build_unary_op (ADDR_EXPR, exp, 0);
|
||||
}
|
||||
|
||||
/* Perform the default conversion of arrays and functions to pointers.
|
||||
Return the result of converting EXP. For any other expression, just
|
||||
return EXP after removing NOPs. */
|
||||
|
||||
tree
|
||||
default_function_array_conversion (tree exp)
|
||||
struct c_expr
|
||||
default_function_array_conversion (struct c_expr exp)
|
||||
{
|
||||
tree orig_exp;
|
||||
tree type = TREE_TYPE (exp);
|
||||
tree orig_exp = exp.value;
|
||||
tree type = TREE_TYPE (exp.value);
|
||||
enum tree_code code = TREE_CODE (type);
|
||||
int not_lvalue = 0;
|
||||
|
||||
/* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as
|
||||
an lvalue.
|
||||
|
||||
Do not use STRIP_NOPS here! It will remove conversions from pointer
|
||||
to integer and cause infinite recursion. */
|
||||
orig_exp = exp;
|
||||
while (TREE_CODE (exp) == NON_LVALUE_EXPR
|
||||
|| (TREE_CODE (exp) == NOP_EXPR
|
||||
&& TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp)))
|
||||
switch (code)
|
||||
{
|
||||
if (TREE_CODE (exp) == NON_LVALUE_EXPR)
|
||||
not_lvalue = 1;
|
||||
exp = TREE_OPERAND (exp, 0);
|
||||
case ARRAY_TYPE:
|
||||
{
|
||||
bool not_lvalue = false;
|
||||
bool lvalue_array_p;
|
||||
|
||||
while ((TREE_CODE (exp.value) == NON_LVALUE_EXPR
|
||||
|| TREE_CODE (exp.value) == NOP_EXPR)
|
||||
&& TREE_TYPE (TREE_OPERAND (exp.value, 0)) == type)
|
||||
{
|
||||
if (TREE_CODE (exp.value) == NON_LVALUE_EXPR)
|
||||
not_lvalue = true;
|
||||
exp.value = TREE_OPERAND (exp.value, 0);
|
||||
}
|
||||
|
||||
if (TREE_NO_WARNING (orig_exp))
|
||||
TREE_NO_WARNING (exp.value) = 1;
|
||||
|
||||
lvalue_array_p = !not_lvalue && lvalue_p (exp.value);
|
||||
if (!flag_isoc99 && !lvalue_array_p)
|
||||
{
|
||||
/* Before C99, non-lvalue arrays do not decay to pointers.
|
||||
Normally, using such an array would be invalid; but it can
|
||||
be used correctly inside sizeof or as a statement expression.
|
||||
Thus, do not give an error here; an error will result later. */
|
||||
return exp;
|
||||
}
|
||||
|
||||
exp.value = array_to_pointer_conversion (exp.value);
|
||||
}
|
||||
break;
|
||||
case FUNCTION_TYPE:
|
||||
exp.value = function_to_pointer_conversion (exp.value);
|
||||
break;
|
||||
default:
|
||||
STRIP_TYPE_NOPS (exp.value);
|
||||
if (TREE_NO_WARNING (orig_exp))
|
||||
TREE_NO_WARNING (exp.value) = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (TREE_NO_WARNING (orig_exp))
|
||||
TREE_NO_WARNING (exp) = 1;
|
||||
|
||||
if (code == FUNCTION_TYPE)
|
||||
{
|
||||
return build_unary_op (ADDR_EXPR, exp, 0);
|
||||
}
|
||||
if (code == ARRAY_TYPE)
|
||||
{
|
||||
tree adr;
|
||||
tree restype = TREE_TYPE (type);
|
||||
tree ptrtype;
|
||||
int constp = 0;
|
||||
int volatilep = 0;
|
||||
int lvalue_array_p;
|
||||
|
||||
if (REFERENCE_CLASS_P (exp) || DECL_P (exp))
|
||||
{
|
||||
constp = TREE_READONLY (exp);
|
||||
volatilep = TREE_THIS_VOLATILE (exp);
|
||||
}
|
||||
|
||||
if (TYPE_QUALS (type) || constp || volatilep)
|
||||
restype
|
||||
= c_build_qualified_type (restype,
|
||||
TYPE_QUALS (type)
|
||||
| (constp * TYPE_QUAL_CONST)
|
||||
| (volatilep * TYPE_QUAL_VOLATILE));
|
||||
|
||||
if (TREE_CODE (exp) == INDIRECT_REF)
|
||||
return convert (build_pointer_type (restype),
|
||||
TREE_OPERAND (exp, 0));
|
||||
|
||||
if (TREE_CODE (exp) == COMPOUND_EXPR)
|
||||
{
|
||||
tree op1 = default_conversion (TREE_OPERAND (exp, 1));
|
||||
return build2 (COMPOUND_EXPR, TREE_TYPE (op1),
|
||||
TREE_OPERAND (exp, 0), op1);
|
||||
}
|
||||
|
||||
lvalue_array_p = !not_lvalue && lvalue_p (exp);
|
||||
if (!flag_isoc99 && !lvalue_array_p)
|
||||
{
|
||||
/* Before C99, non-lvalue arrays do not decay to pointers.
|
||||
Normally, using such an array would be invalid; but it can
|
||||
be used correctly inside sizeof or as a statement expression.
|
||||
Thus, do not give an error here; an error will result later. */
|
||||
return exp;
|
||||
}
|
||||
|
||||
ptrtype = build_pointer_type (restype);
|
||||
|
||||
if (TREE_CODE (exp) == VAR_DECL)
|
||||
{
|
||||
/* We are making an ADDR_EXPR of ptrtype. This is a valid
|
||||
ADDR_EXPR because it's the best way of representing what
|
||||
happens in C when we take the address of an array and place
|
||||
it in a pointer to the element type. */
|
||||
adr = build1 (ADDR_EXPR, ptrtype, exp);
|
||||
if (!c_mark_addressable (exp))
|
||||
return error_mark_node;
|
||||
TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */
|
||||
return adr;
|
||||
}
|
||||
/* This way is better for a COMPONENT_REF since it can
|
||||
simplify the offset for a component. */
|
||||
adr = build_unary_op (ADDR_EXPR, exp, 1);
|
||||
return convert (ptrtype, adr);
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
|
||||
|
@ -1992,7 +2005,8 @@ build_function_call (tree function, tree params)
|
|||
name = DECL_NAME (function);
|
||||
fundecl = function;
|
||||
}
|
||||
function = default_function_array_conversion (function);
|
||||
if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE)
|
||||
function = function_to_pointer_conversion (function);
|
||||
|
||||
/* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
|
||||
expressions, like those used for ObjC messenger dispatches. */
|
||||
|
@ -2730,11 +2744,13 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
|
|||
/* For &x[y], return x+y */
|
||||
if (TREE_CODE (arg) == ARRAY_REF)
|
||||
{
|
||||
if (!c_mark_addressable (TREE_OPERAND (arg, 0)))
|
||||
tree op0 = TREE_OPERAND (arg, 0);
|
||||
if (!c_mark_addressable (op0))
|
||||
return error_mark_node;
|
||||
return build_binary_op (PLUS_EXPR,
|
||||
default_function_array_conversion
|
||||
(TREE_OPERAND (arg, 0)),
|
||||
(TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE
|
||||
? array_to_pointer_conversion (op0)
|
||||
: op0),
|
||||
TREE_OPERAND (arg, 1), 1);
|
||||
}
|
||||
|
||||
|
@ -4367,16 +4383,18 @@ digest_init (tree type, tree init, bool strict_string, int require_constant)
|
|||
{
|
||||
if (code == POINTER_TYPE)
|
||||
{
|
||||
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)
|
||||
{
|
||||
error_init ("invalid use of non-lvalue array");
|
||||
return error_mark_node;
|
||||
if (TREE_CODE (inside_init) == STRING_CST
|
||||
|| TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
|
||||
inside_init = array_to_pointer_conversion (inside_init);
|
||||
else
|
||||
{
|
||||
error_init ("invalid use of non-lvalue array");
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (code == VECTOR_TYPE)
|
||||
/* Although the types are compatible, we may require a
|
||||
|
@ -4436,9 +4454,10 @@ digest_init (tree type, tree init, bool strict_string, int require_constant)
|
|||
|| code == ENUMERAL_TYPE || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
|
||||
|| code == VECTOR_TYPE)
|
||||
{
|
||||
if (TREE_CODE (init) == STRING_CST
|
||||
|| TREE_CODE (init) == COMPOUND_LITERAL_EXPR)
|
||||
init = default_function_array_conversion (init);
|
||||
if (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE
|
||||
&& (TREE_CODE (init) == STRING_CST
|
||||
|| TREE_CODE (init) == COMPOUND_LITERAL_EXPR))
|
||||
init = array_to_pointer_conversion (init);
|
||||
inside_init
|
||||
= convert_for_assignment (type, init, ic_init,
|
||||
NULL_TREE, NULL_TREE, 0);
|
||||
|
@ -5796,7 +5815,7 @@ output_init_element (tree value, bool strict_string, tree type, tree field,
|
|||
&& INTEGRAL_TYPE_P (TREE_TYPE (type)))
|
||||
&& !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)),
|
||||
TYPE_MAIN_VARIANT (type)))
|
||||
value = default_function_array_conversion (value);
|
||||
value = array_to_pointer_conversion (value);
|
||||
|
||||
if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR
|
||||
&& require_constant_value && !flag_isoc99 && pending)
|
||||
|
|
Loading…
Add table
Reference in a new issue