Merge pull request 'fix(compiler): 修复unset引用变量后对变量的操作' (#14) from fix-unset-ref-coalesce into master

Reviewed-on: #14
pull/15/head
韩天峰 2 months ago
commit 035b1b09d7
  1. 4
      src/Php/CompilerBase.php
  2. 96
      tests/aot/coalesce/unset-ref-coalesce.phpt

@ -5977,8 +5977,12 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont
$fn = $this->getChainedFunc($op);
$expr = $node;
if ($this->isVarExpr($expr)) {
if (!$getValue) {
return $fn . '(' . $this->parseExpr($expr) . ')';
}
// $getValue is true: fall through to use the chain+result mechanism,
// which ensures the result type is TYPE_VAR (compatible with ternaries).
}
// 单属性读取(非链式)
if ($this->isPropertyFetch($expr) and $this->isVarExpr($expr->var) and $this->isIdExpr($expr->name)) {
$prop = $this->parsePropertyFetch($expr);

@ -0,0 +1,96 @@
--TEST--
Null coalescing (??) on unset reference variable
--FILE--
<?php
function main()
{
// Test 1: unset reference variable then ?? with int
$a = 1;
$b = &$a;
$b = 2;
var_dump($a, $b);
unset($b);
var_dump($a);
var_dump(isset($b));
var_dump($b ?? 123);
// Test 2: unset reference variable then ?? with string
$c = 'hello';
$d = &$c;
$d = 'world';
var_dump($c, $d);
unset($d);
var_dump($c);
var_dump(isset($d));
var_dump($d ?? 'default');
// Test 3: ?? on reference without unset (should return value)
$e = 42;
$f = &$e;
var_dump($f ?? 999);
// Test 4: chained ?? with unset reference
$g = 'first';
$h = &$g;
unset($h);
var_dump($h ?? null ?? 'fallback');
// Test 5: ??= on unset reference (assign coalesce)
$i = 10;
$j = &$i;
$j = 20;
unset($j);
$j ??= 30;
var_dump($j);
var_dump($i);
// Test 6: reference reassignment after unset
$k = 100;
$l = &$k;
unset($l);
var_dump($l ?? 200);
$l = 300;
var_dump($l);
var_dump($k);
// Test 7: normal variable unset + ??
$m = 50;
unset($m);
var_dump($m ?? 777);
// Test 8: isset after unset of reference
$n = 'test';
$o = &$n;
unset($o);
var_dump(isset($o));
// Test 9: elvis (?:) on unset reference
$p = 5;
$q = &$p;
$q = 6;
unset($q);
var_dump($q ?: -1);
}
?>
--EXPECT--
int(2)
int(2)
int(2)
bool(false)
int(123)
string(5) "world"
string(5) "world"
string(5) "world"
bool(false)
string(7) "default"
int(42)
string(8) "fallback"
int(30)
int(20)
int(200)
int(300)
int(100)
int(777)
bool(false)
int(-1)
Loading…
Cancel
Save