summaryrefslogtreecommitdiff
path: root/Zend/zend_inheritance.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-05-08 12:13:11 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-05-08 12:13:11 +0200
commit6ada4db002f2a6a90242576664ab8a60b5275534 (patch)
tree6026f808b311f99044d2582867892258c307fb38 /Zend/zend_inheritance.c
parent11655d09742054fd92a9235a828ddf4586ecd64d (diff)
parentf778e1a0b2b2535398bd37cb2e63ad06c82f8cd7 (diff)
downloadphp-git-6ada4db002f2a6a90242576664ab8a60b5275534.tar.gz
Merge branch 'PHP-7.4'
Diffstat (limited to 'Zend/zend_inheritance.c')
-rw-r--r--Zend/zend_inheritance.c72
1 files changed, 24 insertions, 48 deletions
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index dca0f555cb..38e5c205fb 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -169,61 +169,34 @@ char *zend_visibility_string(uint32_t fn_flags) /* {{{ */
}
/* }}} */
-static zend_always_inline zend_bool zend_iterable_compatibility_check(zend_arg_info *arg_info) /* {{{ */
-{
- if (ZEND_TYPE_CODE(arg_info->type) == IS_ARRAY) {
- return 1;
- }
-
- if (ZEND_TYPE_IS_CLASS(arg_info->type) && zend_string_equals_literal_ci(ZEND_TYPE_NAME(arg_info->type), "Traversable")) {
- return 1;
+static zend_string *resolve_class_name(const zend_function *fe, zend_string *name) {
+ ZEND_ASSERT(fe->common.scope);
+ if (zend_string_equals_literal_ci(name, "parent") && fe->common.scope->parent) {
+ return fe->common.scope->parent->name;
+ } else if (zend_string_equals_literal_ci(name, "self")) {
+ return fe->common.scope->name;
+ } else {
+ return name;
}
-
- return 0;
}
-/* }}} */
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));
+ zend_type fe_type = fe_arg_info->type, proto_type = proto_arg_info->type;
+ ZEND_ASSERT(ZEND_TYPE_IS_SET(fe_type) && ZEND_TYPE_IS_SET(proto_type));
- if (ZEND_TYPE_ALLOW_NULL(fe_arg_info->type) && !ZEND_TYPE_ALLOW_NULL(proto_arg_info->type)) {
+ if (ZEND_TYPE_ALLOW_NULL(fe_type) && !ZEND_TYPE_ALLOW_NULL(proto_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;
- size_t class_name_len;
-
- fe_class_name = ZEND_TYPE_NAME(fe_arg_info->type);
- class_name = ZSTR_VAL(fe_class_name);
- class_name_len = ZSTR_LEN(fe_class_name);
- if (class_name_len == sizeof("parent")-1 && !strcasecmp(class_name, "parent") && fe->common.scope && fe->common.scope->parent) {
- fe_class_name = zend_string_copy(fe->common.scope->parent->name);
- } else if (class_name_len == sizeof("self")-1 && !strcasecmp(class_name, "self") && fe->common.scope) {
- fe_class_name = zend_string_copy(fe->common.scope->name);
- } else {
- zend_string_addref(fe_class_name);
- }
-
- proto_class_name = ZEND_TYPE_NAME(proto_arg_info->type);
- class_name = ZSTR_VAL(proto_class_name);
- class_name_len = ZSTR_LEN(proto_class_name);
- if (class_name_len == sizeof("parent")-1 && !strcasecmp(class_name, "parent") && proto->common.scope && proto->common.scope->parent) {
- proto_class_name = zend_string_copy(proto->common.scope->parent->name);
- } else if (class_name_len == sizeof("self")-1 && !strcasecmp(class_name, "self") && proto->common.scope) {
- proto_class_name = zend_string_copy(proto->common.scope->name);
- } else {
- zend_string_addref(proto_class_name);
- }
+ if (ZEND_TYPE_IS_CLASS(fe_type) && ZEND_TYPE_IS_CLASS(proto_type)) {
+ zend_string *fe_class_name = resolve_class_name(fe, ZEND_TYPE_NAME(fe_type));
+ zend_string *proto_class_name = resolve_class_name(proto, ZEND_TYPE_NAME(proto_type));
if (fe_class_name != proto_class_name && strcasecmp(ZSTR_VAL(fe_class_name), ZSTR_VAL(proto_class_name)) != 0) {
if (fe->common.type != ZEND_USER_FUNCTION) {
- zend_string_release(proto_class_name);
- zend_string_release(fe_class_name);
return 0;
} else {
zend_class_entry *fe_ce, *proto_ce;
@@ -236,17 +209,20 @@ static int zend_perform_covariant_type_check(
fe_ce->type == ZEND_INTERNAL_CLASS ||
proto_ce->type == ZEND_INTERNAL_CLASS ||
fe_ce != proto_ce) {
- zend_string_release(proto_class_name);
- zend_string_release(fe_class_name);
return 0;
}
}
}
- 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);
+ } else if (ZEND_TYPE_CODE(fe_type) != ZEND_TYPE_CODE(proto_type)) {
+ if (ZEND_TYPE_CODE(proto_type) == IS_ITERABLE) {
+ if (ZEND_TYPE_CODE(fe_type) == IS_ARRAY) {
+ return 1;
+ }
+
+ if (ZEND_TYPE_IS_CLASS(fe_type) &&
+ zend_string_equals_literal_ci(ZEND_TYPE_NAME(fe_type), "Traversable")) {
+ return 1;
+ }
}
/* Incompatible built-in types */