1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Avoid capturing nested arrow function parameters

Fixes GH-19867
Closes GH-20041
This commit is contained in:
Ilija Tovilo
2025-10-03 00:12:52 +02:00
parent d10d18852b
commit 5c956f9838
2 changed files with 47 additions and 1 deletions

View File

@@ -8092,6 +8092,8 @@ typedef struct {
bool varvars_used;
} closure_info;
static void find_implicit_binds(closure_info *info, zend_ast *params_ast, zend_ast *stmt_ast);
static void find_implicit_binds_recursively(closure_info *info, zend_ast *ast) {
if (!ast) {
return;
@@ -8136,7 +8138,15 @@ static void find_implicit_binds_recursively(closure_info *info, zend_ast *ast) {
} else if (ast->kind == ZEND_AST_ARROW_FUNC) {
/* For arrow functions recursively check the expression. */
zend_ast_decl *closure_ast = (zend_ast_decl *) ast;
find_implicit_binds_recursively(info, closure_ast->child[2]);
closure_info inner_info;
find_implicit_binds(&inner_info, closure_ast->child[0], closure_ast->child[2]);
if (inner_info.varvars_used) {
info->varvars_used = true;
}
if (zend_hash_num_elements(&inner_info.uses)) {
zend_hash_copy(&info->uses, &inner_info.uses, NULL);
}
zend_hash_destroy(&inner_info.uses);
} else if (!zend_ast_is_special(ast)) {
uint32_t i, children = zend_ast_get_num_children(ast);
for (i = 0; i < children; i++) {

View File

@@ -0,0 +1,36 @@
--TEST--
GH-19867: Avoid capturing nested arrow function parameters
--EXTENSIONS--
opcache
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.opt_debug_level=0x20000
--FILE--
<?php
fn() => fn($a, $b) => $a + $b;
?>
--EXPECTF--
$_main:
; (lines=%d, args=0, vars=%d, tmps=%d)
; (after optimizer)
; %s
0000 T0 = DECLARE_LAMBDA_FUNCTION 0
0001 FREE T0
0002 RETURN int(1)
{closure:%s:%d}:
; (lines=%d, args=0, vars=%d, tmps=%d)
; (after optimizer)
; %s
0000 T0 = DECLARE_LAMBDA_FUNCTION 0
0001 RETURN T0
{closure:%s:%d}:
; (lines=%d, args=2, vars=%d, tmps=%d)
; (after optimizer)
; %s
0000 CV0($a) = RECV 1
0001 CV1($b) = RECV 2
0002 T2 = ADD CV0($a) CV1($b)
0003 RETURN T2