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:
Joseph Myers 2009-10-08 01:32:51 +01:00 committed by Joseph Myers
parent 1afab7bdc3
commit e5a9423123
6 changed files with 65 additions and 26 deletions

View File

@ -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.

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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.

View 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")))));
}