[php-src] master: Merge branch 'PHP-8.5' into PHP-8.6
| From: | ndossche | Date: | Sat, 10 Oct 2026 23:07:15 +0000 |
| Subject: | [php-src] master: Merge branch 'PHP-8.5' into PHP-8.6 | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-142165@lists.php.net to get a copy of this message | ||
Author: ndossche (ndossche)
Date: 2026-10-11T01:06:53+02:00
Commit: https://github.com/php/php-src/commit/46aab15eba90f89e331c4a9c582a21f68156b700
Raw diff: https://github.com/php/php-src/commit/46aab15eba90f89e331c4a9c582a21f68156b700.diff
Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5:
Fix exception checks due to NAN warnings and object empty()'s
Changed paths:
A ext/opcache/tests/jit/nan_to_bool_exception.phpt
M NEWS
M Zend/Optimizer/zend_inference.c
M ext/opcache/jit/zend_jit_ir.c
Diff:
diff --git a/NEWS b/NEWS
index a4b3d143c37c..641488d813fb 100644
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,7 @@ PHP NEWS
. Fix type inference of ADD_ARRAY_UNPACK with integer keys. (ndossche)
. Fix too wide type inference for ASSIGN_DIM_OP. (ndossche)
. Fix OSS-Fuzz #568005340 (FETCH_DIM_FUNC_ARG partial conversion). (ndossche)
+ . Fix exception checks due to NAN warnings and object empty()'s. (ndossche)
- Phar:
. Fixed GH-24166 (Double-free in Phar::webPhar() in CGI without PATH_INFO).
diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c
index b373541736c1..dc6dcb052d69 100644
--- a/Zend/Optimizer/zend_inference.c
+++ b/Zend/Optimizer/zend_inference.c
@@ -5028,7 +5028,6 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op
*ssa_op
case ZEND_SWITCH_STRING:
case ZEND_MATCH:
case ZEND_ISSET_ISEMPTY_VAR:
- case ZEND_ISSET_ISEMPTY_CV:
case ZEND_FUNC_NUM_ARGS:
case ZEND_FUNC_GET_ARGS:
case ZEND_COPY_TMP:
@@ -5116,7 +5115,14 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op
*ssa_op
case ZEND_JMPZ_EX:
case ZEND_JMPNZ_EX:
case ZEND_JMP_SET:
- return (t1 & MAY_BE_OBJECT);
+ /* NAN cast to bool will warn */
+ return (t1 & (MAY_BE_OBJECT|MAY_BE_DOUBLE));
+ case ZEND_ISSET_ISEMPTY_CV:
+ if (!(opline->extended_value & ZEND_ISEMPTY)) {
+ return 0;
+ }
+ /* empty() casts to bool: objects may have a cast handler, and NAN will warn */
+ return (t1 & (MAY_BE_OBJECT|MAY_BE_DOUBLE));
case ZEND_BOOL:
case ZEND_BOOL_NOT:
/* NAN Cast to bool will warn, but if we have a range it is fine */
diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c
index bf5b5a14f5fa..d7f54e2b6471 100644
--- a/ext/opcache/jit/zend_jit_ir.c
+++ b/ext/opcache/jit/zend_jit_ir.c
@@ -7774,6 +7774,8 @@ static int zend_jit_bool_jmpznz(zend_jit_ctx *jit, const zend_op *opline,
uint32
ir_IF_TRUE_cold(if_val);
jit_SET_EX_OPLINE(jit, opline);
ir_CALL(IR_VOID, ir_CONST_FC_FUNC(zend_jit_nan_coerced_to_type_warning));
+ /* The warning may be turned into an exception by an error handler */
+ zend_jit_check_exception_undef_result(jit, opline);
ir_MERGE_WITH_EMPTY_FALSE(if_val);
ref = ir_NE(dval, ir_CONST_DOUBLE(0.0));
diff --git a/ext/opcache/tests/jit/nan_to_bool_exception.phpt
b/ext/opcache/tests/jit/nan_to_bool_exception.phpt
new file mode 100644
index 000000000000..c612c008f312
--- /dev/null
+++ b/ext/opcache/tests/jit/nan_to_bool_exception.phpt
@@ -0,0 +1,46 @@
+--TEST--
+JIT: NAN to bool coercion warning promoted to exception
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.file_update_protection=0
+opcache.jit=1205
+--EXTENSIONS--
+opcache
+--FILE--
+<?php
+set_error_handler(function ($no, $str) {
+ throw new Exception($str);
+});
+
+function jmpz(float $d) {
+ if ($d) {
+ echo "side effect\n";
+ }
+ echo "side effect\n";
+}
+
+function jmp_set(float $d) {
+ $r = $d ?: 1;
+ echo "side effect\n";
+ return $r;
+}
+
+function isempty(float $d) {
+ $r = empty($d);
+ echo "side effect\n";
+ return $r;
+}
+
+foreach (["jmpz", "jmp_set", "isempty"] as $f) {
+ try {
+ $f(NAN);
+ } catch (Exception $e) {
+ echo "$f: ", $e->getMessage(), "\n";
+ }
+}
+?>
+--EXPECT--
+jmpz: unexpected NAN value was coerced to bool
+jmp_set: unexpected NAN value was coerced to bool
+isempty: unexpected NAN value was coerced to bool