Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -8083,6 +8083,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;
Expand Down Expand Up @@ -8127,7 +8129,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++) {
Expand Down
35 changes: 35 additions & 0 deletions ext/opcache/tests/gh19867.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
--TEST--
GH-19867: Avoid capturing nested arrow function parameters
--EXTENSIONS--
opcache
--INI--
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