This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Avoid infinite recursion in fold_ternary/fold_cond_expr_with_comparison (PR middle-end/40692)


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]