diff --git a/phpunit/code/void-method-call.php b/phpunit/code/void-method-call.php new file mode 100644 index 00000000..b02158b0 --- /dev/null +++ b/phpunit/code/void-method-call.php @@ -0,0 +1,9 @@ +toString()); +} diff --git a/phpunit/src/UniversalMethodCallTest.php b/phpunit/src/UniversalMethodCallTest.php index 71016eb1..b1e69007 100644 --- a/phpunit/src/UniversalMethodCallTest.php +++ b/phpunit/src/UniversalMethodCallTest.php @@ -16,4 +16,9 @@ class UniversalMethodCallTest extends \BaseTest { $this->exec('Cannot call mutating method `push()` on a non-variable expression', 'universal-method-mutating-expr.php'); } + + public function testVoidMethodCall() + { + $this->exec('Cannot call method on void', 'void-method-call.php'); + } } diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 13a3e17c..da9c7d26 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -5438,6 +5438,9 @@ class CompilerBase extends \PhpAot\Core\Translator } else { $receiverType = $this->detectTypeOfExpr($expr->var); } + if ($receiverType === self::TYPE_VOID) { + $this->fatalError($expr->var, 'Cannot call method on void'); + } if ($methodName === 'toObject') { return $this->genToObjectCall($expr, $object); } @@ -5479,6 +5482,9 @@ class CompilerBase extends \PhpAot\Core\Translator // 表达式返回值也可使用内置方法:fn()->method(), $obj->fn()->method(), Foo::fn()->method(), $obj->prop->method() if (!$this->isVarExpr($expr->var) and $this->isNamedMethod($expr->name)) { $type = $this->detectTypeOfExpr($expr->var); + if ($type === self::TYPE_VOID) { + $this->fatalError($expr->var, 'Cannot call method on void'); + } if ($type !== self::TYPE_VAR && !$this->checkArgType($type, self::TYPE_OBJECT)) { $methodName = $expr->name->toString(); $fn = $this->findUniversalMethodAnyType($type, $methodName);