1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

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
This commit is contained in:
Arnaud Le Blanc
2025-09-03 16:17:23 +02:00
parent 080fd14458
commit bd88a54934
3 changed files with 27 additions and 0 deletions

1
NEWS
View File

@@ -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.

View File

@@ -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 &&

22
Zend/tests/gh19679.phpt Normal file
View File

@@ -0,0 +1,22 @@
--TEST--
GH-19679: zend_ssa_range_widening does not converge
--SKIPIF--
<?php
if (PHP_INT_SIZE !== 8) {
die('skip output depends PHP_INT_SIZE=8');
}
?>
--FILE--
<?php
function test() {
$a = PHP_INT_MIN+1;
$b = 0;
while ($b++ < 3) {
$a = (int) ($a-- - $b - 1);
}
return $a;
}
var_dump(test() == PHP_INT_MIN);
?>
--EXPECT--
bool(true)