https://gcc.gnu.org/g:acbbdaf829a056ec1a20405742a3b6494db64dc7
commit r16-7710-gacbbdaf829a056ec1a20405742a3b6494db64dc7 Author: Roger Sayle <[email protected]> Date: Thu Feb 26 08:03:25 2026 +0000 PR c/119651: Fix some unexpected error_mark_node ICEs. This patch resolves PR c/119651 and PR c/123472 P4 regressions. 2026-02-26 Roger Sayle <[email protected]> gcc/ChangeLog PR c/119651 PR c/123472 * fold-const.cc (tree_nonzero_bits): Rename the original as a static function taking an additional precision parameter. Make this implementation robust to error_mark_node. Preserve the original API by checking for error_operand_p before invoking the static helper function. gcc/testsuite/ChangeLog PR c/119651 PR c/123472 * gcc.dg/pr119651.c: New test case. * gcc.dg/pr123472.c: Likewise. Diff: --- gcc/fold-const.cc | 70 ++++++++++++++++++++++++++--------------- gcc/testsuite/gcc.dg/pr119651.c | 10 ++++++ gcc/testsuite/gcc.dg/pr123472.c | 16 ++++++++++ 3 files changed, 70 insertions(+), 26 deletions(-) diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 41681d38570f..19f25d40d7f7 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -16708,10 +16708,11 @@ c_getstr (tree str) return getbyterep (str, NULL); } -/* Given a tree T, compute which bits in T may be nonzero. */ +/* Helper for tree_nonzero_bits. Given a tree T, compute which bits in T + may be nonzero, with precision PREC, the precision of T's type. */ -wide_int -tree_nonzero_bits (const_tree t) +static wide_int +tree_nonzero_bits (const_tree t, unsigned prec) { switch (TREE_CODE (t)) { @@ -16721,59 +16722,76 @@ tree_nonzero_bits (const_tree t) return get_nonzero_bits (t); case NON_LVALUE_EXPR: case SAVE_EXPR: - return tree_nonzero_bits (TREE_OPERAND (t, 0)); + return tree_nonzero_bits (TREE_OPERAND (t, 0), prec); case BIT_AND_EXPR: - return wi::bit_and (tree_nonzero_bits (TREE_OPERAND (t, 0)), - tree_nonzero_bits (TREE_OPERAND (t, 1))); + return wi::bit_and (tree_nonzero_bits (TREE_OPERAND (t, 0), prec), + tree_nonzero_bits (TREE_OPERAND (t, 1), prec)); case BIT_IOR_EXPR: case BIT_XOR_EXPR: - return wi::bit_or (tree_nonzero_bits (TREE_OPERAND (t, 0)), - tree_nonzero_bits (TREE_OPERAND (t, 1))); + return wi::bit_or (tree_nonzero_bits (TREE_OPERAND (t, 0), prec), + tree_nonzero_bits (TREE_OPERAND (t, 1), prec)); case COND_EXPR: - return wi::bit_or (tree_nonzero_bits (TREE_OPERAND (t, 1)), - tree_nonzero_bits (TREE_OPERAND (t, 2))); + return wi::bit_or (tree_nonzero_bits (TREE_OPERAND (t, 1), prec), + tree_nonzero_bits (TREE_OPERAND (t, 2), prec)); CASE_CONVERT: - return wide_int::from (tree_nonzero_bits (TREE_OPERAND (t, 0)), - TYPE_PRECISION (TREE_TYPE (t)), - TYPE_SIGN (TREE_TYPE (TREE_OPERAND (t, 0)))); + if (TREE_TYPE (t) != error_mark_node + && !error_operand_p (TREE_OPERAND (t, 0))) + { + tree op0 = TREE_OPERAND (t, 0); + tree inner_type = TREE_TYPE (op0); + unsigned inner_prec = TYPE_PRECISION (inner_type); + return wide_int::from (tree_nonzero_bits (op0, inner_prec), + prec, TYPE_SIGN (inner_type)); + } + break; case PLUS_EXPR: if (INTEGRAL_TYPE_P (TREE_TYPE (t))) { - wide_int nzbits1 = tree_nonzero_bits (TREE_OPERAND (t, 0)); - wide_int nzbits2 = tree_nonzero_bits (TREE_OPERAND (t, 1)); + wide_int nzbits1 = tree_nonzero_bits (TREE_OPERAND (t, 0), prec); + wide_int nzbits2 = tree_nonzero_bits (TREE_OPERAND (t, 1), prec); if (wi::bit_and (nzbits1, nzbits2) == 0) return wi::bit_or (nzbits1, nzbits2); } break; case LSHIFT_EXPR: - if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST) + if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST + && TREE_TYPE (t) != error_mark_node) { tree type = TREE_TYPE (t); - wide_int nzbits = tree_nonzero_bits (TREE_OPERAND (t, 0)); - wide_int arg1 = wi::to_wide (TREE_OPERAND (t, 1), - TYPE_PRECISION (type)); + wide_int nzbits = tree_nonzero_bits (TREE_OPERAND (t, 0), prec); + wide_int arg1 = wi::to_wide (TREE_OPERAND (t, 1), prec); return wi::neg_p (arg1) ? wi::rshift (nzbits, -arg1, TYPE_SIGN (type)) : wi::lshift (nzbits, arg1); } break; case RSHIFT_EXPR: - if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST) - { + if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST + && TREE_TYPE (t) != error_mark_node) + { tree type = TREE_TYPE (t); - wide_int nzbits = tree_nonzero_bits (TREE_OPERAND (t, 0)); - wide_int arg1 = wi::to_wide (TREE_OPERAND (t, 1), - TYPE_PRECISION (type)); + wide_int nzbits = tree_nonzero_bits (TREE_OPERAND (t, 0), prec); + wide_int arg1 = wi::to_wide (TREE_OPERAND (t, 1), prec); return wi::neg_p (arg1) ? wi::lshift (nzbits, -arg1) : wi::rshift (nzbits, arg1, TYPE_SIGN (type)); - } + } break; default: break; } - return wi::shwi (-1, TYPE_PRECISION (TREE_TYPE (t))); + return wi::shwi (-1, prec); +} + +/* Given a tree T, compute which bits in T may be nonzero. */ + +wide_int +tree_nonzero_bits (const_tree t) +{ + if (error_operand_p (t)) + return wi::shwi (-1, 64); + return tree_nonzero_bits (t, TYPE_PRECISION (TREE_TYPE (t))); } /* Helper function for address compare simplifications in match.pd. diff --git a/gcc/testsuite/gcc.dg/pr119651.c b/gcc/testsuite/gcc.dg/pr119651.c new file mode 100644 index 000000000000..d89c3c2b8cf8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr119651.c @@ -0,0 +1,10 @@ +/* PR c/119651 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +int main() { + int r = 0; + while (r % 2 == 0) { + } + double r = (double) sizeof(int); /* { dg-error "conflicting type" } */ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr123472.c b/gcc/testsuite/gcc.dg/pr123472.c new file mode 100644 index 000000000000..2f690c03db97 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr123472.c @@ -0,0 +1,16 @@ +/* PR c/123472 */ +/* { dg-do compile } */ +/* { do-options "-O2" } */ + +int a , b , c ; +__attribute__ ( ( __noinline__ ) ) int fn1 ( ) { +if ( ( b | ( a != ( a & c ) ) ) == 1 ) +__builtin_abort ( ) ; +return 0 ; +} +int c ( void ) { /* { dg-error "redeclared as different kind" } */ +a = 5 ; +c = 1 ; /* { dg-error "lvalue required" } */ +b = 6 ; +return fn1 ( ) ; +}
