diff --git a/NEWS b/NEWS index 519b0ccaf053..affdf246a709 100644 --- a/NEWS +++ b/NEWS @@ -51,6 +51,8 @@ PHP NEWS . Fixed a tracing JIT crash when compiling a side trace for a method of a class that could not be stored in the inheritance cache. (GH-21710) (Arnaud, iliaal) + . Fixed the block pass dropping the definition of the ZEND_FAST_CALL OP2 + operand. (Mrmaxmeier) - PDO: . Fixed a leak when a persistent connection failed a liveness check diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index ee70d021f4a9..c87b09c1d134 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -398,6 +398,16 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array } break; + case ZEND_FAST_CALL: + if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) { + /* OP2 holds the pending return value, which is consumed by the + * following RETURN, or destroyed by + * zend_dispatch_try_catch_finally_helper() if the finally block + * throws. Its source must not be removed. */ + Tsource[VAR_NUM(opline->op2.var)] = NULL; + } + break; + case ZEND_SWITCH_LONG: case ZEND_SWITCH_STRING: case ZEND_MATCH: diff --git a/ext/opcache/tests/fuzzer_function_jit_live_range_fast_call.phpt b/ext/opcache/tests/fuzzer_function_jit_live_range_fast_call.phpt new file mode 100644 index 000000000000..16d388c213d4 --- /dev/null +++ b/ext/opcache/tests/fuzzer_function_jit_live_range_fast_call.phpt @@ -0,0 +1,49 @@ +--TEST-- +Block pass must not remove the source of the ZEND_FAST_CALL OP2 return value +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=disable +--ENV-- +USE_ZEND_ALLOC=0 +USE_TRACKED_ALLOC=1 +--FILE-- +getMessage(), "\n"; + } + return "fallback"; +} + +function test_refcounted() { + $x = 1; + try { + try { + return true ? "returned" : "other"; + } finally { + undef_fn(); + } + } catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; + } + return "fallback"; +} + +var_dump(test_scalar()); +var_dump(test_refcounted()); +?> +--EXPECT-- +Error: Call to undefined function undef_fn() +string(8) "fallback" +Error: Call to undefined function undef_fn() +string(8) "fallback"