diff options
Diffstat (limited to 'Zend/zend_inheritance.c')
-rw-r--r-- | Zend/zend_inheritance.c | 124 |
1 files changed, 24 insertions, 100 deletions
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index ba1612c189..cda838d837 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -28,8 +28,7 @@ static void add_dependency_obligation(zend_class_entry *ce, zend_class_entry *dependency_ce); static void add_compatibility_obligation( - zend_class_entry *ce, const zend_function *child_fn, const zend_function *parent_fn, - zend_bool always_error); + zend_class_entry *ce, const zend_function *child_fn, const zend_function *parent_fn); static void overridden_ptr_dtor(zval *zv) /* {{{ */ { @@ -491,11 +490,10 @@ static inheritance_status zend_do_perform_implementation_check( static inheritance_status perform_delayable_implementation_check( zend_string **unresolved_class, zend_class_entry *ce, - const zend_function *fe, const zend_function *proto, zend_bool always_error) { - inheritance_status status = zend_do_perform_implementation_check( - unresolved_class, fe, proto); + const zend_function *fe, const zend_function *proto) { + inheritance_status status = zend_do_perform_implementation_check(unresolved_class, fe, proto); if (status == INHERITANCE_UNRESOLVED) { - add_compatibility_obligation(ce, fe, proto, always_error); + add_compatibility_obligation(ce, fe, proto); } return status; } @@ -666,46 +664,23 @@ static zend_always_inline uint32_t func_lineno(const zend_function *fn) { } static void ZEND_COLD emit_incompatible_method_error( - int error_level, const char *error_verb, const zend_function *child, const 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 ZEND_COLD emit_incompatible_method_error_or_warning( - const zend_function *child, const zend_function *parent, - inheritance_status status, zend_string *unresolved_class, zend_bool always_error) { - int error_level; - const char *error_verb; - if (always_error || - (child->common.prototype && - (child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT)) || - ((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); -} - static void do_inheritance_check_on_method(zend_function *child, zend_function *parent, zend_class_entry *ce, zval *child_zv) /* {{{ */ { uint32_t child_flags; @@ -790,11 +765,9 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * 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"); } - status = perform_delayable_implementation_check( - &unresolved_class, ce, child, parent, /*always_error*/0); + status = perform_delayable_implementation_check(&unresolved_class, ce, child, parent); if (status == INHERITANCE_ERROR) { - emit_incompatible_method_error_or_warning( - child, parent, status, unresolved_class, /*always_error*/0); + emit_incompatible_method_error(child, parent, status, unresolved_class); } } } while (0); @@ -1457,14 +1430,11 @@ static void zend_add_magic_methods(zend_class_entry* ce, zend_string* mname, zen ce->serialize_func = fe; } else if (zend_string_equals_literal(mname, "unserialize")) { ce->unserialize_func = fe; - } else if (ZSTR_LEN(ce->name) != ZSTR_LEN(mname) && (ZSTR_VAL(mname)[0] != '_' || ZSTR_VAL(mname)[1] != '_')) { + } else if (ZSTR_VAL(mname)[0] != '_' || ZSTR_VAL(mname)[1] != '_') { /* pass */ } else if (zend_string_equals_literal(mname, ZEND_CLONE_FUNC_NAME)) { ce->clone = fe; } else if (zend_string_equals_literal(mname, ZEND_CONSTRUCTOR_FUNC_NAME)) { - if (ce->constructor && (!ce->parent || ce->constructor != ce->parent->constructor)) { - zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ZSTR_VAL(ce->name)); - } ce->constructor = fe; } else if (zend_string_equals_literal(mname, ZEND_DESTRUCTOR_FUNC_NAME)) { ce->destructor = fe; @@ -1488,17 +1458,6 @@ static void zend_add_magic_methods(zend_class_entry* ce, zend_string* mname, zen ce->__tostring = fe; } else if (zend_string_equals_literal(mname, ZEND_DEBUGINFO_FUNC_NAME)) { ce->__debugInfo = fe; - } else if (ZSTR_LEN(ce->name) == ZSTR_LEN(mname)) { - zend_string *lowercase_name = zend_string_tolower(ce->name); - lowercase_name = zend_new_interned_string(lowercase_name); - if (!memcmp(ZSTR_VAL(mname), ZSTR_VAL(lowercase_name), ZSTR_LEN(mname))) { - if (ce->constructor && (!ce->parent || ce->constructor != ce->parent->constructor)) { - zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ZSTR_VAL(ce->name)); - } - ce->constructor = fe; - fe->common.fn_flags |= ZEND_ACC_CTOR; - } - zend_string_release_ex(lowercase_name, 0); } } /* }}} */ @@ -1527,19 +1486,19 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT) { /* Make sure the trait method is compatible with previosly declared abstract method */ status = perform_delayable_implementation_check( - &unresolved_class, ce, fn, existing_fn, /*always_error*/ 1); + &unresolved_class, ce, fn, existing_fn); if (status == INHERITANCE_ERROR) { 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 */ status = perform_delayable_implementation_check( - &unresolved_class, ce, existing_fn, fn, /*always_error*/ 1); + &unresolved_class, ce, existing_fn, fn); if (status == INHERITANCE_ERROR) { emit_incompatible_method_error( - E_COMPILE_ERROR, "must", existing_fn, fn, status, unresolved_class); + existing_fn, fn, status, unresolved_class); } return; } @@ -1553,19 +1512,15 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s } 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 */ - status = perform_delayable_implementation_check( - &unresolved_class, ce, fn, existing_fn, /*always_error*/ 1); + status = perform_delayable_implementation_check(&unresolved_class, ce, fn, existing_fn); if (status == INHERITANCE_ERROR) { - 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 */ - status = perform_delayable_implementation_check( - &unresolved_class, ce, existing_fn, fn, /*always_error*/ 1); + status = perform_delayable_implementation_check(&unresolved_class, ce, existing_fn, fn); if (status == INHERITANCE_ERROR) { - 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)) { @@ -2114,32 +2069,6 @@ static void zend_do_bind_traits(zend_class_entry *ce) /* {{{ */ zend_do_traits_property_binding(ce, traits); efree(traits); - - /* Emit E_DEPRECATED for PHP 4 constructors */ - zend_check_deprecated_constructor(ce); -} -/* }}} */ - - -static zend_bool zend_has_deprecated_constructor(const zend_class_entry *ce) /* {{{ */ -{ - const zend_string *constructor_name; - if (!ce->constructor) { - return 0; - } - constructor_name = ce->constructor->common.function_name; - return !zend_binary_strcasecmp( - ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), - ZSTR_VAL(constructor_name), ZSTR_LEN(constructor_name) - ); -} -/* }}} */ - -void zend_check_deprecated_constructor(const zend_class_entry *ce) /* {{{ */ -{ - if (zend_has_deprecated_constructor(ce)) { - zend_error(E_DEPRECATED, "Methods with the same name as their class will not be constructors in a future version of PHP; %s has a deprecated constructor", ZSTR_VAL(ce->name)); - } } /* }}} */ @@ -2211,7 +2140,6 @@ typedef struct { struct { const zend_function *parent_fn; const zend_function *child_fn; - zend_bool always_error; }; }; } variance_obligation; @@ -2255,14 +2183,12 @@ static void add_dependency_obligation(zend_class_entry *ce, zend_class_entry *de } static void add_compatibility_obligation( - zend_class_entry *ce, const zend_function *child_fn, const zend_function *parent_fn, - zend_bool always_error) { + zend_class_entry *ce, const zend_function *child_fn, const zend_function *parent_fn) { HashTable *obligations = get_or_init_obligations_for_class(ce); variance_obligation *obligation = emalloc(sizeof(variance_obligation)); obligation->type = OBLIGATION_COMPATIBILITY; obligation->child_fn = child_fn; obligation->parent_fn = parent_fn; - obligation->always_error = always_error; zend_hash_next_index_insert_ptr(obligations, obligation); } @@ -2286,9 +2212,8 @@ static int check_variance_obligation(zval *zv) { return ZEND_HASH_APPLY_KEEP; } if (status == INHERITANCE_ERROR) { - emit_incompatible_method_error_or_warning( - obligation->child_fn, obligation->parent_fn, status, unresolved_class, - obligation->always_error); + emit_incompatible_method_error( + obligation->child_fn, obligation->parent_fn, status, unresolved_class); } /* Either the compatibility check was successful or only threw a warning. */ } @@ -2350,9 +2275,8 @@ static void report_variance_errors(zend_class_entry *ce) { status = zend_do_perform_implementation_check( &unresolved_class, obligation->child_fn, obligation->parent_fn); ZEND_ASSERT(status == INHERITANCE_UNRESOLVED); - emit_incompatible_method_error_or_warning( - obligation->child_fn, obligation->parent_fn, - status, unresolved_class, obligation->always_error); + emit_incompatible_method_error( + obligation->child_fn, obligation->parent_fn, status, unresolved_class); } ZEND_HASH_FOREACH_END(); /* Only warnings were thrown above -- that means that there are incompatibilities, but only |