re PR c/41182 (Revision 145254 caused ICE: tree check: expected integer_cst, have nop_expr in tree_int_cst_lt, at tree.c:5259)
PR c/41182 * c-common.c (c_fully_fold_internal): Strip nops from the result of recursive calls to c_fully_fold_internal. (c_wrap_maybe_const): New. (c_save_expr): Use c_wrap_maybe_const. * c-common.h (c_wrap_maybe_const): Declare. * c-typeck.c (build_conditional_expr, c_finish_stmt_expr, build_binary_op): Use c_wrap_maybe_const. testsuite: * gcc.c-torture/compile/pr41182-1.c: New. From-SVN: r152548
This commit is contained in:
parent
1afab7bdc3
commit
e5a9423123
@ -1,3 +1,14 @@
|
||||
2009-10-07 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
PR c/41182
|
||||
* c-common.c (c_fully_fold_internal): Strip nops from the result
|
||||
of recursive calls to c_fully_fold_internal.
|
||||
(c_wrap_maybe_const): New.
|
||||
(c_save_expr): Use c_wrap_maybe_const.
|
||||
* c-common.h (c_wrap_maybe_const): Declare.
|
||||
* c-typeck.c (build_conditional_expr, c_finish_stmt_expr,
|
||||
build_binary_op): Use c_wrap_maybe_const.
|
||||
|
||||
2009-10-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* real.c: Fix comment to reflect actual exponent size.
|
||||
|
@ -1219,6 +1219,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
|
||||
op2 = TREE_OPERAND (expr, 2);
|
||||
op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
|
||||
maybe_const_itself);
|
||||
STRIP_TYPE_NOPS (op0);
|
||||
if (op0 != orig_op0)
|
||||
ret = build3 (COMPONENT_REF, TREE_TYPE (expr), op0, op1, op2);
|
||||
if (ret != expr)
|
||||
@ -1235,8 +1236,10 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
|
||||
op3 = TREE_OPERAND (expr, 3);
|
||||
op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
|
||||
maybe_const_itself);
|
||||
STRIP_TYPE_NOPS (op0);
|
||||
op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
|
||||
maybe_const_itself);
|
||||
STRIP_TYPE_NOPS (op1);
|
||||
op1 = decl_constant_value_for_optimization (op1);
|
||||
if (op0 != orig_op0 || op1 != orig_op1)
|
||||
ret = build4 (ARRAY_REF, TREE_TYPE (expr), op0, op1, op2, op3);
|
||||
@ -1293,6 +1296,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
|
||||
orig_op1 = op1 = TREE_OPERAND (expr, 1);
|
||||
op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
|
||||
maybe_const_itself);
|
||||
STRIP_TYPE_NOPS (op0);
|
||||
if (code != MODIFY_EXPR
|
||||
&& code != PREDECREMENT_EXPR
|
||||
&& code != PREINCREMENT_EXPR
|
||||
@ -1304,6 +1308,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
|
||||
if (code != MODIFY_EXPR)
|
||||
op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
|
||||
maybe_const_itself);
|
||||
STRIP_TYPE_NOPS (op1);
|
||||
op1 = decl_constant_value_for_optimization (op1);
|
||||
if (op0 != orig_op0 || op1 != orig_op1 || in_init)
|
||||
ret = in_init
|
||||
@ -1333,6 +1338,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
|
||||
orig_op0 = op0 = TREE_OPERAND (expr, 0);
|
||||
op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
|
||||
maybe_const_itself);
|
||||
STRIP_TYPE_NOPS (op0);
|
||||
if (code != ADDR_EXPR && code != REALPART_EXPR && code != IMAGPART_EXPR)
|
||||
op0 = decl_constant_value_for_optimization (op0);
|
||||
if (op0 != orig_op0 || in_init)
|
||||
@ -1372,12 +1378,14 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
|
||||
orig_op0 = op0 = TREE_OPERAND (expr, 0);
|
||||
orig_op1 = op1 = TREE_OPERAND (expr, 1);
|
||||
op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self);
|
||||
STRIP_TYPE_NOPS (op0);
|
||||
|
||||
unused_p = (op0 == (code == TRUTH_ANDIF_EXPR
|
||||
? truthvalue_false_node
|
||||
: truthvalue_true_node));
|
||||
c_inhibit_evaluation_warnings += unused_p;
|
||||
op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self);
|
||||
STRIP_TYPE_NOPS (op1);
|
||||
c_inhibit_evaluation_warnings -= unused_p;
|
||||
|
||||
if (op0 != orig_op0 || op1 != orig_op1 || in_init)
|
||||
@ -1409,12 +1417,15 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
|
||||
orig_op2 = op2 = TREE_OPERAND (expr, 2);
|
||||
op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self);
|
||||
|
||||
STRIP_TYPE_NOPS (op0);
|
||||
c_inhibit_evaluation_warnings += (op0 == truthvalue_false_node);
|
||||
op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self);
|
||||
STRIP_TYPE_NOPS (op1);
|
||||
c_inhibit_evaluation_warnings -= (op0 == truthvalue_false_node);
|
||||
|
||||
c_inhibit_evaluation_warnings += (op0 == truthvalue_true_node);
|
||||
op2 = c_fully_fold_internal (op2, in_init, &op2_const, &op2_const_self);
|
||||
STRIP_TYPE_NOPS (op2);
|
||||
c_inhibit_evaluation_warnings -= (op0 == truthvalue_true_node);
|
||||
|
||||
if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
|
||||
@ -3790,6 +3801,31 @@ pointer_int_sum (location_t loc, enum tree_code resultcode,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wrap a C_MAYBE_CONST_EXPR around an expression that is fully folded
|
||||
and if NON_CONST is known not to be permitted in an evaluated part
|
||||
of a constant expression. */
|
||||
|
||||
tree
|
||||
c_wrap_maybe_const (tree expr, bool non_const)
|
||||
{
|
||||
bool nowarning = TREE_NO_WARNING (expr);
|
||||
location_t loc = EXPR_LOCATION (expr);
|
||||
|
||||
/* This should never be called for C++. */
|
||||
if (c_dialect_cxx ())
|
||||
gcc_unreachable ();
|
||||
|
||||
/* The result of folding may have a NOP_EXPR to set TREE_NO_WARNING. */
|
||||
STRIP_TYPE_NOPS (expr);
|
||||
expr = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (expr), NULL, expr);
|
||||
C_MAYBE_CONST_EXPR_NON_CONST (expr) = non_const;
|
||||
if (nowarning)
|
||||
TREE_NO_WARNING (expr) = 1;
|
||||
protected_set_expr_location (expr, loc);
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
/* Wrap a SAVE_EXPR around EXPR, if appropriate. Like save_expr, but
|
||||
for C folds the inside expression and wraps a C_MAYBE_CONST_EXPR
|
||||
around the SAVE_EXPR if needed so that c_fully_fold does not need
|
||||
@ -3804,10 +3840,7 @@ c_save_expr (tree expr)
|
||||
expr = c_fully_fold (expr, false, &maybe_const);
|
||||
expr = save_expr (expr);
|
||||
if (!maybe_const)
|
||||
{
|
||||
expr = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (expr), NULL, expr);
|
||||
C_MAYBE_CONST_EXPR_NON_CONST (expr) = 1;
|
||||
}
|
||||
expr = c_wrap_maybe_const (expr, true);
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
@ -792,6 +792,7 @@ extern tree c_build_bitfield_integer_type (unsigned HOST_WIDE_INT, int);
|
||||
extern bool decl_with_nonnull_addr_p (const_tree);
|
||||
extern tree c_fully_fold (tree, bool, bool *);
|
||||
extern tree decl_constant_value_for_optimization (tree);
|
||||
extern tree c_wrap_maybe_const (tree, bool);
|
||||
extern tree c_save_expr (tree);
|
||||
extern tree c_common_truthvalue_conversion (location_t, tree);
|
||||
extern void c_apply_type_quals_to_decl (int, tree);
|
||||
|
@ -3940,17 +3940,9 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
|
||||
"conditional expression"));
|
||||
}
|
||||
if (!op1_maybe_const || TREE_CODE (op1) != INTEGER_CST)
|
||||
{
|
||||
op1 = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (op1),
|
||||
NULL, op1);
|
||||
C_MAYBE_CONST_EXPR_NON_CONST (op1) = !op1_maybe_const;
|
||||
}
|
||||
op1 = c_wrap_maybe_const (op1, !op1_maybe_const);
|
||||
if (!op2_maybe_const || TREE_CODE (op2) != INTEGER_CST)
|
||||
{
|
||||
op2 = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (op2),
|
||||
NULL, op2);
|
||||
C_MAYBE_CONST_EXPR_NON_CONST (op2) = !op2_maybe_const;
|
||||
}
|
||||
op2 = c_wrap_maybe_const (op2, !op2_maybe_const);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8669,8 +8661,7 @@ c_finish_stmt_expr (location_t loc, tree body)
|
||||
{
|
||||
/* Even if this looks constant, do not allow it in a constant
|
||||
expression. */
|
||||
last = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (last), NULL_TREE, last);
|
||||
C_MAYBE_CONST_EXPR_NON_CONST (last) = 1;
|
||||
last = c_wrap_maybe_const (last, true);
|
||||
/* Do not warn if the return value of a statement expression is
|
||||
unused. */
|
||||
TREE_NO_WARNING (last) = 1;
|
||||
@ -9545,17 +9536,9 @@ build_binary_op (location_t location, enum tree_code code,
|
||||
if (!in_late_binary_op)
|
||||
{
|
||||
if (!op0_maybe_const || TREE_CODE (op0) != INTEGER_CST)
|
||||
{
|
||||
op0 = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (op0),
|
||||
NULL, op0);
|
||||
C_MAYBE_CONST_EXPR_NON_CONST (op0) = !op0_maybe_const;
|
||||
}
|
||||
op0 = c_wrap_maybe_const (op0, !op0_maybe_const);
|
||||
if (!op1_maybe_const || TREE_CODE (op1) != INTEGER_CST)
|
||||
{
|
||||
op1 = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (op1),
|
||||
NULL, op1);
|
||||
C_MAYBE_CONST_EXPR_NON_CONST (op1) = !op1_maybe_const;
|
||||
}
|
||||
op1 = c_wrap_maybe_const (op1, !op1_maybe_const);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,8 @@
|
||||
2009-10-07 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
PR c/41182
|
||||
* gcc.c-torture/compile/pr41182-1.c: New.
|
||||
|
||||
2009-10-07 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/cpp0x/variadic95.C: New.
|
||||
|
6
gcc/testsuite/gcc.c-torture/compile/pr41182-1.c
Normal file
6
gcc/testsuite/gcc.c-torture/compile/pr41182-1.c
Normal file
@ -0,0 +1,6 @@
|
||||
typedef long unsigned int size_t;
|
||||
int _lae_process_opts(char *pr, char *pe)
|
||||
{
|
||||
return (strlen ("on") < ((size_t) ((pe-&pr[2])>(strlen("on"))
|
||||
? (pe-&pr[2]) : (strlen("on")))));
|
||||
}
|
Loading…
Reference in New Issue
Block a user