diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 75c5ed4d..4734b2ce 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1532,12 +1532,15 @@ class CompilerBase extends \PhpAot\Core\Translator return $this->parseIdentifier($expr); } - protected function parseBinaryOp($left, $right, $op): string + protected function parseBinaryOp(NodeAbstract $left, NodeAbstract $right, string $op): string { // 运算逻辑,优先转为数字 $leftExpr = $this->parseNumericIdentifier($left); $rightExpr = $this->parseNumericIdentifier($right); + $this->checkVarMustExist($left, $leftExpr); + $this->checkVarMustExist($right, $rightExpr); + $leftType = $this->detectExprType($left); $rightType = $this->detectExprType($right); @@ -4576,13 +4579,14 @@ class CompilerBase extends \PhpAot\Core\Translator } foreach ($vars as $var) { - if ($var->name === 'this' - or !$this->hasLocalVar($var->name) + $varName = $this->escapeVarName($this->parseVariable($var)); + if ($varName === 'this' + or !$this->hasLocalVar($varName) or isset($params[$var->name]) - or isset($uses[$var->name])) { + or isset($uses[$varName])) { continue; } - $uses[$var->name] = new Node\ClosureUse($var); + $uses[$varName] = new Node\ClosureUse($var); } $uses = array_values($uses); diff --git a/tests/zend/array_unpack/gh19303.phpt b/tests/zend/array_unpack/gh19303.phpt new file mode 100644 index 00000000..af594c37 --- /dev/null +++ b/tests/zend/array_unpack/gh19303.phpt @@ -0,0 +1,11 @@ +--TEST-- +GH-19303 (Unpacking empty packed array into uninitialized array causes assertion failure) +--FILE-- + +--EXPECT-- +array(0) { +} diff --git a/tests/zend/arrow_functions/001.phpt b/tests/zend/arrow_functions/001.phpt new file mode 100644 index 00000000..27b2557b --- /dev/null +++ b/tests/zend/arrow_functions/001.phpt @@ -0,0 +1,45 @@ +--TEST-- +Basic arrow function functionality check +--FILE-- + 1; +var_dump($foo()); + +$foo = fn($x) => $x; +var_dump($foo(2)); + +$foo = fn($x, $y) => $x + $y; +var_dump($foo(1, 2)); + +// Closing over $var +$var = 4; +$foo = fn() => $var; +var_dump($foo()); + +// Not closing over $var, it's a parameter +$foo = fn($var) => $var; +var_dump($foo(5)); + +// Close over $var by-value, not by-reference +$var = 5; +$foo = fn() => ++$var; +var_dump($foo()); +var_dump($var); + +// Nested arrow functions closing over variable +$var = 6; +var_dump((fn() => fn() => $var)()()); +var_dump((fn() => function() use($var) { return $var; })()()); + +?> +--EXPECT-- +int(1) +int(2) +int(3) +int(4) +int(5) +int(6) +int(5) +int(6) +int(6) diff --git a/tests/zend/arrow_functions/004.phpt b/tests/zend/arrow_functions/004.phpt new file mode 100644 index 00000000..f581cb21 --- /dev/null +++ b/tests/zend/arrow_functions/004.phpt @@ -0,0 +1,13 @@ +--TEST-- +Auto-globals in arrow functions +--FILE-- + $GLOBALS['a']; + var_dump($fn()); +} +?> +--EXPECT-- +int(123)