[php-src] master: Merge branch 'PHP-8.6'

From: Date: Wed, 07 Oct 2026 20:26:49 +0000
Subject: [php-src] master: Merge branch 'PHP-8.6'
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-142075@lists.php.net to get a copy of this message
Author: ndossche (ndossche) Date: 2026-10-07T22:26:29+02:00 Commit: https://github.com/php/php-src/commit/60702faf6af0b0f93fc1f2cc27318acf8b359f7d Raw diff: https://github.com/php/php-src/commit/60702faf6af0b0f93fc1f2cc27318acf8b359f7d.diff Merge branch 'PHP-8.6' * PHP-8.6: Fix GH-17626: JIT corrupts opline handler when blacklisting root trace Changed paths: A ext/opcache/tests/jit/gh17626.inc A ext/opcache/tests/jit/gh17626.phpt A ext/opcache/tests/jit/gh17626_002.inc A ext/opcache/tests/jit/gh17626_002.phpt M ext/opcache/jit/zend_jit_trace.c Diff: diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 748ede31a0a0..e4c59d0b8aa7 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -8890,7 +8890,7 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf SHM_UNPROTECT(); zend_jit_unprotect(); - ((zend_op*)opline)->handler = + ((zend_op*)(t->opline))->handler = ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->orig_handler; ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->trace_flags &= ~ZEND_JIT_TRACE_JITED; diff --git a/ext/opcache/tests/jit/gh17626.inc b/ext/opcache/tests/jit/gh17626.inc new file mode 100644 index 000000000000..307a47ad2943 --- /dev/null +++ b/ext/opcache/tests/jit/gh17626.inc @@ -0,0 +1,2 @@ +<?php +function gh17626_callee(string $s) { return strtoupper($s); } diff --git a/ext/opcache/tests/jit/gh17626.phpt b/ext/opcache/tests/jit/gh17626.phpt new file mode 100644 index 000000000000..dbd917935c5f --- /dev/null +++ b/ext/opcache/tests/jit/gh17626.phpt @@ -0,0 +1,41 @@ +--TEST-- +GH-17626: Opline handler corrupted when a root trace is blacklisted at the max_root_traces limit (fails with --repeat 2) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.revalidate_freq=0 +opcache.jit=tracing +opcache.jit_buffer_size=16M +opcache.jit_hot_func=2 +opcache.jit_hot_loop=255 +opcache.jit_hot_return=255 +opcache.jit_hot_side_exit=255 +opcache.jit_max_root_traces=2 +--EXTENSIONS-- +opcache +--FILE-- +<?php +namespace GH17626; + +// In --repeat 2 the callee is recompiled after the first run, so the function +// guard in the trace compiled for caller() fails with ZEND_JIT_EXIT_INVALIDATE. + +require __DIR__ . '/gh17626.inc'; + +function caller(string $s) { + return gh17626_callee($s) . $s; +} + +caller('a'); +caller('a'); +caller('a'); +echo caller('a'), "\n"; +echo caller('b'), "\n"; + +touch(__DIR__ . '/gh17626.inc'); +opcache_invalidate(__DIR__ . '/gh17626.inc', true); +?> +--EXPECT-- +Aa +Bb diff --git a/ext/opcache/tests/jit/gh17626_002.inc b/ext/opcache/tests/jit/gh17626_002.inc new file mode 100644 index 000000000000..8a12c7ae9fb6 --- /dev/null +++ b/ext/opcache/tests/jit/gh17626_002.inc @@ -0,0 +1,2 @@ +<?php +class GH17626GrandParent {} diff --git a/ext/opcache/tests/jit/gh17626_002.phpt b/ext/opcache/tests/jit/gh17626_002.phpt new file mode 100644 index 000000000000..a0f4792f5404 --- /dev/null +++ b/ext/opcache/tests/jit/gh17626_002.phpt @@ -0,0 +1,47 @@ +--TEST-- +GH-17626: Opline handler corrupted when a root trace is blacklisted at the max_root_traces limit +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit=tracing +opcache.jit_buffer_size=16M +opcache.jit_hot_func=2 +opcache.jit_hot_loop=255 +opcache.jit_hot_return=255 +opcache.jit_hot_side_exit=255 +opcache.jit_max_root_traces=2 +--EXTENSIONS-- +opcache +--FILE-- +<?php +require __DIR__ . '/gh17626_002.inc'; + +class ParentA extends GH17626GrandParent { public static function m() { return 'A'; } } +class ParentB extends GH17626GrandParent { public static function m() { return 'B'; } } + +trait T { + public function run(string $s) { + return parent::m() . $s; + } +} + +class A extends ParentA { use T; } +class B extends ParentB { use T; } + +$a = new A; +$b = new B; + +$a->run('x'); +$a->run('x'); +$a->run('x'); +echo $a->run('x'), "\n"; +echo $b->run('y'), "\n"; +echo $b->run('y'), "\n"; +echo $a->run('x'), "\n"; +?> +--EXPECT-- +Ax +By +By +Ax

« previous php.cvs (#142075) next »