https://gcc.gnu.org/g:9b090e35cd753681e70e13c50975bfd3e6a110c9
commit r16-7458-g9b090e35cd753681e70e13c50975bfd3e6a110c9 Author: David Malcolm <[email protected]> Date: Wed Feb 11 08:51:16 2026 -0500 analyzer: fold X + (Y - X) to Y [PR123973] gcc/analyzer/ChangeLog: PR analyzer/123973 * region-model-manager.cc (region_model_manager::maybe_fold_binop): Fold X + (Y - X) to Y. gcc/testsuite/ChangeLog: PR analyzer/123973 * c-c++-common/analyzer/infinite-recursion-pr123973.c: New test. Signed-off-by: David Malcolm <[email protected]> Diff: --- gcc/analyzer/region-model-manager.cc | 5 +++++ gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr123973.c | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index 1a2a0c740d09..cfde061d6561 100644 --- a/gcc/analyzer/region-model-manager.cc +++ b/gcc/analyzer/region-model-manager.cc @@ -685,6 +685,11 @@ region_model_manager::maybe_fold_binop (tree type, enum tree_code op, if (unary_op->get_op () == NEGATE_EXPR && unary_op->get_arg () == arg0) return get_or_create_int_cst (type, 0); + /* X + (Y - X) -> Y. */ + if (const binop_svalue *bin_op = arg1->dyn_cast_binop_svalue ()) + if (bin_op->get_op () == MINUS_EXPR) + if (bin_op->get_arg1 () == arg0) + return get_or_create_cast (type, bin_op->get_arg0 ()); break; case MINUS_EXPR: /* (VAL - 0) -> VAL. */ diff --git a/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr123973.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr123973.c new file mode 100644 index 000000000000..56be3a1af8ff --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr123973.c @@ -0,0 +1,7 @@ +#define Z 8 + +void fun(int x, int y) +{ + if (x + y > Z) + fun(x, Z - x); /* { dg-bogus "infinite recursion" } */ +}
