- 实现了对匿名类和嵌入类方法的混合返回类型自动推断 - 添加了魔术方法返回类型敏感性检测逻辑 - 集成了祖先类方法返回类型的递归检查机制 - 扩展了类继承链中的返回类型声明分析功能 - 优化了内部类和接口方法返回类型的反射检测 - 新增了类方法返回类型未声明时的混合类型注入逻辑 fix(optimizer): 修复对象属性提升优化中的引用槽位安全检测 - 修正了对象暴露给动态代码时的属性引用安全检查机制 - 更新了方法调用和函数调用的安全性判断逻辑 - 重构了对象参数传递时的危险操作检测算法 - 添加了pull/3/head
parent
4acb632c13
commit
602e8b34ee
6 changed files with 283 additions and 26 deletions
@ -0,0 +1,21 @@ |
|||||||
|
--TEST-- |
||||||
|
Anonymous Classes - magic methods keep undeclared return semantics |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
function main() { |
||||||
|
$obj = new class { |
||||||
|
public int $value = 0; |
||||||
|
|
||||||
|
public function __set($name, $value) { |
||||||
|
$this->value = $value; |
||||||
|
return 1; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
$obj->dynamic = 2; |
||||||
|
var_dump($obj->value); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
int(2) |
||||||
@ -0,0 +1,56 @@ |
|||||||
|
--TEST-- |
||||||
|
unset typed property preserves existing property reference |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
class UnsetRefProp { |
||||||
|
public int $value = 42; |
||||||
|
public string $name = "abc"; |
||||||
|
public array $items = [1, 2]; |
||||||
|
} |
||||||
|
|
||||||
|
function main() { |
||||||
|
eval('function unset_value(UnsetRefProp $obj) { unset($obj->value); }'); |
||||||
|
eval('function unset_name(UnsetRefProp $obj) { unset($obj->name); }'); |
||||||
|
eval('function unset_items(UnsetRefProp $obj) { unset($obj->items); }'); |
||||||
|
|
||||||
|
$obj = new UnsetRefProp(); |
||||||
|
|
||||||
|
$valueRef =& $obj->value; |
||||||
|
$valueRef = 7; |
||||||
|
unset_value($obj); |
||||||
|
var_dump($obj->value); |
||||||
|
var_dump($valueRef); |
||||||
|
$valueRef = 9; |
||||||
|
var_dump($obj->value); |
||||||
|
|
||||||
|
$nameRef =& $obj->name; |
||||||
|
unset_name($obj); |
||||||
|
var_dump($obj->name); |
||||||
|
var_dump($nameRef); |
||||||
|
$nameRef = "changed"; |
||||||
|
var_dump($obj->name); |
||||||
|
|
||||||
|
$itemsRef =& $obj->items; |
||||||
|
unset_items($obj); |
||||||
|
var_dump($obj->items); |
||||||
|
var_dump($itemsRef); |
||||||
|
$itemsRef[] = 3; |
||||||
|
var_dump($obj->items); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
int(0) |
||||||
|
int(0) |
||||||
|
int(9) |
||||||
|
string(0) "" |
||||||
|
string(0) "" |
||||||
|
string(7) "changed" |
||||||
|
array(0) { |
||||||
|
} |
||||||
|
array(0) { |
||||||
|
} |
||||||
|
array(1) { |
||||||
|
[0]=> |
||||||
|
int(3) |
||||||
|
} |
||||||
@ -0,0 +1,29 @@ |
|||||||
|
--TEST-- |
||||||
|
SSA object prop: object argument can turn property slot into reference |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
use native_types; |
||||||
|
|
||||||
|
class RefSlotFoo { |
||||||
|
public int $a; |
||||||
|
} |
||||||
|
|
||||||
|
function bind_ref(RefSlotFoo $o): void { |
||||||
|
$ref =& $o->a; |
||||||
|
$ref = 99; |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void { |
||||||
|
$o = new RefSlotFoo(); |
||||||
|
$o->a = 1; |
||||||
|
|
||||||
|
bind_ref($o); |
||||||
|
var_dump($o->a); |
||||||
|
$o->a += 1; |
||||||
|
|
||||||
|
var_dump($o->a); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
int(99) |
||||||
|
int(100) |
||||||
Loading…
Reference in new issue