diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index ace1206682042..19b3ce125733a 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -14105,6 +14105,13 @@ static int zend_jit_fe_fetch(zend_jit_ctx *jit, const zend_op *opline, uint32_t return 0; } } else { + // JIT: ZVAL_DEREF(value); + if (val_info & MAY_BE_REF) { + ir_ref ref = jit_ZVAL_ADDR(jit, val_addr); + ref = jit_ZVAL_DEREF_ref(jit, ref); + val_addr = ZEND_ADDR_REF_ZVAL(ref); + val_info &= ~MAY_BE_REF; + } // JIT: ZVAL_COPY(res, value); jit_ZVAL_COPY(jit, var_addr, -1, val_addr, val_info, true); } diff --git a/ext/opcache/tests/jit/gh21264-1.phpt b/ext/opcache/tests/jit/gh21264-1.phpt new file mode 100644 index 0000000000000..ec6cf407fa3b3 --- /dev/null +++ b/ext/opcache/tests/jit/gh21264-1.phpt @@ -0,0 +1,47 @@ +--TEST-- +GH-21264: Missing reference unwrap for FE_FETCH_R in JIT +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=function +--FILE-- +array); + } +} + +function test() { + $c = new C; + $element = 'qux'; + $c->array = [&$element, &$element]; + var_dump($c->test()); +} + +test(); +test(); + +?> +--EXPECT-- +array(2) { + [0]=> + string(3) "qux" + [1]=> + string(3) "qux" +} +array(2) { + [0]=> + string(3) "qux" + [1]=> + string(3) "qux" +} diff --git a/ext/opcache/tests/jit/gh21264-2.phpt b/ext/opcache/tests/jit/gh21264-2.phpt new file mode 100644 index 0000000000000..0729546a959d4 --- /dev/null +++ b/ext/opcache/tests/jit/gh21264-2.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-21264: Missing reference unwrap for FE_FETCH_R in JIT +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +--FILE-- +prop) { + $c->prop++; + } +} + +$element = 0; +$array = [&$element, &$element]; +test($array); +test($array); +var_dump($element); + +?> +--EXPECT-- +int(0)