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