test(compiler): strengthen undefined coalesce assignment coverage

pull/20/head
韩天峰 1 month ago
parent 0da07cb065
commit 8b76f841ad
  1. 15
      src/Parser/AssignOpTrait.php
  2. 14
      tests/compiler/coalesce/assign-coalesce-undefined-var.phpt

@ -863,19 +863,16 @@ trait AssignOpTrait
{
$this->checkLeftValue($expr->var);
// PHP 允许对未定义的简单变量使用 ??=(例如 `$a ??= 123`):
// 此时 isset 为 false,直接执行赋值。需要提前声明该局部变量,
// 否则 isset 检查会因变量未定义而报错。此处必须声明为 Type::VAR
// (Variant),使其初值为 NULL,从而 isset 在运行时正确判定为
// false 并执行赋值;若使用原生类型,isset 恒为 true 会导致取到
// 未初始化的默认值(如 int(0)、空字符串)。
if ($this->isVarExpr($expr->var) and !$this->hasVar($this->parseIdentifier($expr->var))) {
$this->addLocalVar($this->parseIdentifier($expr->var), Type::VAR);
// An undefined variable must exist before generating its isset check.
// Keep it as Variant so NULL remains distinguishable from native defaults.
$var = $this->isVarExpr($expr->var) ? $this->parseIdentifier($expr->var) : null;
if ($var !== null && !$this->hasVar($var)) {
$this->addLocalVar($var, Type::VAR);
}
$isset = $this->parseChainedExpr($expr->var, self::OP_ISSET);
$var = $this->parseWritableIdentifier($expr->var);
$var ??= $this->parseWritableIdentifier($expr->var);
$propertyWriteTarget = $this->preparePropertyWriteTarget($expr->var);
if ($propertyWriteTarget !== null) {

@ -8,7 +8,21 @@ var_dump($a);
$b ??= 'foo';
$b ??= 'bar';
var_dump($b);
$c ??= null;
var_dump(isset($c));
$c ??= 'after-null';
var_dump($c);
for ($i = 0; $i < 2; $i++) {
$d ??= printf("default\n");
}
var_dump($d);
?>
--EXPECT--
int(123)
string(3) "foo"
bool(false)
string(10) "after-null"
default
int(8)

Loading…
Cancel
Save