ZEND_FN_SCOPE_NAME(child), ZSTR_VAL(child->common.function_name), zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker");
}
- perform_delayable_implementation_check(ce, child, parent);
+ if (!checked) {
+ if (check_only) {
+ zend_string *unresolved_class;
+
+ return zend_do_perform_implementation_check(
+ &unresolved_class, child, parent);
+ }
- perform_delayable_implementation_check(
- ce, child, parent, /*always_error*/0);
++ perform_delayable_implementation_check(ce, child, parent);
+ }
+ return INHERITANCE_SUCCESS;
+ }
+ /* }}} */
+
+ static void do_inheritance_check_on_method(zend_function *child, zend_function *parent, zend_class_entry *ce, zval *child_zv) /* {{{ */
+ {
+ do_inheritance_check_on_method_ex(child, parent, ce, child_zv, 0, 0);
}
/* }}} */
}
}
}
+ /* }}} */
/* Check whether early binding is prevented due to unresolved types in inheritance checks. */
- zend_bool zend_can_early_bind(zend_class_entry *ce, zend_class_entry *parent_ce) {
+ static inheritance_status zend_can_early_bind(zend_class_entry *ce, zend_class_entry *parent_ce) /* {{{ */
+ {
- inheritance_status ret = INHERITANCE_SUCCESS;
zend_string *key;
zend_function *parent_func;
- ZEND_HASH_FOREACH_STR_KEY_PTR(&parent_ce->function_table, key, parent_func) {
- uint32_t parent_flags = parent_func->common.fn_flags;
- zval *zv;
- zend_string *unresolved_class;
- if (parent_flags & ZEND_ACC_PRIVATE) {
- continue;
- } else if (parent_flags & ZEND_ACC_CTOR) {
- zend_function *proto = parent_func->common.prototype ?
- parent_func->common.prototype : parent_func;
+ ZEND_HASH_FOREACH_STR_KEY_PTR(&parent_ce->function_table, key, parent_func) {
+ zval *zv = zend_hash_find_ex(&ce->function_table, key, 1);
+ if (zv) {
+ zend_function *child_func = Z_FUNC_P(zv);
+ inheritance_status status =
+ do_inheritance_check_on_method_ex(child_func, parent_func, ce, NULL, 1, 0);
- /* ctors only have a prototype if is abstract (or comes from an interface) */
- /* and if that is the case, we want to check inheritance against it */
- if (!(proto->common.fn_flags & ZEND_ACC_ABSTRACT)) {
- continue;
+ if (UNEXPECTED(status != INHERITANCE_SUCCESS)) {
- if (EXPECTED(status == INHERITANCE_UNRESOLVED)) {
- return INHERITANCE_UNRESOLVED;
- }
- ZEND_ASSERT(status == INHERITANCE_ERROR);
- ret = INHERITANCE_ERROR;
++ return status;
}
- parent_func = proto;
}
+ } ZEND_HASH_FOREACH_END();
- zv = zend_hash_find_ex(&ce->function_table, key, 1);
- if (zv) {
- zend_function *child_func = Z_FUNC_P(zv);
- inheritance_status status;
- return ret;
++ return INHERITANCE_SUCCESS;
+ }
+ /* }}} */
- status = zend_do_perform_implementation_check(
- &unresolved_class, child_func, parent_func);
+ zend_bool zend_try_early_bind(zend_class_entry *ce, zend_class_entry *parent_ce, zend_string *lcname, zval *delayed_early_binding) /* {{{ */
+ {
+ inheritance_status status = zend_can_early_bind(ce, parent_ce);
- if (UNEXPECTED(status == INHERITANCE_UNRESOLVED)) {
+ if (EXPECTED(status != INHERITANCE_UNRESOLVED)) {
+ if (delayed_early_binding) {
+ if (UNEXPECTED(zend_hash_set_bucket_key(EG(class_table), (Bucket*)delayed_early_binding, lcname) == NULL)) {
+ zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name));
+ return 0;
+ }
+ } else {
+ if (UNEXPECTED(zend_hash_add_ptr(CG(class_table), lcname, ce) == NULL)) {
return 0;
}
}