aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-parser.c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2005-06-15 16:55:47 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2005-06-15 16:55:47 +0100
commit46bdb9cffb6b1cd45bc8032f9b1d7e9e101ba7b0 (patch)
tree1872e122192fae90234ef8f17d82cd485d62d6cf /gcc/c-parser.c
parent38e19e4c73b8614fb094c5c36abdd7da47a26a50 (diff)
downloadgcc-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.c141
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