The attached patch avoids infinite recursion when traversing phi
nodes in maybe_warn_alloc_args_overflow by using a bitmap to keep
track of those already visited and breaking out.

Thanks
Martin
PR tree-optimization/78775 - ICE in maybe_warn_alloc_args_overflow

gcc/ChangeLog:

	PR tree-optimization/78775
	* calls.c (operand_signed_p): Add overload and avoid getting into
	infinite recursion when traversing phi nodes.

gcc/testsuite/ChangeLog:

	PR tree-optimization/78775
	* gcc.dg/pr78775.c: New test.

Index: gcc/calls.c
===================================================================
--- gcc/calls.c	(revision 243581)
+++ gcc/calls.c	(working copy)
@@ -1247,10 +1247,12 @@ alloc_max_size (void)
 }
 
 /* Return true if the type of OP is signed, looking through any casts
-   to an unsigned type.  */
+   to an unsigned type.  VISITED is expected to be initially null and
+   is used internally by recursive calls of the function.  Caller
+   must free *VISITED if non-null after the function returns.  */
 
 static bool
-operand_signed_p (tree op)
+operand_signed_p (tree op, bitmap *visited)
 {
   if (TREE_CODE (op) == SSA_NAME)
     {
@@ -1265,6 +1267,12 @@ static bool
 	}
       else if (gimple_code (def) == GIMPLE_PHI)
 	{
+	  if (!*visited)
+	    *visited = BITMAP_ALLOC (NULL);
+
+	  if (!bitmap_set_bit (*visited, SSA_NAME_VERSION (op)))
+	    return true;
+
 	  /* In a phi, a constant argument may be unsigned even
 	     if in the source it's signed and negative.  Ignore
 	     those and consider the result of a phi signed if
@@ -1274,7 +1282,7 @@ static bool
 	    {
 	      tree op = gimple_phi_arg_def (def, i);
 	      if (TREE_CODE (op) != INTEGER_CST
-		  && !operand_signed_p (op))
+		  && !operand_signed_p (op, visited))
 		return false;
 	    }
 
@@ -1285,6 +1293,21 @@ static bool
   return !TYPE_UNSIGNED (TREE_TYPE (op));
 }
 
+/* Return true if the type of OP is signed, looking through any casts
+   to an unsigned type.  */
+
+static bool
+operand_signed_p (tree op)
+{
+  bitmap visited = NULL;
+  bool ret = operand_signed_p (op, &visited);
+
+  if (visited)
+    BITMAP_FREE (visited);
+
+  return ret;
+}
+
 /* Diagnose a call EXP to function FN decorated with attribute alloc_size
    whose argument numbers given by IDX with values given by ARGS exceed
    the maximum object size or cause an unsigned oveflow (wrapping) when
Index: gcc/testsuite/gcc.dg/pr78775.c
===================================================================
--- gcc/testsuite/gcc.dg/pr78775.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr78775.c	(working copy)
@@ -0,0 +1,19 @@
+/* PR c/78775 - [7 Regression] ICE in maybe_warn_alloc_args_overflow
+   { dg-do compile }
+   { dg-options "-O2" } */
+
+int a, b, *c;
+
+int main (void)
+{
+  unsigned long d = 0;
+  while (1)
+    {
+      switch (b)
+      case 'S':
+	d = a;
+      c = __builtin_malloc (d);
+    }
+
+  return 0;
+}

Reply via email to