Commit ef522525cff for php.net

commit ef522525cff4bb9218d4b663cbacd2686ea17922
Author: Arnaud Le Blanc <365207+arnaud-lb@users.noreply.github.com>
Date:   Thu Jan 8 11:46:10 2026 +0100

    Introduce zend_ast_call_get_args() (#20859)

diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS
index 22b9e6f660c..748549e085b 100644
--- a/UPGRADING.INTERNALS
+++ b/UPGRADING.INTERNALS
@@ -52,6 +52,8 @@ PHP 8.6 INTERNALS UPGRADE NOTES
   . zend_function.arg_info is now always a zend_arg_info*. Before, it was a
     zend_internal_arg_info on internal functions, unless the
     ZEND_ACC_USER_ARG_INFO flag was set.
+  . Added zend_ast_call_get_args() to fetch the argument node from any call
+    node.

 ========================
 2. Build system changes
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c
index 2cd2ab40b04..e0a68a73bdf 100644
--- a/Zend/zend_ast.c
+++ b/Zend/zend_ast.c
@@ -1139,19 +1139,22 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
 		{
 			zend_function *fptr;
 			zend_class_entry *called_scope = NULL;
+
+			zend_ast *args_ast = zend_ast_call_get_args(ast);
+			ZEND_ASSERT(args_ast->kind == ZEND_AST_CALLABLE_CONVERT);
+
+			zend_ast_fcc *fcc_ast = (zend_ast_fcc*)args_ast;
+
+			zend_ast_list *args = zend_ast_get_list(fcc_ast->args);
+			ZEND_ASSERT(args->children > 0);
+			if (args->children != 1 || args->child[0]->attr != ZEND_PLACEHOLDER_VARIADIC) {
+				/* TODO: PFAs */
+				zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations");
+				return FAILURE;
+			}
+
 			switch (ast->kind) {
 				case ZEND_AST_CALL: {
-					ZEND_ASSERT(ast->child[1]->kind == ZEND_AST_CALLABLE_CONVERT);
-					zend_ast_fcc *fcc_ast = (zend_ast_fcc*)ast->child[1];
-
-					zend_ast_list *args = zend_ast_get_list(fcc_ast->args);
-					ZEND_ASSERT(args->children > 0);
-					if (args->children != 1 || args->child[0]->attr != ZEND_PLACEHOLDER_VARIADIC) {
-						/* TODO: PFAs */
-						zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations");
-						return FAILURE;
-					}
-
 					fptr = ZEND_MAP_PTR_GET(fcc_ast->fptr);

 					if (!fptr) {
@@ -1176,17 +1179,6 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
 					break;
 				}
 				case ZEND_AST_STATIC_CALL: {
-					ZEND_ASSERT(ast->child[2]->kind == ZEND_AST_CALLABLE_CONVERT);
-					zend_ast_fcc *fcc_ast = (zend_ast_fcc*)ast->child[2];
-
-					zend_ast_list *args = zend_ast_get_list(fcc_ast->args);
-					ZEND_ASSERT(args->children > 0);
-					if (args->children != 1 || args->child[0]->attr != ZEND_PLACEHOLDER_VARIADIC) {
-						/* TODO: PFAs */
-						zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations");
-						return FAILURE;
-					}
-
 					zend_class_entry *ce = zend_ast_fetch_class(ast->child[0], scope);
 					if (!ce) {
 						return FAILURE;
@@ -3083,3 +3075,15 @@ zend_ast * ZEND_FASTCALL zend_ast_with_attributes(zend_ast *ast, zend_ast *attr)

 	return ast;
 }
+
+zend_ast * ZEND_FASTCALL zend_ast_call_get_args(zend_ast *ast)
+{
+	if (ast->kind == ZEND_AST_CALL) {
+		return ast->child[1];
+	} else if (ast->kind == ZEND_AST_STATIC_CALL || ast->kind == ZEND_AST_METHOD_CALL) {
+		return ast->child[2];
+	}
+
+	ZEND_UNREACHABLE();
+	return NULL;
+}
diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h
index 1c6d6f82fad..c212cd8367a 100644
--- a/Zend/zend_ast.h
+++ b/Zend/zend_ast.h
@@ -440,4 +440,6 @@ static zend_always_inline zend_ast *zend_ast_list_rtrim(zend_ast *ast) {

 zend_ast * ZEND_FASTCALL zend_ast_with_attributes(zend_ast *ast, zend_ast *attr);

+zend_ast * ZEND_FASTCALL zend_ast_call_get_args(zend_ast *ast);
+
 #endif