From 60ba3da4049308a3033d0d297374eb52e310b4b1 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 9 Feb 2026 16:02:42 +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=E6=9C=AA=E5=AE=9A=E4=B9=89=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E6=A3=80=E6=9F=A5=E5=92=8C=E5=BC=95=E7=94=A8=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构引用参数处理逻辑,统一处理未定义变量作为引用的情况 - 添加对属性访问和数组索引操作中未定义变量的检查 - 修复临时变量创建和替换逻辑,确保引用类型参数正确传递 - 修改未定义变量错误报告机制,增强编译时错误检测 - 优化变量引用转换流程,提高代码生成的准确性 --- src/Php/CompilerBase.php | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 97ec5f7a..60c4beee 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1905,31 +1905,42 @@ class CompilerBase extends \PhpAot\Core\Translator } if ($this->isVarExpr($arg->value)) { $name = $this->parseIdentifier($arg->value); - // 调用了不存在的变量,可能是引用 - if (!$this->hasVar($name)) { - $this->addLocalVar($name, self::TYPE_REF); - $this->beforeStmtLines[] = $name . ' = php::newReference();'; - } elseif ($funcName and Reflection::isReferenceArg($funcName, $i)) { - // 需要引用类型的参数,使用临时变量作为引用,并替换掉实际的参数 - $tmpVar = $this->genTmpVarName(); - $this->addLocalVar($tmpVar, self::TYPE_REF); - $this->beforeStmtLines[] = $tmpVar . ' = ' . $this->parseExpr($arg->value) . '.toReference();'; - $list_args[] = '&' . $tmpVar; + if ($funcName and Reflection::isReferenceArg($funcName, $i)) { + if (!$this->hasVar($name)) { + // 若参数是引用类型,可以传入未定义变量,将立即创建变量作为引用 + $this->addLocalVar($name, self::TYPE_REF); + } else { + // 需要引用类型的参数,使用临时变量作为引用,并替换掉实际的参数 + $tmpVar = $this->genTmpVarName(); + $this->addLocalVar($tmpVar, self::TYPE_REF); + $name = $tmpVar; + } + $this->beforeStmtLines[] = $name . ' = ' . $this->parseExpr($arg->value) . '.toReference();'; + $list_args[] = '&' . $name; continue; } + if (!$this->hasVar($name)) { + $this->fatalError($arg, 'Undefined variable `$' . $name . '`'); + } } elseif ($this->isPropertyFetch($arg->value)) { + $obj = $this->parseIdentifier($arg->value->var); + if (!$this->hasVar($obj)) { + $this->fatalError($arg, 'Undefined variable `$' . $obj . '`'); + } if ($funcName and Reflection::isReferenceArg($funcName, $i)) { - $obj = $this->parseIdentifier($arg->value->var); $list_args[] = $obj . '.attrRef(' . $this->identifierToStr($arg->value->name) . ')'; continue; } } elseif ($this->isArrayDimFetch($arg->value)) { + $array = $this->parseIdentifier($arg->value->var); + if (!$this->hasVar($array)) { + $this->fatalError($arg, 'Undefined variable `$' . $array . '`'); + } if ($funcName and Reflection::isReferenceArg($funcName, $i)) { - $obj = $this->parseIdentifier($arg->value->var); if ($arg->value->dim === null) { $this->fatalError($arg, 'Array dimension must be a constant expression'); } - $list_args[] = $obj . '.itemRef(' . $this->identifierToStr($arg->value->dim) . ')'; + $list_args[] = $array . '.itemRef(' . $this->identifierToStr($arg->value->dim) . ')'; continue; } }