class One {
const Baz = parent::class;
}
+ var_dump(One::Baz);
}
?>
--EXPECTF--
-Fatal error: parent::class cannot be used for compile-time class name resolution in %s on line %d
+Fatal error: Uncaught Error: Cannot use "parent" when current class scope has no parent in %s:%d
+Stack trace:
+#0 {main}
+ thrown in %s on line %d
<?php
namespace Foo\Bar {
- class One {
- public function baz($x = parent::class) {}
+ class One {}
+ class Two extends One {
+ public function baz($x = parent::class) {
+ var_dump($x);
+ }
}
+ (new Two)->baz();
}
?>
---EXPECTF--
-Fatal error: parent::class cannot be used for compile-time class name resolution in %s on line %d
+--EXPECT--
+string(11) "Foo\Bar\One"
break;
}
case ZEND_AST_CONSTANT_CLASS:
- if (scope && scope->name) {
+ if (scope) {
ZVAL_STR_COPY(result, scope->name);
} else {
ZVAL_EMPTY_STRING(result);
}
break;
case ZEND_AST_CLASS_NAME:
- ZEND_ASSERT(ast->attr == ZEND_FETCH_CLASS_SELF);
- if (scope && scope->name) {
+ if (!scope) {
+ zend_throw_error(NULL, "Cannot use \"self\" when no class scope is active");
+ return FAILURE;
+ }
+ if (ast->attr == ZEND_FETCH_CLASS_SELF) {
ZVAL_STR_COPY(result, scope->name);
+ } else if (ast->attr == ZEND_FETCH_CLASS_PARENT) {
+ if (!scope->parent) {
+ zend_throw_error(NULL,
+ "Cannot use \"parent\" when current class scope has no parent");
+ return FAILURE;
+ }
+ ZVAL_STR_COPY(result, scope->parent->name);
} else {
- zend_throw_error(NULL, "Cannot use \"self\" when no class scope is active");
- ret = FAILURE;
+ ZEND_ASSERT(0 && "Should have errored during compilation");
}
break;
case ZEND_AST_AND:
zend_string *class_name = zend_ast_get_str(class_ast);
uint32_t fetch_type = zend_get_class_fetch_type(class_name);
- /* For the const-eval representation store the fetch type instead of the name. */
- if (fetch_type == ZEND_FETCH_CLASS_SELF) {
- zend_string_release(class_name);
- ast->child[0] = NULL;
- ast->attr = fetch_type;
- return;
+ switch (fetch_type) {
+ case ZEND_FETCH_CLASS_SELF:
+ case ZEND_FETCH_CLASS_PARENT:
+ /* For the const-eval representation store the fetch type instead of the name. */
+ zend_string_release(class_name);
+ ast->child[0] = NULL;
+ ast->attr = fetch_type;
+ return;
+ case ZEND_FETCH_CLASS_STATIC:
+ zend_error_noreturn(E_COMPILE_ERROR,
+ "static::class cannot be used for compile-time class name resolution");
+ return;
+ EMPTY_SWITCH_DEFAULT_CASE()
}
-
- zend_error_noreturn(E_COMPILE_ERROR,
- "%s::class cannot be used for compile-time class name resolution",
- fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
- );
}
void zend_compile_const_expr_const(zend_ast **ast_ptr) /* {{{ */