From eb9fdd7b93cc737d1f483719e65f878b8112b89a Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 10 Nov 2026 21:02:29 +0000 Subject: [PATCH 1/2] ext/opcache: tracing JIT drops reference type of a named by-ref argument. Fix GH-25359 zend_jit_trace_build_tssa() narrowed SEND_VAR_EX op1_def to the by-value type using op2.num, which is the name literal for a named argument. The callee looked by-value, so the CV lost MAY_BE_REF and the ref leaked or was returned unwrapped. Skip the narrowing for named arguments. --- ext/opcache/jit/zend_jit_trace.c | 1 + ext/opcache/tests/jit/gh25359.phpt | 25 +++++++++++++++++++++++++ ext/opcache/tests/jit/gh25359_2.phpt | 27 +++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 ext/opcache/tests/jit/gh25359.phpt create mode 100644 ext/opcache/tests/jit/gh25359_2.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 9c54767fc226..4148fa8c5308 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -2357,6 +2357,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin /* Add statically inferred restrictions */ if (ssa_ops[idx].op1_def >= 0) { if (opline->opcode == ZEND_SEND_VAR_EX + && opline->op2_type != IS_CONST && frame && frame->call && frame->call->func diff --git a/ext/opcache/tests/jit/gh25359.phpt b/ext/opcache/tests/jit/gh25359.phpt new file mode 100644 index 000000000000..5ecc08115a20 --- /dev/null +++ b/ext/opcache/tests/jit/gh25359.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-25359 (Tracing JIT drops reference type of CV passed as a named by-ref argument) +--CREDITS-- +YuanchengJiang +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +opcache.jit_hot_func=1 +--FILE-- + +--EXPECT-- +string(5) "false" diff --git a/ext/opcache/tests/jit/gh25359_2.phpt b/ext/opcache/tests/jit/gh25359_2.phpt new file mode 100644 index 000000000000..bf6a499ed051 --- /dev/null +++ b/ext/opcache/tests/jit/gh25359_2.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-25359 (Tracing JIT drops reference type of CV passed as a named by-ref argument, leak) +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +opcache.jit_hot_func=1 +--FILE-- + +--EXPECT-- +int(43) +int(43) +int(43) +int(43) +int(43) From 6f0bd582e544356a7cb18bb489952aa2ab2d0e49 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 11 Nov 2026 04:54:14 +0000 Subject: [PATCH 2/2] feedback --- ext/opcache/tests/jit/gh25359.phpt | 22 ++++++++++++---------- ext/opcache/tests/jit/gh25359_2.phpt | 27 --------------------------- 2 files changed, 12 insertions(+), 37 deletions(-) delete mode 100644 ext/opcache/tests/jit/gh25359_2.phpt diff --git a/ext/opcache/tests/jit/gh25359.phpt b/ext/opcache/tests/jit/gh25359.phpt index 5ecc08115a20..b9c011cea57b 100644 --- a/ext/opcache/tests/jit/gh25359.phpt +++ b/ext/opcache/tests/jit/gh25359.phpt @@ -1,7 +1,5 @@ --TEST-- GH-25359 (Tracing JIT drops reference type of CV passed as a named by-ref argument) ---CREDITS-- -YuanchengJiang --EXTENSIONS-- opcache --INI-- @@ -11,15 +9,19 @@ opcache.jit=tracing opcache.jit_hot_func=1 --FILE-- --EXPECT-- -string(5) "false" +int(43) +int(43) +int(43) +int(43) +int(43) diff --git a/ext/opcache/tests/jit/gh25359_2.phpt b/ext/opcache/tests/jit/gh25359_2.phpt deleted file mode 100644 index bf6a499ed051..000000000000 --- a/ext/opcache/tests/jit/gh25359_2.phpt +++ /dev/null @@ -1,27 +0,0 @@ ---TEST-- -GH-25359 (Tracing JIT drops reference type of CV passed as a named by-ref argument, leak) ---EXTENSIONS-- -opcache ---INI-- -opcache.enable=1 -opcache.enable_cli=1 -opcache.jit=tracing -opcache.jit_hot_func=1 ---FILE-- - ---EXPECT-- -int(43) -int(43) -int(43) -int(43) -int(43)