Commit 86785830 by Artjoms Sinkarovs Committed by Artjoms Sinkarovs

Fix bconstp-3.c failure in PR50607.

From-SVN: r179588
parent 57d1eadd
2011-10-06 Artjoms Sinkarovs <artyom.shinkaroff@gmail.com>
* c-tree.h (c_expr_t): New typedef for struct c_expr.
(C_EXPR_APPEND): New macro.
* c-parser.c (c_parser_get_builtin_args): Preserve
original_tree_code of c_expr structure. Fixes bconstp-3.c
failure of PR50607.
(c_parser_postfix_expression): Adjust to the new function.
2011-10-05 Bernd Schmidt <bernds@codesourcery.com> 2011-10-05 Bernd Schmidt <bernds@codesourcery.com>
* function.c (thread_prologue_and_epilogue_insns): Don't shrink-wrap * function.c (thread_prologue_and_epilogue_insns): Don't shrink-wrap
...@@ -5993,16 +5993,16 @@ c_parser_alignof_expression (c_parser *parser) ...@@ -5993,16 +5993,16 @@ c_parser_alignof_expression (c_parser *parser)
for the middle-end nodes like COMPLEX_EXPR, VEC_SHUFFLE_EXPR and for the middle-end nodes like COMPLEX_EXPR, VEC_SHUFFLE_EXPR and
others. The name of the builtin is passed using BNAME parameter. others. The name of the builtin is passed using BNAME parameter.
Function returns true if there were no errors while parsing and Function returns true if there were no errors while parsing and
stores the arguments in EXPR_LIST. List of original types can be stores the arguments in CEXPR_LIST. */
obtained by passing non NULL value to ORIG_TYPES. */
static bool static bool
c_parser_get_builtin_args (c_parser *parser, const char *bname, c_parser_get_builtin_args (c_parser *parser, const char *bname,
VEC(tree,gc) **expr_list, VEC(c_expr_t,gc) **ret_cexpr_list)
VEC(tree,gc) **orig_types)
{ {
location_t loc = c_parser_peek_token (parser)->location; location_t loc = c_parser_peek_token (parser)->location;
*expr_list = NULL; VEC (c_expr_t,gc) *cexpr_list;
c_expr_t expr;
*ret_cexpr_list = NULL;
if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
{ {
error_at (loc, "cannot take address of %qs", bname); error_at (loc, "cannot take address of %qs", bname);
...@@ -6016,15 +6016,21 @@ c_parser_get_builtin_args (c_parser *parser, const char *bname, ...@@ -6016,15 +6016,21 @@ c_parser_get_builtin_args (c_parser *parser, const char *bname,
c_parser_consume_token (parser); c_parser_consume_token (parser);
return true; return true;
} }
if (orig_types) expr = c_parser_expr_no_commas (parser, NULL);
*expr_list = c_parser_expr_list (parser, false, false, orig_types); cexpr_list = VEC_alloc (c_expr_t, gc, 1);
else C_EXPR_APPEND (cexpr_list, expr);
*expr_list = c_parser_expr_list (parser, false, false, NULL); while (c_parser_next_token_is (parser, CPP_COMMA))
{
c_parser_consume_token (parser);
expr = c_parser_expr_no_commas (parser, NULL);
C_EXPR_APPEND (cexpr_list, expr);
}
if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
return false; return false;
*ret_cexpr_list = cexpr_list;
return true; return true;
} }
...@@ -6378,52 +6384,41 @@ c_parser_postfix_expression (c_parser *parser) ...@@ -6378,52 +6384,41 @@ c_parser_postfix_expression (c_parser *parser)
break; break;
case RID_CHOOSE_EXPR: case RID_CHOOSE_EXPR:
{ {
VEC(tree,gc) *expr_list; VEC (c_expr_t, gc) *cexpr_list;
VEC(tree,gc) *orig_types; c_expr_t *e1_p, *e2_p, *e3_p;
tree e1value, e2value, e3value, c; tree c;
c_parser_consume_token (parser); c_parser_consume_token (parser);
if (!c_parser_get_builtin_args (parser, if (!c_parser_get_builtin_args (parser,
"__builtin_choose_expr", "__builtin_choose_expr",
&expr_list, &orig_types)) &cexpr_list))
{ {
expr.value = error_mark_node; expr.value = error_mark_node;
break; break;
} }
if (VEC_length (tree, expr_list) != 3) if (VEC_length (c_expr_t, cexpr_list) != 3)
{ {
error_at (loc, "wrong number of arguments to " error_at (loc, "wrong number of arguments to "
"%<__builtin_choose_expr%>"); "%<__builtin_choose_expr%>");
expr.value = error_mark_node; expr.value = error_mark_node;
break; break;
} }
e1value = VEC_index (tree, expr_list, 0); e1_p = VEC_index (c_expr_t, cexpr_list, 0);
e2value = VEC_index (tree, expr_list, 1); e2_p = VEC_index (c_expr_t, cexpr_list, 1);
e3value = VEC_index (tree, expr_list, 2); e3_p = VEC_index (c_expr_t, cexpr_list, 2);
c = e1value; c = e1_p->value;
mark_exp_read (e2value); mark_exp_read (e2_p->value);
mark_exp_read (e3value); mark_exp_read (e3_p->value);
if (TREE_CODE (c) != INTEGER_CST if (TREE_CODE (c) != INTEGER_CST
|| !INTEGRAL_TYPE_P (TREE_TYPE (c))) || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
error_at (loc, error_at (loc,
"first argument to %<__builtin_choose_expr%> not" "first argument to %<__builtin_choose_expr%> not"
" a constant"); " a constant");
constant_expression_warning (c); constant_expression_warning (c);
expr = integer_zerop (c) ? *e3_p : *e2_p;
if (integer_zerop (c))
{
expr.value = e3value;
expr.original_type = VEC_index (tree, orig_types, 2);
}
else
{
expr.value = e2value;
expr.original_type = VEC_index (tree, orig_types, 1);
}
break; break;
} }
case RID_TYPES_COMPATIBLE_P: case RID_TYPES_COMPATIBLE_P:
...@@ -6464,50 +6459,50 @@ c_parser_postfix_expression (c_parser *parser) ...@@ -6464,50 +6459,50 @@ c_parser_postfix_expression (c_parser *parser)
} }
break; break;
case RID_BUILTIN_COMPLEX: case RID_BUILTIN_COMPLEX:
{ {
VEC(tree,gc) *expr_list; VEC(c_expr_t, gc) *cexpr_list;
tree e1value, e2value; c_expr_t *e1_p, *e2_p;
c_parser_consume_token (parser); c_parser_consume_token (parser);
if (!c_parser_get_builtin_args (parser, if (!c_parser_get_builtin_args (parser,
"__builtin_complex", "__builtin_complex",
&expr_list, NULL)) &cexpr_list))
{ {
expr.value = error_mark_node; expr.value = error_mark_node;
break; break;
} }
if (VEC_length (tree, expr_list) != 2) if (VEC_length (c_expr_t, cexpr_list) != 2)
{ {
error_at (loc, "wrong number of arguments to " error_at (loc, "wrong number of arguments to "
"%<__builtin_complex%>"); "%<__builtin_complex%>");
expr.value = error_mark_node; expr.value = error_mark_node;
break; break;
} }
e1value = VEC_index (tree, expr_list, 0); e1_p = VEC_index (c_expr_t, cexpr_list, 0);
e2value = VEC_index (tree, expr_list, 1); e2_p = VEC_index (c_expr_t, cexpr_list, 1);
mark_exp_read (e1value); mark_exp_read (e1_p->value);
if (TREE_CODE (e1value) == EXCESS_PRECISION_EXPR) if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
e1value = convert (TREE_TYPE (e1value), e1_p->value = convert (TREE_TYPE (e1_p->value),
TREE_OPERAND (e1value, 0)); TREE_OPERAND (e1_p->value, 0));
mark_exp_read (e2value); mark_exp_read (e2_p->value);
if (TREE_CODE (e2value) == EXCESS_PRECISION_EXPR) if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
e2value = convert (TREE_TYPE (e2value), e2_p->value = convert (TREE_TYPE (e2_p->value),
TREE_OPERAND (e2value, 0)); TREE_OPERAND (e2_p->value, 0));
if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1value)) if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
|| DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1value)) || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
|| !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2value)) || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
|| DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2value))) || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
{ {
error_at (loc, "%<__builtin_complex%> operand " error_at (loc, "%<__builtin_complex%> operand "
"not of real binary floating-point type"); "not of real binary floating-point type");
expr.value = error_mark_node; expr.value = error_mark_node;
break; break;
} }
if (TYPE_MAIN_VARIANT (TREE_TYPE (e1value)) if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
!= TYPE_MAIN_VARIANT (TREE_TYPE (e2value))) != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
{ {
error_at (loc, error_at (loc,
"%<__builtin_complex%> operands of different types"); "%<__builtin_complex%> operands of different types");
...@@ -6518,34 +6513,37 @@ c_parser_postfix_expression (c_parser *parser) ...@@ -6518,34 +6513,37 @@ c_parser_postfix_expression (c_parser *parser)
pedwarn (loc, OPT_pedantic, pedwarn (loc, OPT_pedantic,
"ISO C90 does not support complex types"); "ISO C90 does not support complex types");
expr.value = build2 (COMPLEX_EXPR, expr.value = build2 (COMPLEX_EXPR,
build_complex_type (TYPE_MAIN_VARIANT build_complex_type
(TREE_TYPE (e1value))), (TYPE_MAIN_VARIANT
e1value, e2value); (TREE_TYPE (e1_p->value))),
e1_p->value, e2_p->value);
break; break;
} }
case RID_BUILTIN_SHUFFLE: case RID_BUILTIN_SHUFFLE:
{ {
VEC(tree,gc) *expr_list; VEC(c_expr_t,gc) *cexpr_list;
c_parser_consume_token (parser); c_parser_consume_token (parser);
if (!c_parser_get_builtin_args (parser, if (!c_parser_get_builtin_args (parser,
"__builtin_shuffle", "__builtin_shuffle",
&expr_list, NULL)) &cexpr_list))
{ {
expr.value = error_mark_node; expr.value = error_mark_node;
break; break;
} }
if (VEC_length (tree, expr_list) == 2) if (VEC_length (c_expr_t, cexpr_list) == 2)
expr.value = c_build_vec_shuffle_expr expr.value =
(loc, VEC_index (tree, expr_list, 0), c_build_vec_shuffle_expr
NULL_TREE, (loc, VEC_index (c_expr_t, cexpr_list, 0)->value,
VEC_index (tree, expr_list, 1)); NULL_TREE, VEC_index (c_expr_t, cexpr_list, 1)->value);
else if (VEC_length (tree, expr_list) == 3)
expr.value = c_build_vec_shuffle_expr else if (VEC_length (c_expr_t, cexpr_list) == 3)
(loc, VEC_index (tree, expr_list, 0), expr.value =
VEC_index (tree, expr_list, 1), c_build_vec_shuffle_expr
VEC_index (tree, expr_list, 2)); (loc, VEC_index (c_expr_t, cexpr_list, 0)->value,
VEC_index (c_expr_t, cexpr_list, 1)->value,
VEC_index (c_expr_t, cexpr_list, 2)->value);
else else
{ {
error_at (loc, "wrong number of arguments to " error_at (loc, "wrong number of arguments to "
......
...@@ -130,6 +130,22 @@ struct c_expr ...@@ -130,6 +130,22 @@ struct c_expr
tree original_type; tree original_type;
}; };
/* Type alias for struct c_expr. This allows to use the structure
inside the VEC types. */
typedef struct c_expr c_expr_t;
/* A varray of c_expr_t. */
DEF_VEC_O (c_expr_t);
DEF_VEC_ALLOC_O (c_expr_t, gc);
DEF_VEC_ALLOC_O (c_expr_t, heap);
/* Append a new c_expr_t element to V. */
#define C_EXPR_APPEND(V, ELEM) \
do { \
c_expr_t *__elem_p = VEC_safe_push (c_expr_t, gc, V, NULL); \
*__elem_p = (ELEM); \
} while (0)
/* A kind of type specifier. Note that this information is currently /* A kind of type specifier. Note that this information is currently
only used to distinguish tag definitions, tag references and typeof only used to distinguish tag definitions, tag references and typeof
uses. */ uses. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment