From e8b6ae4d7eb40ade613ad3eae7d03cc0b95eea81 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 20 Aug 2025 16:02:14 +0200 Subject: [PATCH 1/2] Fix incorrect opline after deoptimization --- ext/opcache/jit/zend_jit_ir.c | 12 ++------- ext/opcache/tests/jit/gh19486.phpt | 39 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 ext/opcache/tests/jit/gh19486.phpt diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 3ed9a5114756..8f06df51b8c1 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -17291,16 +17291,8 @@ static int zend_jit_trace_return(zend_jit_ctx *jit, bool original_handler, const addr = ir_CAST_FC_FUNC(addr); #endif ref = ir_CALL_2(IR_ADDR, addr, jit_FP(jit), jit_IP(jit)); - if (opline && - (opline->opcode == ZEND_RETURN - || opline->opcode == ZEND_RETURN_BY_REF - || opline->opcode == ZEND_GENERATOR_RETURN - || opline->opcode == ZEND_GENERATOR_CREATE - || opline->opcode == ZEND_YIELD - || opline->opcode == ZEND_YIELD_FROM)) { - zend_jit_vm_enter(jit, ref); - return 1; - } + zend_jit_vm_enter(jit, ref); + return 1; } zend_jit_vm_enter(jit, jit_IP(jit)); } diff --git a/ext/opcache/tests/jit/gh19486.phpt b/ext/opcache/tests/jit/gh19486.phpt new file mode 100644 index 000000000000..889b9bd05b8d --- /dev/null +++ b/ext/opcache/tests/jit/gh19486.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-19486: incorrect opline after deoptimization +--FILE-- +getLakeArea(0, 0); + +class GameMap +{ + public $lakeID = []; + + public function getLakeArea(int $x, int $y): int + { + $this->floodFill(0, 0, 0); + } + + public function floodFill(int $x, int $y, int $id): void + { + if (($x < 0) or ($x >= 900) or ($y < 0) or ($y >= 400)) { + return; + } + if (isset($this->lakeID[$y][$x]) and ($this->lakeID[$y][$x] == $id)) { + return; + } + $this->lakeID[$y][$x] = $id; + $this->floodFill($x - 1, $y, $id); + $this->floodFill($x + 1, $y, $id); + $this->floodFill($x, $y - 1, $id); + $this->floodFill($x, $y + 1, $id); + } +} + +?> +--EXPECTF-- +Fatal error: Uncaught TypeError: GameMap::getLakeArea(): Return value must be of type int, none returned in %s:%d +Stack trace: +#0 %s(%d): GameMap->getLakeArea(0, 0) +#1 {main} + thrown in %s on line %d From 4784f2cce4a332b223fc47ad4b8969efe92780df Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 20 Aug 2025 17:41:47 +0200 Subject: [PATCH 2/2] Simplify test --- ext/opcache/tests/jit/gh19486.phpt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ext/opcache/tests/jit/gh19486.phpt b/ext/opcache/tests/jit/gh19486.phpt index 889b9bd05b8d..8a0c610ed200 100644 --- a/ext/opcache/tests/jit/gh19486.phpt +++ b/ext/opcache/tests/jit/gh19486.phpt @@ -1,5 +1,8 @@ --TEST-- GH-19486: incorrect opline after deoptimization +--INI-- +opcache.jit_blacklist_root_trace=1 +opcache.jit_blacklist_side_trace=1 --FILE-- = 900) or ($y < 0) or ($y >= 400)) { + if (($x < 0) or ($x >= 50) or ($y < 0) or ($y >= 50)) { return; } if (isset($this->lakeID[$y][$x]) and ($this->lakeID[$y][$x] == $id)) {