Commit c8e5c27b3da for php

commit c8e5c27b3da15e50ba7695d272f3520fe45255a5
Author: ndossche <7771979+ndossche@users.noreply.github.com>
Date:   Sat Oct 3 11:29:26 2026 +0200

    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.

diff --git a/NEWS b/NEWS
index df64bebbbc8..12b88a7e8e6 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 f0d8d873977..66369a15482 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 00000000000..f0b6b9a33ce
--- /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