Commit 71d56aa5016 for php.net

commit 71d56aa50169f0feed8e2380a56efe307849a813
Author: ndossche <7771979+ndossche@users.noreply.github.com>
Date:   Sat Sep 19 16:03:32 2026 +0200

    Fix OSS-Fuzz #540904105: ASSERT: ast->attr == T_CLASS_C

    Closes GH-23769.

diff --git a/NEWS b/NEWS
index 69e1b9ade9f..1a448d35591 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ PHP                                                                        NEWS
     restored). (yqtian-se)
   . Fixed OSS-Fuzz #538730793 (Assertion failure when returning by-ref from
     closure invoke). (ndossche)
+  . Fixed OSS-Fuzz #540904105 (ASSERT: ast->attr == T_CLASS_C). (ndossche)

 - CLI
   . Fix GH-22567 (Windows ZTS CLI SAPI should refresh its TSRMLS cache during
diff --git a/Zend/tests/partial_application/oss_fuzz_540904105.phpt b/Zend/tests/partial_application/oss_fuzz_540904105.phpt
new file mode 100644
index 00000000000..5755c576b4f
--- /dev/null
+++ b/Zend/tests/partial_application/oss_fuzz_540904105.phpt
@@ -0,0 +1,31 @@
+--TEST--
+OSS-Fuzz #540904105 (ASSERT: ast->attr == T_CLASS_C)
+--FILE--
+<?php
+
+function foo($test, $extra) {}
+
+const C = foo(__METHOD__, ?);
+
+var_dump(C);
+
+?>
+--EXPECTF--
+object(Closure)#%d (%d) {
+  ["name"]=>
+  string(%d) "%s"
+  ["file"]=>
+  string(%d) "%s"
+  ["line"]=>
+  int(5)
+  ["static"]=>
+  array(1) {
+    ["test"]=>
+    string(0) ""
+  }
+  ["parameter"]=>
+  array(1) {
+    ["$extra"]=>
+    string(10) "<required>"
+  }
+}
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index f6bff9830bf..0ced5528386 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -13076,6 +13076,16 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
 			zend_eval_const_expr(&ast->child[0]);
 			zend_eval_const_expr(&ast->child[1]);
 			return;
+		// Only FCC and PFA can appear in constant expressions.
+		case ZEND_AST_CALL:
+		case ZEND_AST_STATIC_CALL:
+		{
+			zend_ast *args_ast = zend_ast_call_get_args(ast);
+			if (args_ast && args_ast->kind == ZEND_AST_CALLABLE_CONVERT) {
+				zend_eval_const_expr(&((zend_ast_fcc *) args_ast)->args);
+			}
+			return;
+		}
 		case ZEND_AST_NAMED_ARG:
 			zend_eval_const_expr(&ast->child[1]);
 			return;