[php-src] Issue #24154: Function JIT: ++/-- on a typed property holding a reference throws TypeError
| From: | zeriyoshi | Date: | Tue, 06 Oct 2026 07:37:10 +0000 |
| Subject: | [php-src] Issue #24154: Function JIT: ++/-- on a typed property holding a reference throws TypeError | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-252911@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/24154
Author: zeriyoshi
### Description
### Description
The following code:
```php
<?php
class Test
{
public int $value = 0;
public function inc(): void
{
$this->value++;
}
}
$test = new Test();
$ref = &$test->value;
$test->inc();
var_dump($test->value);
```
Run with
php -d opcache.enable_cli=1 -d opcache.file_update_protection=0 -d
opcache.jit=function repro.php
Resulted in this output:
```
Fatal error: Uncaught TypeError: Cannot assign int to property Test::$value of type int in
/path/to/repro.php:8
Stack trace:
#0 /path/to/repro.php(14): Test->inc()
#1 {main}
thrown in /path/to/repro.php on line 8
```
But I expected this output instead:
```
int(1)
```
$this->value-- fails the same way. It works as expected with
opcache.jit=disable and opcache.jit=tracing.
This looks like a regression from 1b2bde474ab (GH-24071). In zend_jit_inc_typed_prop()
/ zend_jit_dec_typed_prop(), ZVAL_DEREF(var_ptr); ZVAL_COPY(&tmp,
var_ptr); was replaced with ZVAL_COPY_DEREF(&tmp, var_ptr);, which only
dereferences the copy. var_ptr keeps pointing at the reference, so the property type
check fails, and the error path then calls zval_ptr_dtor() on the reference and
overwrites the property slot.
Function JIT calls these helpers directly when the result of the increment/decrement is unused.
Restoring the explicit dereference fixes maybe:
```diff
--- a/ext/opcache/jit/zend_jit_helpers.c
+++ b/ext/opcache/jit/zend_jit_helpers.c
@@ -2991,7 +2991,8 @@ static void ZEND_FASTCALL zend_jit_inc_typed_prop(zval *var_ptr,
zend_property_i
zend_execute_data *execute_data = EG(current_execute_data);
zval tmp;
- ZVAL_COPY_DEREF(&tmp, var_ptr);
+ ZVAL_DEREF(var_ptr);
+ ZVAL_COPY(&tmp, var_ptr);
increment_function(var_ptr);
@@ -3022,7 +3023,8 @@ static void ZEND_FASTCALL zend_jit_dec_typed_prop(zval *var_ptr,
zend_property_i
zend_execute_data *execute_data = EG(current_execute_data);
zval tmp;
- ZVAL_COPY_DEREF(&tmp, var_ptr);
+ ZVAL_DEREF(var_ptr);
+ ZVAL_COPY(&tmp, var_ptr);
decrement_function(var_ptr);
```
### PHP Version
```
PHP 8.7.0-dev (cli) (NTS)
master at 9cd641febca (PHP-8.6 and older are not affected)
```
### Operating System
Linux aarch64 / Ubuntu 24.04.5 LTS
### PHP Version
```plain
PHP 8.7.0-dev (cli) (built: Sep 30 2026 13:00:09) (NTS)
Copyright © The PHP Group and Contributors
Zend Engine v4.7.0-dev, Copyright © Zend by Perforce
with Zend OPcache v8.7.0-dev, Copyright ©, by Zend by Perforce
```
### Operating System
Ubuntu 24.04.5 LTS