mirror of
https://github.com/php/php-src.git
synced 2026-04-28 02:33:17 +02:00
Fixed bug #71978 (Existence of return type hint affects other compatibility rules)
This commit is contained in:
@@ -3,6 +3,8 @@ PHP NEWS
|
||||
?? ??? 2016 PHP 7.0.6
|
||||
|
||||
- Core:
|
||||
. Fixed bug #71978 (Existence of return type hint affects other compatibility
|
||||
rules). (Dmitry)
|
||||
. Fixed bug #71930 (_zval_dtor_func: Assertion `(arr)->gc.refcount <= 1'
|
||||
failed). (Laruence)
|
||||
. Fixed bug #71922 (Crash on assert(new class{})). (Nikita)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
Bug #71978 (Existence of return type hint affects other compatibility rules)
|
||||
--FILE--
|
||||
<?php
|
||||
class A {
|
||||
function foo(int $a) {}
|
||||
}
|
||||
class B extends A {
|
||||
function foo(string $a) {}
|
||||
}
|
||||
class A1 {
|
||||
function foo(int $a): int {}
|
||||
}
|
||||
class B1 extends A1 {
|
||||
function foo(string $a): int {}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Declaration of B::foo(string $a) should be compatible with A::foo(int $a) in %s on line %d
|
||||
|
||||
Warning: Declaration of B1::foo(string $a): int should be compatible with A1::foo(int $a): int in %s on line %d
|
||||
+26
-12
@@ -243,11 +243,6 @@ static int zend_do_perform_type_hint_check(const zend_function *fe, zend_arg_inf
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (proto_arg_info->type_hint && proto_arg_info->allow_null && !fe_arg_info->allow_null) {
|
||||
/* incompatible nullability */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -324,6 +319,11 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (proto_arg_info->type_hint && proto_arg_info->allow_null && !fe_arg_info->allow_null) {
|
||||
/* incompatible nullability */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* by-ref constraints on arguments are invariant */
|
||||
if (fe_arg_info->pass_by_reference != proto_arg_info->pass_by_reference) {
|
||||
return 0;
|
||||
@@ -570,17 +570,31 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function *
|
||||
}
|
||||
|
||||
if (child->common.prototype && (
|
||||
child->common.prototype->common.fn_flags & (ZEND_ACC_ABSTRACT | ZEND_ACC_HAS_RETURN_TYPE)
|
||||
child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT
|
||||
)) {
|
||||
if (UNEXPECTED(!zend_do_perform_implementation_check(child, child->common.prototype))) {
|
||||
zend_string *method_prototype = zend_get_function_declaration(child->common.prototype);
|
||||
zend_string *child_prototype = zend_get_function_declaration(child);
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", ZSTR_VAL(child_prototype), ZSTR_VAL(method_prototype));
|
||||
parent = child->common.prototype;
|
||||
}
|
||||
if (UNEXPECTED(!zend_do_perform_implementation_check(child, parent))) {
|
||||
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_do_perform_type_hint_check(child, child->common.arg_info - 1, parent, parent->common.arg_info - 1))) {
|
||||
error_level = E_COMPILE_ERROR;
|
||||
error_verb = "must";
|
||||
} else {
|
||||
error_level = E_WARNING;
|
||||
error_verb = "should";
|
||||
}
|
||||
} else 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(E_WARNING, "Declaration of %s should be compatible with %s", ZSTR_VAL(child_prototype), ZSTR_VAL(method_prototype));
|
||||
zend_error(error_level, "Declaration of %s %s be compatible with %s", ZSTR_VAL(child_prototype), error_verb, ZSTR_VAL(method_prototype));
|
||||
zend_string_free(child_prototype);
|
||||
zend_string_free(method_prototype);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user