This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Avoid infinite recursion in fold_ternary/fold_cond_expr_with_comparison (PR middle-end/40692)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 9 Jul 2009 08:49:53 +0200
- Subject: [PATCH] Avoid infinite recursion in fold_ternary/fold_cond_expr_with_comparison (PR middle-end/40692)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
The recent r149060 checkin where build3 sets TREE_READONLY on COND_EXPRs
with all arguments read-only or CONSTANT_CLASS_P causes ICE when building
Linux kernel. The problem is that the C FE doesn't fully fold stuff and
build_conditional_expr when called with those now newly TREE_READONLY
COND_EXPRs will use a TREE_READONLY result_type, rather than the previous
non-readonly:
/* Merge const and volatile flags of the incoming types. */
result_type
= build_type_variant (result_type,
TREE_READONLY (op1) || TREE_READONLY (op2),
TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE
(op2));
This means fold_ternary (COND_EXPR, <long int readonly>, <eq 0 0>, 0, 2)
is called and fold_cond_expr_with_comparison it calls isn't prepared for
both operands of the comparison being integers, so it replaces
arg1 (0) with arg01 (0) and attempts to fold it again.
The following patch fixes it by not replacing an integer with an integer.
Ok for trunk if bootstrap/regtest passes?
2009-07-09 Jakub Jelinek <jakub@redhat.com>
PR middle-end/40692
* fold-const.c (fold_cond_expr_with_comparison): Don't replace
arg1 with arg01 if arg1 is already INTEGER_CST.
* gcc.c-torture/compile/pr40692.c: New test.
--- gcc/fold-const.c.jj 2009-07-07 12:39:07.000000000 +0200
+++ gcc/fold-const.c 2009-07-09 08:10:38.000000000 +0200
@@ -5303,6 +5303,8 @@ fold_cond_expr_with_comparison (tree typ
switch (comp_code)
{
case EQ_EXPR:
+ if (TREE_CODE (arg1) == INTEGER_CST)
+ break;
/* We can replace A with C1 in this case. */
arg1 = fold_convert (type, arg01);
return fold_build3 (COND_EXPR, type, arg0, arg1, arg2);
--- gcc/testsuite/gcc.c-torture/compile/pr40692.c.jj 2009-07-09 08:19:31.000000000 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr40692.c 2009-07-09 08:18:42.000000000 +0200
@@ -0,0 +1,15 @@
+/* PR middle-end/40692 */
+
+#define M1(x) (((x) & 0x00000002) ? 0x2 : ((x) & 0x1))
+#define M2(x) (((x) & 0x0000000c) ? M1 ((x) >> 2) << 2 : M1 (x))
+#define M3(x) (((x) & 0x000000f0) ? M2 ((x) >> 4) << 4 : M2 (x))
+#define M4(x) (((x) & 0x0000ff00) ? M3 ((x) >> 8) << 8 : M3 (x))
+#define M5(x) (((x) & 0xffff0000) ? M4 ((x) >> 16) << 16 : M4 (x))
+
+struct A { char e; char f; };
+
+long
+foo (void)
+{
+ return M5 (4096UL - (long) &((struct A *) 0)->f);
+}
Jakub