aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2009-10-08 01:32:51 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2009-10-08 01:32:51 +0100
commite5a942312327b2ef428e7d2d7fc97b5150c7c04a (patch)
treefd81fa90e7923181957eb30dcbb964a2a29c5e9d
parent1afab7bdc313af774b7bf5bf61872c6416e48ee9 (diff)
downloadgcc-e5a942312327b2ef428e7d2d7fc97b5150c7c04a.zip
gcc-e5a942312327b2ef428e7d2d7fc97b5150c7c04a.tar.gz
gcc-e5a942312327b2ef428e7d2d7fc97b5150c7c04a.tar.bz2
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
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/c-common.c41
-rw-r--r--gcc/c-common.h1
-rw-r--r--gcc/c-typeck.c27
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr41182-1.c6
6 files changed, 65 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d381c70..885532b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/c-common.c b/gcc/c-common.c
index bf57cb8..fb2a84e 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -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;
}
diff --git a/gcc/c-common.h b/gcc/c-common.h
index db4f910e..61d52c8 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -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);
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 4c55e58..e7425a7 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -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);
}
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fe14298..9b9b141 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr41182-1.c b/gcc/testsuite/gcc.c-torture/compile/pr41182-1.c
new file mode 100644
index 0000000..0171749
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr41182-1.c
@@ -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")))));
+}