From 166f53f28e11072e4d87fb2f450636b425b6632d Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Wed, 21 Jan 2026 16:43:35 +0800 Subject: [PATCH] =?UTF-8?q?fix(php):=20=E4=BF=AE=E5=A4=8D=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=99=A8=E4=B8=AD=E7=9A=84=E5=8F=98=E9=87=8F=E5=A3=B0?= =?UTF-8?q?=E6=98=8E=E5=92=8C=E5=B1=9E=E6=80=A7=E8=8E=B7=E5=8F=96=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在循环中为键变量和值变量添加本地变量声明检查 - 确保变量在使用前已正确定义 - 添加对属性获取表达式的处理支持 - 为递增递减操作添加新的测试用例 - 包括64位平台整数溢出处理的测试 - 添加布尔类型递增递减异常处理测试 - 添加引用属性递增递减功能测试 --- src/Php/CompilerBase.php | 15 ++++++++-- .../in-de-crement/decrement_001_64bit.phpt | 25 +++++++++++++++++ .../in-de-crement/incdec_bool_exception.phpt | 28 +++++++++++++++++++ .../in-de-crement/incdec_ref_property.phpt | 27 ++++++++++++++++++ .../in-de-crement/increment_001_64bit.phpt | 24 ++++++++++++++++ .../in-de-crement/post_inc_without_use.phpt | 12 ++++++++ 6 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 tests/zend/in-de-crement/decrement_001_64bit.phpt create mode 100644 tests/zend/in-de-crement/incdec_bool_exception.phpt create mode 100644 tests/zend/in-de-crement/incdec_ref_property.phpt create mode 100644 tests/zend/in-de-crement/increment_001_64bit.phpt create mode 100644 tests/zend/in-de-crement/post_inc_without_use.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 11156f9c..ea585906 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -2064,7 +2064,10 @@ class CompilerBase extends \PhpAot\Core\Translator $code = 'for (auto iter = ' . $iteratorVar . '.begin(); iter != ' . $iteratorVar . '.end(); ++iter) {' . PHP_EOL; $this->indentLevel++; if ($node->keyVar) { - $code .= self::TYPE_VAR . ' ' . $this->getIndent() . ' ' . $keyVar . ' = iter.key();' . PHP_EOL; + if (!$this->hasVar($keyVar)) { + $this->addLocalVar($keyVar, self::TYPE_VAR); + } + $code .= $this->getIndent() . ' ' . $keyVar . ' = iter.key();' . PHP_EOL; } if ($node->valueVar->getType() == self::EXPR_ARRAY_DIM_FETCH) { @@ -2076,7 +2079,10 @@ class CompilerBase extends \PhpAot\Core\Translator $code .= $this->getIndent() . "$array.offsetSet($dim, iter.value());"; } else { $valueVar = $this->parseIdentifier($node->valueVar); - $code .= self::TYPE_VAR . ' ' . $this->getIndent() . ' ' . $valueVar . ' = iter.value();' . PHP_EOL; + if (!$this->hasVar($valueVar)) { + $this->addLocalVar($valueVar, self::TYPE_VAR); + } + $code .= $this->getIndent() . ' ' . $valueVar . ' = iter.value();' . PHP_EOL; } $body = $this->parseStmts($node->stmts); @@ -2356,6 +2362,11 @@ class CompilerBase extends \PhpAot\Core\Translator return $var . ' = &' . $this->parseIdentifier($expr->expr); } elseif ($expr->expr->getType() === self::EXPR_ARRAY_DIM_FETCH) { return $var . ' = ' . $this->parseIdentifier($expr->expr); + } elseif ($this->isPropertyFetch($expr->expr)) { + $var = $this->parseIdentifier($expr->var); + $object = $this->convertToObject($expr->expr->var); + $prop = $this->identifierToStr($expr->expr->name); + return $var . ' = ' . $object . '.getPropertyReference(' . $prop . ')'; } } abort($expr); diff --git a/tests/zend/in-de-crement/decrement_001_64bit.phpt b/tests/zend/in-de-crement/decrement_001_64bit.phpt new file mode 100644 index 00000000..a94f843c --- /dev/null +++ b/tests/zend/in-de-crement/decrement_001_64bit.phpt @@ -0,0 +1,25 @@ +--TEST-- +Decrementing min int values 64bit +--SKIPIF-- + +--INI-- +precision=14 +--FILE-- + +--EXPECT-- +float(-9.223372036854776E+18) +float(-9.223372036854776E+18) +Done diff --git a/tests/zend/in-de-crement/incdec_bool_exception.phpt b/tests/zend/in-de-crement/incdec_bool_exception.phpt new file mode 100644 index 00000000..8f1db31c --- /dev/null +++ b/tests/zend/in-de-crement/incdec_bool_exception.phpt @@ -0,0 +1,28 @@ +--TEST-- +Inc/dec on bool: warning converted to exception +--FILE-- +getMessage(), PHP_EOL; + } + try { + $value--; + } catch (\Exception $e) { + echo $e->getMessage(), PHP_EOL; + } +} +?> +--EXPECT-- +Warning: Increment on type bool has no effect, this will change in the next major version of PHP in Unknown(0) : eval() on line 1 + +Warning: Increment on type bool has no effect, this will change in the next major version of PHP in Unknown(0) : eval() on line 1 + +Warning: Increment on type bool has no effect, this will change in the next major version of PHP in Unknown(0) : eval() on line 1 + +Warning: Increment on type bool has no effect, this will change in the next major version of PHP in Unknown(0) : eval() on line 1 + diff --git a/tests/zend/in-de-crement/incdec_ref_property.phpt b/tests/zend/in-de-crement/incdec_ref_property.phpt new file mode 100644 index 00000000..a73b2912 --- /dev/null +++ b/tests/zend/in-de-crement/incdec_ref_property.phpt @@ -0,0 +1,27 @@ +--TEST-- +Incrementing and decrementing a referenced property +--FILE-- +prop = 1; +$ref =& $obj->prop; +var_dump(++$obj->prop); +var_dump($obj->prop); +var_dump($obj->prop++); +var_dump($obj->prop); +var_dump(--$obj->prop); +var_dump($obj->prop); +var_dump($obj->prop--); +var_dump($obj->prop); + +?> +--EXPECT-- +int(2) +int(2) +int(2) +int(3) +int(2) +int(2) +int(2) +int(1) diff --git a/tests/zend/in-de-crement/increment_001_64bit.phpt b/tests/zend/in-de-crement/increment_001_64bit.phpt new file mode 100644 index 00000000..333bbcd4 --- /dev/null +++ b/tests/zend/in-de-crement/increment_001_64bit.phpt @@ -0,0 +1,24 @@ +--TEST-- +Incrementing max int values 64bit +--SKIPIF-- + +--INI-- +precision=14 +--FILE-- + +--EXPECT-- +float(9.223372036854776E+18) +float(9.223372036854776E+18) +Done diff --git a/tests/zend/in-de-crement/post_inc_without_use.phpt b/tests/zend/in-de-crement/post_inc_without_use.phpt new file mode 100644 index 00000000..39a7e94a --- /dev/null +++ b/tests/zend/in-de-crement/post_inc_without_use.phpt @@ -0,0 +1,12 @@ +--TEST-- +POST_INC without use during DFA optimization +--FILE-- + +--EXPECT--