From e6f1f3eefc1c9d8e78187e58aa34a46c09d4ae36 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Mon, 15 Sep 2025 11:30:23 +0200 Subject: [PATCH] Handle references after FETCH_OBJ_R with REG destination --- ext/opcache/jit/zend_jit_helpers.c | 9 ++++-- ext/opcache/tests/jit/gh19831_001.phpt | 33 ++++++++++++++++++++++ ext/opcache/tests/jit/gh19831_002.phpt | 39 ++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 ext/opcache/tests/jit/gh19831_001.phpt create mode 100644 ext/opcache/tests/jit/gh19831_002.phpt diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 0f5e1b11c3938..a98b9ebc77606 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -1965,8 +1965,13 @@ static zval* ZEND_FASTCALL zend_jit_fetch_obj_r_slow_ex(zend_object *zobj) void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS); retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, result); - if (retval == result && UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); + if (UNEXPECTED(Z_ISREF_P(retval))) { + if (retval == result) { + zend_unwrap_reference(retval); + } else { + retval = Z_REFVAL_P(retval); + } + ZEND_ASSERT(!Z_REFCOUNTED_P(retval)); } return retval; } diff --git a/ext/opcache/tests/jit/gh19831_001.phpt b/ext/opcache/tests/jit/gh19831_001.phpt new file mode 100644 index 0000000000000..c83ca6daa50d5 --- /dev/null +++ b/ext/opcache/tests/jit/gh19831_001.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-19831 001: fetch obj slow R REG + reference +--CREDITS-- +dktapps +--ENV-- +RT_COND=1 +--INI-- +opcache.jit=1203 +--FILE-- +layers; + } +} + +$t = new Test(); +$a = &$t->layers; +var_dump($t->getLayers()); + +?> +--EXPECT-- +int(1) diff --git a/ext/opcache/tests/jit/gh19831_002.phpt b/ext/opcache/tests/jit/gh19831_002.phpt new file mode 100644 index 0000000000000..25b596a3decb3 --- /dev/null +++ b/ext/opcache/tests/jit/gh19831_002.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-19831 002: fetch obj slow R REG + __get + reference +--CREDITS-- +dktapps +--ENV-- +RT_COND=1 +--INI-- +opcache.jit=1203 +--FILE-- +layers; + } +} + +$t = new Test(); +unset($t->layers); +var_dump($t->getLayers()); + +?> +--EXPECT-- +int(1)