summaryrefslogtreecommitdiff
path: root/Zend/zend_inheritance.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-05-08 11:51:50 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-05-08 11:51:50 +0200
commit11655d09742054fd92a9235a828ddf4586ecd64d (patch)
tree5354aa2c1778b60574422ec5a511642ba0475356 /Zend/zend_inheritance.c
parent97cce70e550f251bb469576a130470e1d699a3a2 (diff)
parent5c474010fbe6f2969eec966250f8fbdf05a6d96d (diff)
downloadphp-git-11655d09742054fd92a9235a828ddf4586ecd64d.tar.gz
Merge branch 'PHP-7.4'
Diffstat (limited to 'Zend/zend_inheritance.c')
-rw-r--r--Zend/zend_inheritance.c46
1 files changed, 15 insertions, 31 deletions
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index 70e2dcdfd4..dca0f555cb 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -183,10 +183,16 @@ static zend_always_inline zend_bool zend_iterable_compatibility_check(zend_arg_i
}
/* }}} */
-static int zend_do_perform_type_hint_check(const zend_function *fe, zend_arg_info *fe_arg_info, const zend_function *proto, zend_arg_info *proto_arg_info) /* {{{ */
+static int zend_perform_covariant_type_check(
+ const zend_function *fe, zend_arg_info *fe_arg_info,
+ const zend_function *proto, zend_arg_info *proto_arg_info) /* {{{ */
{
ZEND_ASSERT(ZEND_TYPE_IS_SET(fe_arg_info->type) && ZEND_TYPE_IS_SET(proto_arg_info->type));
+ if (ZEND_TYPE_ALLOW_NULL(fe_arg_info->type) && !ZEND_TYPE_ALLOW_NULL(proto_arg_info->type)) {
+ return 0;
+ }
+
if (ZEND_TYPE_IS_CLASS(fe_arg_info->type) && ZEND_TYPE_IS_CLASS(proto_arg_info->type)) {
zend_string *fe_class_name, *proto_class_name;
const char *class_name;
@@ -239,6 +245,10 @@ static int zend_do_perform_type_hint_check(const zend_function *fe, zend_arg_inf
zend_string_release(proto_class_name);
zend_string_release(fe_class_name);
} else if (ZEND_TYPE_CODE(fe_arg_info->type) != ZEND_TYPE_CODE(proto_arg_info->type)) {
+ if (ZEND_TYPE_CODE(proto_arg_info->type) == IS_ITERABLE) {
+ return zend_iterable_compatibility_check(fe_arg_info);
+ }
+
/* Incompatible built-in types */
return 0;
}
@@ -259,7 +269,9 @@ static int zend_do_perform_arg_type_hint_check(const zend_function *fe, zend_arg
return 0;
}
- return zend_do_perform_type_hint_check(fe, fe_arg_info, proto, proto_arg_info);
+ /* Contravariant type check is performed as a covariant type check with swapped
+ * argument order. */
+ return zend_perform_covariant_type_check(proto, proto_arg_info, fe, fe_arg_info);
}
/* }}} */
@@ -332,21 +344,6 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
}
if (!zend_do_perform_arg_type_hint_check(fe, fe_arg_info, proto, proto_arg_info)) {
- switch (ZEND_TYPE_CODE(fe_arg_info->type)) {
- case IS_ITERABLE:
- if (!zend_iterable_compatibility_check(proto_arg_info)) {
- return 0;
- }
- break;
-
- default:
- return 0;
- }
- }
-
- // This introduces BC break described at https://bugs.php.net/bug.php?id=72119
- if (ZEND_TYPE_IS_SET(proto_arg_info->type) && ZEND_TYPE_ALLOW_NULL(proto_arg_info->type) && !ZEND_TYPE_ALLOW_NULL(fe_arg_info->type)) {
- /* incompatible nullability */
return 0;
}
@@ -364,20 +361,7 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
return 0;
}
- if (!zend_do_perform_type_hint_check(fe, fe->common.arg_info - 1, proto, proto->common.arg_info - 1)) {
- switch (ZEND_TYPE_CODE(proto->common.arg_info[-1].type)) {
- case IS_ITERABLE:
- if (!zend_iterable_compatibility_check(fe->common.arg_info - 1)) {
- return 0;
- }
- break;
-
- default:
- return 0;
- }
- }
-
- if (ZEND_TYPE_ALLOW_NULL(fe->common.arg_info[-1].type) && !ZEND_TYPE_ALLOW_NULL(proto->common.arg_info[-1].type)) {
+ if (!zend_perform_covariant_type_check(fe, fe->common.arg_info - 1, proto, proto->common.arg_info - 1)) {
return 0;
}
}