[php-src] PHP-8.6: Fix exception checks due to NAN warnings and object empty()'s

From: Date: Sat, 10 Oct 2026 23:07:15 +0000
Subject: [php-src] PHP-8.6: Fix exception checks due to NAN warnings and object empty()'s
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-142164@lists.php.net to get a copy of this message
Author: ndossche (ndossche) Date: 2026-10-11T01:06:25+02:00 Commit: https://github.com/php/php-src/commit/269f7b762b5938915a6a2792a8b9b0d81edc664a Raw diff: https://github.com/php/php-src/commit/269f7b762b5938915a6a2792a8b9b0d81edc664a.diff Fix exception checks due to NAN warnings and object empty()'s The empty() check for objects must be backported to 8.4, the NAN problem is new since 320fe2975b. Closes GH-24241. 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 34f540d39b49..262f3f4fd7a4 100644 --- a/NEWS +++ b/NEWS @@ -30,6 +30,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) - Standard: . Fixed password_get_info() and password_needs_rehash() accepting malformed diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index b862fe483613..af31ec757bed 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -5030,7 +5030,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: @@ -5118,7 +5117,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 ec745d0613ae..471cf55c6543 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -7753,6 +7753,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

« previous php.cvs (#142164) next »