From bd88a54934f4953987c0085c574e482c6b50dc0d Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 3 Sep 2025 16:17:23 +0200 Subject: [PATCH] Ensure that type widening converges Range analysis may fail to converge (the process hangs) when the transfer function zend_inference_calc_range produces a smaller range. Fix by ensuring that the widening operator zend_inference_widening_meet allows only widening. This matches the inference rules in figure 13 of the paper. Fixes GH-19679 Closes GH-19683 --- NEWS | 1 + Zend/Optimizer/zend_inference.c | 4 ++++ Zend/tests/gh19679.phpt | 22 ++++++++++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 Zend/tests/gh19679.phpt diff --git a/NEWS b/NEWS index 0435cb4a8c5..b2b2dccd1cd 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,7 @@ PHP NEWS . Fixed bug GH-19544 (GC treats ZEND_WEAKREF_TAG_MAP references as WeakMap references). (Arnaud, timwolla) . Fixed bug GH-19613 (Stale array iterator pointer). (ilutov) + . Fixed bug GH-19679 (zend_ssa_range_widening may fail to converge). (Arnaud) - Date: . Fixed date_sunrise() and date_sunset() with partial-hour UTC offset. diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 15eb7afaaf1..0fe3e278529 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -1633,12 +1633,16 @@ static bool zend_inference_widening_meet(zend_ssa_var_info *var_info, zend_ssa_r r->min < var_info->range.min) { r->underflow = 1; r->min = ZEND_LONG_MIN; + } else { + r->min = var_info->range.min; } if (r->overflow || var_info->range.overflow || r->max > var_info->range.max) { r->overflow = 1; r->max = ZEND_LONG_MAX; + } else { + r->max = var_info->range.max; } if (var_info->range.min == r->min && var_info->range.max == r->max && diff --git a/Zend/tests/gh19679.phpt b/Zend/tests/gh19679.phpt new file mode 100644 index 00000000000..ab7f3be344d --- /dev/null +++ b/Zend/tests/gh19679.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-19679: zend_ssa_range_widening does not converge +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true)