[php-src] master: Fix type inference of ADD_ARRAY_UNPACK with integer keys

From: Date: Thu, 08 Oct 2026 16:49:47 +0000
Subject: [php-src] master: Fix type inference of ADD_ARRAY_UNPACK with integer keys
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-142089@lists.php.net to get a copy of this message
Author: ndossche (ndossche) Date: 2026-10-08T18:47:19+02:00 Commit: https://github.com/php/php-src/commit/c8e5c27b3da15e50ba7695d272f3520fe45255a5 Raw diff: https://github.com/php/php-src/commit/c8e5c27b3da15e50ba7695d272f3520fe45255a5.diff Fix type inference of ADD_ARRAY_UNPACK with integer keys This causes a crash with the JIT for the provided test, because JIT will only emit the hash case even though the array is gonna be packed. Closes GH-24093. Changed paths: A ext/opcache/tests/jit/add_array_unpack_packed.phpt M NEWS M Zend/Optimizer/zend_inference.c Diff: diff --git a/NEWS b/NEWS index df64bebbbc83..12b88a7e8e6f 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,7 @@ PHP NEWS . Fixed bug GH-17626 (JIT corrupts an opline handler when blacklisting a root trace at the opcache.jit_max_root_traces limit, causing spurious "Too few arguments" errors and crashes). (RV7PR) + . Fix type inference of ADD_ARRAY_UNPACK with integer keys. (ndossche) - SOAP: . Fixed use of uninitialized func in do_request() on OOM bailout. diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index f0d8d873977e..66369a154820 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -3454,7 +3454,11 @@ static zend_always_inline zend_result _zend_update_type_info( case ZEND_ADD_ARRAY_UNPACK: tmp = ssa_var_info[ssa_op->result_use].type; ZEND_ASSERT(tmp & MAY_BE_ARRAY); - tmp |= t1 & (MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF); + if (t1 & MAY_BE_ARRAY_KEY_LONG) { + /* Integer keys are appended without copying the hash/packed layout of the source array. */ + tmp |= MAY_BE_HASH_ONLY(tmp) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG; + } + tmp |= t1 & (MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF); if (t1 & MAY_BE_OBJECT) { tmp |= MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY; } diff --git a/ext/opcache/tests/jit/add_array_unpack_packed.phpt b/ext/opcache/tests/jit/add_array_unpack_packed.phpt new file mode 100644 index 000000000000..f0b6b9a33cec --- /dev/null +++ b/ext/opcache/tests/jit/add_array_unpack_packed.phpt @@ -0,0 +1,24 @@ +--TEST-- +JIT: unpacking a hash array with integer keys produces a packed array +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=64M +opcache.jit=1205 +--EXTENSIONS-- +opcache +--FILE-- +<?php +function f($c) { + $b = $c ? [-5 => 1, -6 => 2, -7 => 3] : [-7 => 2]; + $a = [...$b]; + foreach ($a as $k => $v) { + echo "$k => $v\n"; + } +} +f(true); +?> +--EXPECT-- +0 => 1 +1 => 2 +2 => 3

« previous php.cvs (#142089) next »