Browse Source

Avoid capturing nested arrow function parameters

Fixes GH-19867
Closes GH-20041
pull/19429/merge
Ilija Tovilo 1 week ago
parent
commit
5c956f9838
No known key found for this signature in database GPG Key ID: 115CEA7A713E12E9
  1. 12
      Zend/zend_compile.c
  2. 36
      ext/opcache/tests/gh19867.phpt

12
Zend/zend_compile.c

@ -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++) {

36
ext/opcache/tests/gh19867.phpt

@ -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
Loading…
Cancel
Save