diff --git a/phpunit/code/base-class-method.php b/phpunit/code/base-class-method.php new file mode 100644 index 00000000..e5c17d7b --- /dev/null +++ b/phpunit/code/base-class-method.php @@ -0,0 +1,29 @@ +bar(); + } +} + +class FooChild extends FooBase { + function bar() + { + var_dump(__CLASS__); + } +} + +function bar(FooBase $o) +{ + $o->doSomething(); +} + +function main() { + $o = new FooChild(); + $o2 = any($o); + bar($o2); +} diff --git a/phpunit/src/UndefineTest.php b/phpunit/src/UndefineTest.php index aad5de6f..3924ec4b 100644 --- a/phpunit/src/UndefineTest.php +++ b/phpunit/src/UndefineTest.php @@ -17,4 +17,14 @@ class UndefineTest extends \BaseTest { $this->exec('Attempt to unset static property', 'unset-static-prop.php'); } + + public function testPropertyAccessOnUndefinedVar(): void + { + $this->exec('The variable `$obj` is undefined', 'undefined-prop-access.php'); + } + + public function testMethodCallOnUndefinedVar(): void + { + $this->exec('The variable `$obj` is undefined', 'undefined-method-call.php'); + } } \ No newline at end of file diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 0607cabb..7ca938d4 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -3975,7 +3975,11 @@ class CompilerBase extends \PhpAot\Core\Translator $object = $expr->var; $property = $expr->name; $id = $this->getPropertyIdentifier($expr, $object, $property); - $objectVar = $this->parseIdentifier($object); + $objectName = $this->parseIdentifier($object); + if ($this->isVarExpr($object) and !$this->hasVar($objectName)) { + $this->errorUndefinedVariable($object); + } + $objectVar = $objectName; $getProperty = $objectVar . '.attr(' . $id . ', ' . $this->escapeBool($update) . ')'; if ($expr->hasAttribute('nativePropertyDef') and $this->nativeTypes) { /** diff --git a/src/gen_stub.php b/src/gen_stub.php index cae09295..d6c1c4c7 100755 --- a/src/gen_stub.php +++ b/src/gen_stub.php @@ -3781,6 +3781,11 @@ class ClassInfo { $code .= $php80CondEnd; } + $code .= "\n\tstatic zend_object_handlers class_object_handlers;"; + $code .= "\n\tphp_aot_init_object_handlers(&class_object_handlers);"; + $code .= "\n\tclass_entry->default_object_handlers = &class_object_handlers;"; + $code .= "\n"; + $code .= "\n\treturn class_entry;\n"; $code .= "}\n"; diff --git a/tests/aot/class/unset-int-prop.phpt b/tests/aot/class/unset-int-prop.phpt new file mode 100644 index 00000000..4bf5b4ea --- /dev/null +++ b/tests/aot/class/unset-int-prop.phpt @@ -0,0 +1,28 @@ +--TEST-- +unset typed property via dynamic code +--FILE-- +value += 1; + var_dump($base->value); + + eval('function test(FooObject $obj) { + unset($obj->value); + }'); + + test($base); + var_dump($base->value); + + echo "done\n"; +} +?> +--EXPECT-- +int(43) +int(0) +done \ No newline at end of file