Commit 2f2b421a485 for php.net

commit 2f2b421a485b9b95265b591d90aaabea90d35ec9
Author: Ilija Tovilo <ilija.tovilo@me.com>
Date:   Thu Jan 29 00:25:14 2026 +0100

    Fix segfault when preloading constant AST closure

    Fixes GH-21059
    Closes GH-21071

diff --git a/NEWS b/NEWS
index dbf94f74882..8ec869035f0 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ PHP                                                                        NEWS

 - Core:
   . Fixed bug GH-21029 (zend_mm_heap corrupted on Aarch64, LTO builds). (Arnaud)
+  . Fixed bug GH-21059 (Segfault when preloading constant AST closure). (ilutov)

 - Windows:
   . Fixed compilation with clang (missing intrin.h include). (Kévin Dunglas)
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c
index 9cb3c7aae4a..62a4bfec506 100644
--- a/Zend/zend_ast.c
+++ b/Zend/zend_ast.c
@@ -1154,6 +1154,12 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
 		}
 		case ZEND_AST_OP_ARRAY:
 		{
+			// Preloading will attempt to resolve constants but objects can't be stored in shm
+			// Aborting here to store the const AST instead
+			if (CG(in_compilation)) {
+				return FAILURE;
+			}
+
 			zend_function *func = (zend_function *)zend_ast_get_op_array(ast)->op_array;

 			zend_create_closure(result, func, scope, scope, NULL);
diff --git a/ext/opcache/tests/preload_gh21059.inc b/ext/opcache/tests/preload_gh21059.inc
new file mode 100644
index 00000000000..8f93bb45020
--- /dev/null
+++ b/ext/opcache/tests/preload_gh21059.inc
@@ -0,0 +1,7 @@
+<?php
+
+class Foo {
+    public const C = static function() {
+        echo "Hello world\n";
+    };
+}
diff --git a/ext/opcache/tests/preload_gh21059.phpt b/ext/opcache/tests/preload_gh21059.phpt
new file mode 100644
index 00000000000..39e7aceae94
--- /dev/null
+++ b/ext/opcache/tests/preload_gh21059.phpt
@@ -0,0 +1,18 @@
+--TEST--
+GH-21059: Segfault when preloading constant AST closure
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.preload={PWD}/preload_gh21059.inc
+--EXTENSIONS--
+opcache
+--SKIPIF--
+<?php
+if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
+?>
+--FILE--
+<?php
+(Foo::C)();
+?>
+--EXPECT--
+Hello world