From: David Malcolm Date: Wed, 11 Feb 2026 13:51:16 +0000 (-0500) Subject: analyzer: fold X + (Y - X) to Y [PR123973] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b090e35cd753681e70e13c50975bfd3e6a110c9;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index 1a2a0c740d0..cfde061d656 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 00000000000..56be3a1af8f --- /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" } */ +}