1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00
Files
archived-php-src/ext/opcache/tests/jit/gh20818.phpt
Chris Hasiński 1db1c7f5c1 Fix segfault in Tracing JIT with object reference (GH-20818)
When FE_RESET_RW executes, it converts the CV to a reference before
checking if the array/object is empty. However, when the JIT creates
exit points for FE_RESET_RW in zend_jit_trace_handler(), it wasn't
updating the stack type for op1 to reflect this change.

This caused side traces compiled from these exit points to have
incorrect type information. The side trace's CV cleanup code would
see IS_OBJECT and generate a direct call to zend_objects_store_del(),
but the actual value was a zend_reference*, causing a segfault.

The fix adds ZEND_FE_RESET_RW to the list of opcodes that temporarily
set their op1 stack type to IS_UNKNOWN before creating exit points.
This follows the same pattern used for ZEND_BIND_INIT_STATIC_OR_JMP.
When IS_UNKNOWN, the JIT falls back to SSA type info which correctly
includes MAY_BE_REF for FE_RESET_RW's op1_def.

Fixes GH-20818
Closes GH-20948
2026-01-21 00:24:14 +01:00

31 lines
447 B
PHP

--TEST--
GH-20818 (Segfault in Tracing JIT with Object Reference)
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.jit=tracing
opcache.jit_buffer_size=1M
--FILE--
<?php
function process($data) {
foreach ($data as &$v) {}
}
$data = [
(object) ["" => 1],
(object) ["" => 1],
(object) [],
];
for ($i = 0; $i < 200; $i += 1) {
foreach ($data as $entry) {
process($entry);
}
}
echo "Done\n";
?>
--EXPECT--
Done