Skip to content

Commit cb494fd

Browse files
committed
Zend: Use pointer to zend_type for variance checks
1 parent dc189f5 commit cb494fd

File tree

1 file changed

+32
-26
lines changed

1 file changed

+32
-26
lines changed

Zend/zend_inheritance.c

+32-26
Original file line numberDiff line numberDiff line change
@@ -428,16 +428,16 @@ static void track_class_dependency(zend_class_entry *ce, zend_string *class_name
428428

429429
/* Check whether any type in the fe_type intersection type is a subtype of the proto class. */
430430
static inheritance_status zend_is_intersection_subtype_of_class(
431-
zend_class_entry *fe_scope, const zend_type fe_type,
431+
zend_class_entry *fe_scope, const zend_type *fe_type_ptr,
432432
zend_class_entry *proto_scope, zend_string *proto_class_name, zend_class_entry *proto_ce)
433433
{
434-
ZEND_ASSERT(ZEND_TYPE_IS_INTERSECTION(fe_type));
434+
ZEND_ASSERT(ZEND_TYPE_IS_INTERSECTION(*fe_type_ptr));
435435
bool have_unresolved = false;
436436
const zend_type *single_type;
437437

438438
/* Traverse the list of child types and check that at least one is
439439
* a subtype of the parent type being checked */
440-
ZEND_TYPE_FOREACH(fe_type, single_type) {
440+
ZEND_TYPE_FOREACH(*fe_type_ptr, single_type) {
441441
zend_class_entry *fe_ce;
442442
zend_string *fe_class_name = NULL;
443443
if (ZEND_TYPE_HAS_NAME(*single_type)) {
@@ -473,7 +473,9 @@ static inheritance_status zend_is_intersection_subtype_of_class(
473473
/* Check whether a single class proto type is a subtype of a potentially complex fe_type. */
474474
static inheritance_status zend_is_class_subtype_of_type(
475475
zend_class_entry *fe_scope, zend_string *fe_class_name,
476-
zend_class_entry *proto_scope, const zend_type proto_type) {
476+
zend_class_entry *proto_scope, const zend_type *proto_type_ptr
477+
) {
478+
const zend_type proto_type = *proto_type_ptr;
477479
zend_class_entry *fe_ce = NULL;
478480
bool have_unresolved = 0;
479481

@@ -521,7 +523,7 @@ static inheritance_status zend_is_class_subtype_of_type(
521523
ZEND_TYPE_FOREACH(proto_type, single_type) {
522524
if (ZEND_TYPE_IS_INTERSECTION(*single_type)) {
523525
inheritance_status subtype_status = zend_is_class_subtype_of_type(
524-
fe_scope, fe_class_name, proto_scope, *single_type);
526+
fe_scope, fe_class_name, proto_scope, single_type);
525527

526528
switch (subtype_status) {
527529
case INHERITANCE_ERROR:
@@ -606,9 +608,11 @@ static void register_unresolved_classes(zend_class_entry *scope, const zend_type
606608
}
607609

608610
static inheritance_status zend_is_intersection_subtype_of_type(
609-
zend_class_entry *fe_scope, const zend_type fe_type,
610-
zend_class_entry *proto_scope, const zend_type proto_type)
611-
{
611+
zend_class_entry *fe_scope, const zend_type *fe_type_ptr,
612+
zend_class_entry *proto_scope, const zend_type *proto_type_ptr
613+
) {
614+
const zend_type fe_type = *fe_type_ptr;
615+
const zend_type proto_type = *proto_type_ptr;
612616
bool have_unresolved = false;
613617
const zend_type *single_type;
614618
uint32_t proto_type_mask = ZEND_TYPE_PURE_MASK(proto_type);
@@ -644,7 +648,7 @@ static inheritance_status zend_is_intersection_subtype_of_type(
644648

645649
if (ZEND_TYPE_IS_INTERSECTION(*single_type)) {
646650
status = zend_is_intersection_subtype_of_type(
647-
fe_scope, fe_type, proto_scope, *single_type);
651+
fe_scope, fe_type_ptr, proto_scope, single_type);
648652
} else {
649653
zend_string *proto_class_name = get_class_from_type(proto_scope, *single_type);
650654
if (!proto_class_name) {
@@ -653,7 +657,7 @@ static inheritance_status zend_is_intersection_subtype_of_type(
653657

654658
zend_class_entry *proto_ce = NULL;
655659
status = zend_is_intersection_subtype_of_class(
656-
fe_scope, fe_type, proto_scope, proto_class_name, proto_ce);
660+
fe_scope, fe_type_ptr, proto_scope, proto_class_name, proto_ce);
657661
}
658662

659663
if (status == early_exit_status) {
@@ -672,9 +676,11 @@ static inheritance_status zend_is_intersection_subtype_of_type(
672676
}
673677

674678
ZEND_API inheritance_status zend_perform_covariant_type_check(
675-
zend_class_entry *fe_scope, const zend_type fe_type,
676-
zend_class_entry *proto_scope, const zend_type proto_type)
679+
zend_class_entry *fe_scope, const zend_type *fe_type_ptr,
680+
zend_class_entry *proto_scope, const zend_type *proto_type_ptr)
677681
{
682+
const zend_type fe_type = *fe_type_ptr;
683+
const zend_type proto_type = *proto_type_ptr;
678684
ZEND_ASSERT(ZEND_TYPE_IS_SET(fe_type) && ZEND_TYPE_IS_SET(proto_type));
679685

680686
/* Apart from void, everything is trivially covariant to the mixed type.
@@ -713,7 +719,7 @@ ZEND_API inheritance_status zend_perform_covariant_type_check(
713719
early_exit_status =
714720
ZEND_TYPE_IS_INTERSECTION(proto_type) ? INHERITANCE_ERROR : INHERITANCE_SUCCESS;
715721
inheritance_status status = zend_is_intersection_subtype_of_type(
716-
fe_scope, fe_type, proto_scope, proto_type);
722+
fe_scope, fe_type_ptr, proto_scope, proto_type_ptr);
717723

718724
if (status == early_exit_status) {
719725
return status;
@@ -733,15 +739,15 @@ ZEND_API inheritance_status zend_perform_covariant_type_check(
733739
/* Union has an intersection type as it's member */
734740
if (ZEND_TYPE_IS_INTERSECTION(*single_type)) {
735741
status = zend_is_intersection_subtype_of_type(
736-
fe_scope, *single_type, proto_scope, proto_type);
742+
fe_scope, single_type, proto_scope, proto_type_ptr);
737743
} else {
738744
zend_string *fe_class_name = get_class_from_type(fe_scope, *single_type);
739745
if (!fe_class_name) {
740746
continue;
741747
}
742748

743749
status = zend_is_class_subtype_of_type(
744-
fe_scope, fe_class_name, proto_scope, proto_type);
750+
fe_scope, fe_class_name, proto_scope, proto_type_ptr);
745751
}
746752

747753
if (status == early_exit_status) {
@@ -763,7 +769,7 @@ ZEND_API inheritance_status zend_perform_covariant_type_check(
763769
}
764770

765771
static inheritance_status zend_do_perform_arg_type_hint_check(
766-
zend_class_entry *fe_scope, zend_arg_info *fe_arg_info,
772+
zend_class_entry *fe_scope, const zend_arg_info *fe_arg_info,
767773
zend_class_entry *proto_scope, zend_arg_info *proto_arg_info) /* {{{ */
768774
{
769775
if (!ZEND_TYPE_IS_SET(fe_arg_info->type) || ZEND_TYPE_PURE_MASK(fe_arg_info->type) == MAY_BE_ANY) {
@@ -779,7 +785,7 @@ static inheritance_status zend_do_perform_arg_type_hint_check(
779785
/* Contravariant type check is performed as a covariant type check with swapped
780786
* argument order. */
781787
return zend_perform_covariant_type_check(
782-
proto_scope, proto_arg_info->type, fe_scope, fe_arg_info->type);
788+
proto_scope, &proto_arg_info->type, fe_scope, &fe_arg_info->type);
783789
}
784790
/* }}} */
785791

@@ -881,7 +887,7 @@ static inheritance_status zend_do_perform_implementation_check(
881887
}
882888

883889
local_status = zend_perform_covariant_type_check(
884-
fe_scope, fe->common.arg_info[-1].type, proto_scope, proto->common.arg_info[-1].type);
890+
fe_scope, &fe->common.arg_info[-1].type, proto_scope, &proto->common.arg_info[-1].type);
885891

886892
if (UNEXPECTED(local_status != INHERITANCE_SUCCESS)) {
887893
if (local_status == INHERITANCE_ERROR
@@ -1297,10 +1303,10 @@ static inheritance_status full_property_types_compatible(
12971303
/* Perform a covariant type check in both directions to determined invariance. */
12981304
inheritance_status status1 = variance == PROP_CONTRAVARIANT ? INHERITANCE_SUCCESS :
12991305
zend_perform_covariant_type_check(
1300-
child_info->ce, child_info->type, parent_info->ce, parent_info->type);
1306+
child_info->ce, &child_info->type, parent_info->ce, &parent_info->type);
13011307
inheritance_status status2 = variance == PROP_COVARIANT ? INHERITANCE_SUCCESS :
13021308
zend_perform_covariant_type_check(
1303-
parent_info->ce, parent_info->type, child_info->ce, child_info->type);
1309+
parent_info->ce, &parent_info->type, child_info->ce, &child_info->type);
13041310
if (status1 == INHERITANCE_SUCCESS && status2 == INHERITANCE_SUCCESS) {
13051311
return INHERITANCE_SUCCESS;
13061312
}
@@ -1357,7 +1363,7 @@ static inheritance_status verify_property_type_compatibility(
13571363
&& (!child_info->hooks || !child_info->hooks[ZEND_PROPERTY_HOOK_SET])) {
13581364
zend_type set_type = parent_info->hooks[ZEND_PROPERTY_HOOK_SET]->common.arg_info[0].type;
13591365
inheritance_status result = zend_perform_covariant_type_check(
1360-
parent_info->ce, set_type, child_info->ce, child_info->type);
1366+
parent_info->ce, &set_type, child_info->ce, &child_info->type);
13611367
if ((result == INHERITANCE_ERROR && throw_on_error) || (result == INHERITANCE_UNRESOLVED && throw_on_unresolved)) {
13621368
emit_set_hook_type_error(child_info, parent_info);
13631369
}
@@ -1645,7 +1651,7 @@ static inheritance_status class_constant_types_compatible(const zend_class_const
16451651
return INHERITANCE_ERROR;
16461652
}
16471653

1648-
return zend_perform_covariant_type_check(child->ce, child->type, parent->ce, parent->type);
1654+
return zend_perform_covariant_type_check(child->ce, &child->type, parent->ce, &parent->type);
16491655
}
16501656

16511657
static bool do_inherit_constant_check(
@@ -1791,7 +1797,7 @@ ZEND_API inheritance_status zend_verify_property_hook_variance(const zend_proper
17911797
{
17921798
ZEND_ASSERT(prop_info->hooks && prop_info->hooks[ZEND_PROPERTY_HOOK_SET] == func);
17931799

1794-
zend_arg_info *value_arg_info = &func->op_array.arg_info[0];
1800+
const zend_arg_info *value_arg_info = &func->op_array.arg_info[0];
17951801
if (!ZEND_TYPE_IS_SET(value_arg_info->type)) {
17961802
return INHERITANCE_SUCCESS;
17971803
}
@@ -1801,7 +1807,7 @@ ZEND_API inheritance_status zend_verify_property_hook_variance(const zend_proper
18011807
}
18021808

18031809
zend_class_entry *ce = prop_info->ce;
1804-
return zend_perform_covariant_type_check(ce, prop_info->type, ce, value_arg_info->type);
1810+
return zend_perform_covariant_type_check(ce, &prop_info->type, ce, &value_arg_info->type);
18051811
}
18061812

18071813
#ifdef ZEND_OPCACHE_SHM_REATTACHMENT
@@ -2777,8 +2783,8 @@ static bool do_trait_constant_check(
27772783
emit_incompatible_trait_constant_error(ce, existing_constant, trait_constant, name, traits, current_trait);
27782784
return false;
27792785
} else if (ZEND_TYPE_IS_SET(trait_constant->type)) {
2780-
inheritance_status status1 = zend_perform_covariant_type_check(ce, existing_constant->type, traits[current_trait], trait_constant->type);
2781-
inheritance_status status2 = zend_perform_covariant_type_check(traits[current_trait], trait_constant->type, ce, existing_constant->type);
2786+
inheritance_status status1 = zend_perform_covariant_type_check(ce, &existing_constant->type, traits[current_trait], &trait_constant->type);
2787+
inheritance_status status2 = zend_perform_covariant_type_check(traits[current_trait], &trait_constant->type, ce, &existing_constant->type);
27822788
if (status1 == INHERITANCE_ERROR || status2 == INHERITANCE_ERROR) {
27832789
emit_incompatible_trait_constant_error(ce, existing_constant, trait_constant, name, traits, current_trait);
27842790
return false;

0 commit comments

Comments
 (0)