From: Nikita Popov Date: Fri, 24 May 2019 07:33:58 +0000 (+0200) Subject: Merge branch 'PHP-7.4' X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e06ec226bc661acbf4d705e5bf02a11690b31baa;p=php Merge branch 'PHP-7.4' --- e06ec226bc661acbf4d705e5bf02a11690b31baa diff --cc Zend/zend_inheritance.c index e4292b3484,36d765386d..dc26d115de --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@@ -510,6 -605,24 +605,24 @@@ static zend_always_inline uint32_t func return fn->common.type == ZEND_USER_FUNCTION ? fn->op_array.line_start : 0; } + static void ZEND_COLD emit_incompatible_method_error( - int error_level, const char *error_verb, zend_function *child, zend_function *parent, ++ zend_function *child, zend_function *parent, + inheritance_status status, zend_string *unresolved_class) { + zend_string *parent_prototype = zend_get_function_declaration(parent); + zend_string *child_prototype = zend_get_function_declaration(child); + if (status == INHERITANCE_UNRESOLVED) { - zend_error_at(error_level, NULL, func_lineno(child), ++ zend_error_at(E_COMPILE_ERROR, NULL, func_lineno(child), + "Could not check compatibility between %s and %s, because class %s is not available", + ZSTR_VAL(child_prototype), ZSTR_VAL(parent_prototype), ZSTR_VAL(unresolved_class)); + } else { - zend_error_at(error_level, NULL, func_lineno(child), - "Declaration of %s %s be compatible with %s", - ZSTR_VAL(child_prototype), error_verb, ZSTR_VAL(parent_prototype)); ++ zend_error_at(E_COMPILE_ERROR, NULL, func_lineno(child), ++ "Declaration of %s must be compatible with %s", ++ ZSTR_VAL(child_prototype), ZSTR_VAL(parent_prototype)); + } + zend_string_efree(child_prototype); + zend_string_efree(parent_prototype); + } + static void do_inheritance_check_on_method(zend_function *child, zend_function *parent, zend_class_entry *ce, zval *child_zv) /* {{{ */ { uint32_t child_flags; @@@ -592,14 -707,26 +707,9 @@@ 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"); } - if (UNEXPECTED(!zend_do_perform_implementation_check(child, parent))) { - zend_string *method_prototype = zend_get_function_declaration(parent); - zend_string *child_prototype = zend_get_function_declaration(child); - zend_error_at(E_COMPILE_ERROR, NULL, func_lineno(child), - "Declaration of %s must be compatible with %s", - ZSTR_VAL(child_prototype), ZSTR_VAL(method_prototype)); - zend_string_efree(child_prototype); - zend_string_efree(method_prototype); + status = zend_do_perform_implementation_check(&unresolved_class, child, parent); - if (UNEXPECTED(status != INHERITANCE_SUCCESS)) { - int error_level; - const char *error_verb; - if (child->common.prototype && ( - child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT - )) { - error_level = E_COMPILE_ERROR; - error_verb = "must"; - } else if ((parent->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) && - (!(child->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_perform_covariant_type_check(&unresolved_class, child, child->common.arg_info - 1, parent, parent->common.arg_info - 1) != INHERITANCE_SUCCESS)) { - error_level = E_COMPILE_ERROR; - error_verb = "must"; - } else { - error_level = E_WARNING; - error_verb = "should"; - } - emit_incompatible_method_error( - error_level, error_verb, child, parent, status, unresolved_class); ++ if (status != INHERITANCE_SUCCESS) { ++ emit_incompatible_method_error(child, parent, status, unresolved_class); } } } while (0); @@@ -1311,18 -1454,20 +1423,20 @@@ static void zend_add_trait_method(zend_ if ((existing_fn = zend_hash_find_ptr(*overridden, key)) != NULL) { if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT) { /* Make sure the trait method is compatible with previosly declared abstract method */ - if (UNEXPECTED(!zend_do_perform_implementation_check(fn, existing_fn))) { - zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", - ZSTR_VAL(zend_get_function_declaration(fn)), - ZSTR_VAL(zend_get_function_declaration(existing_fn))); + status = zend_do_perform_implementation_check( + &unresolved_class, fn, existing_fn); + if (status != INHERITANCE_SUCCESS) { + emit_incompatible_method_error( - E_COMPILE_ERROR, "must", fn, existing_fn, status, unresolved_class); ++ fn, existing_fn, status, unresolved_class); } } if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) { /* Make sure the abstract declaration is compatible with previous declaration */ - if (UNEXPECTED(!zend_do_perform_implementation_check(existing_fn, fn))) { - zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", - ZSTR_VAL(zend_get_function_declaration(existing_fn)), - ZSTR_VAL(zend_get_function_declaration(fn))); + status = zend_do_perform_implementation_check( + &unresolved_class, existing_fn, fn); + if (status != INHERITANCE_SUCCESS) { + emit_incompatible_method_error( - E_COMPILE_ERROR, "must", existing_fn, fn, status, unresolved_class); ++ existing_fn, fn, status, unresolved_class); } return; } @@@ -1336,17 -1481,17 +1450,15 @@@ } else if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT && (existing_fn->common.scope->ce_flags & ZEND_ACC_INTERFACE) == 0) { /* Make sure the trait method is compatible with previosly declared abstract method */ - if (UNEXPECTED(!zend_do_perform_implementation_check(fn, existing_fn))) { - zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", - ZSTR_VAL(zend_get_function_declaration(fn)), - ZSTR_VAL(zend_get_function_declaration(existing_fn))); + status = zend_do_perform_implementation_check(&unresolved_class, fn, existing_fn); + if (status != INHERITANCE_SUCCESS) { - emit_incompatible_method_error( - E_COMPILE_ERROR, "must", fn, existing_fn, status, unresolved_class); ++ emit_incompatible_method_error(fn, existing_fn, status, unresolved_class); } } else if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) { /* Make sure the abstract declaration is compatible with previous declaration */ - if (UNEXPECTED(!zend_do_perform_implementation_check(existing_fn, fn))) { - zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", - ZSTR_VAL(zend_get_function_declaration(existing_fn)), - ZSTR_VAL(zend_get_function_declaration(fn))); + status = zend_do_perform_implementation_check(&unresolved_class, existing_fn, fn); + if (status != INHERITANCE_SUCCESS) { - emit_incompatible_method_error( - E_COMPILE_ERROR, "must", existing_fn, fn, status, unresolved_class); ++ emit_incompatible_method_error(existing_fn, fn, status, unresolved_class); } return; } else if (UNEXPECTED(existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT)) { diff --cc Zend/zend_inheritance.h index eb68a6d278,a35a4c6638..cba8efe50b --- a/Zend/zend_inheritance.h +++ b/Zend/zend_inheritance.h @@@ -30,7 -30,9 +30,8 @@@ ZEND_API void zend_do_inheritance(zend_ ZEND_API void zend_do_link_class(zend_class_entry *ce, zend_class_entry *parent_ce); void zend_verify_abstract_class(zend_class_entry *ce); -void zend_check_deprecated_constructor(const zend_class_entry *ce); void zend_build_properties_info_table(zend_class_entry *ce); + zend_bool zend_can_early_bind(zend_class_entry *ce, zend_class_entry *parent_ce); END_EXTERN_C()