49static void add_compatibility_obligation(
52static void add_property_compatibility_obligation(
55static void add_class_constant_compatibility_obligation(
58static void add_property_hook_obligation(
61static void ZEND_COLD emit_incompatible_method_error(
68static void zend_type_list_copy_ctor(
86 zend_type_copy_ctor(list_type, use_arena,
persistent);
120 return zend_duplicate_internal_function(
func, ce);
122 if (
func->op_array.refcount) {
123 (*
func->op_array.refcount)++;
126 zend_string_addref(
func->op_array.function_name);
147 ce->
__get = parent->__get;
150 ce->
__set = parent->__set;
159 ce->
__call = parent->__call;
168 ce->
clone = parent->clone;
192 ZSTR_VAL(parent->name),
ZSTR_VAL(parent->constructor->common.function_name),
215static const char *zend_asymmetric_visibility_string(uint32_t fn_flags)
218 return "private(set)";
220 return "protected(set)";
231 return scope->parent->name;
233 return scope->parent_name;
254 if (!
CG(delayed_autoloads)) {
269 ce = zend_hash_find_ptr(
CG(class_table), lc_name);
271 zend_string_release(lc_name);
273 if (register_unresolved && !ce) {
285 if (!
CG(in_compilation) || in_preload) {
290 if (register_unresolved) {
291 register_unresolved_class(
name);
294 if (ce && class_visible(ce)) {
308 return lookup_class_ex(
scope,
name,
false);
318 return instanceof_function(ce1, ce2);
332 if (parent_ce && unlinked_instanceof(parent_ce, ce2)) {
343 if (unlinked_instanceof(ce1->
interfaces[i], ce2)) {
353 if (ce && ce != ce1 && unlinked_instanceof(ce, ce2)) {
363static bool zend_type_permits_self(
377 if (ce && unlinked_instanceof(self, ce)) {
390 if (!
CG(current_linking_class) || ce ==
CG(current_linking_class)) {
405 ht = (
HashTable*)
CG(current_linking_class)->inheritance_cache;
412 CG(current_linking_class)->inheritance_cache =
NULL;
415 CG(current_linking_class) =
NULL;
425 zend_hash_add_ptr(
ht, class_name, ce);
434 bool have_unresolved =
false;
449 if (!proto_ce) proto_ce = lookup_class(proto_scope, proto_class_name);
450 fe_ce = lookup_class(fe_scope, fe_class_name);
458 if (!fe_ce || !proto_ce) {
459 have_unresolved =
true;
462 if (unlinked_instanceof(fe_ce, proto_ce)) {
463 track_class_dependency(fe_ce, fe_class_name);
464 track_class_dependency(proto_ce, proto_class_name);
477 bool have_unresolved = 0;
484 if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name);
488 track_class_dependency(fe_ce, fe_class_name);
501 fe_scope, fe_class_name, proto_scope, *single_type);
503 switch (subtype_status) {
505 if (is_intersection) {
513 if (!is_intersection) {
527 if (!is_intersection) {
533 if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name);
534 proto_ce = lookup_class(proto_scope, proto_class_name);
541 if (!fe_ce || !proto_ce) {
545 if (unlinked_instanceof(fe_ce, proto_ce)) {
546 track_class_dependency(fe_ce, fe_class_name);
547 track_class_dependency(proto_ce, proto_class_name);
548 if (!is_intersection) {
552 if (is_intersection) {
558 if (have_unresolved) {
575 register_unresolved_classes(
scope, *single_type);
580 lookup_class_ex(
scope, class_name,
true);
589 bool have_unresolved =
false;
599 zend_string *fe_class_name = get_class_from_type(fe_scope, *single_type);
600 if (!fe_class_name) {
605 track_class_dependency(fe_ce, fe_class_name);
608 have_unresolved =
true;
623 status = zend_is_intersection_subtype_of_type(
624 fe_scope, fe_type, proto_scope, *single_type);
626 zend_string *proto_class_name = get_class_from_type(proto_scope, *single_type);
627 if (!proto_class_name) {
632 status = zend_is_intersection_subtype_of_class(
633 fe_scope, fe_type, proto_scope, proto_class_name, proto_ce);
636 if (
status == early_exit_status) {
640 have_unresolved =
true;
644 if (have_unresolved) {
667 uint32_t added_types = fe_type_mask & ~proto_type_mask;
670 && zend_type_permits_self(proto_type, proto_scope, fe_scope)) {
688 bool have_unresolved =
false;
694 fe_scope, fe_type, proto_scope, proto_type);
696 if (
status == early_exit_status) {
700 have_unresolved =
true;
712 status = zend_is_intersection_subtype_of_type(
713 fe_scope, *single_type, proto_scope, proto_type);
715 zend_string *fe_class_name = get_class_from_type(fe_scope, *single_type);
716 if (!fe_class_name) {
720 status = zend_is_class_subtype_of_type(
721 fe_scope, fe_class_name, proto_scope, proto_type);
724 if (
status == early_exit_status) {
728 have_unresolved =
true;
733 if (!have_unresolved) {
737 register_unresolved_classes(fe_scope, fe_type);
738 register_unresolved_classes(proto_scope, proto_type);
759 proto_scope, proto_arg_info->
type, fe_scope, fe_arg_info->
type);
770 uint32_t i,
num_args, proto_num_args, fe_num_args;
772 bool proto_is_variadic, fe_is_variadic;
801 if (proto_is_variadic && !fe_is_variadic) {
818 if (!proto_arg_info) {
829 local_status = zend_do_perform_arg_type_hint_check(
830 fe_scope, fe_arg_info, proto_scope, proto_arg_info);
876static ZEND_COLD void zend_append_type_hint(
881 smart_str_append(str, type_str);
882 zend_string_release(type_str);
884 smart_str_appendc(str,
' ');
896 smart_str_appends(&str,
"& ");
906 smart_str_appends(&str,
"::");
910 smart_str_appendc(&str,
'(');
922 zend_append_type_hint(&str,
scope, arg_info, 0);
925 smart_str_appendc(&str,
'&');
929 smart_str_appends(&str,
"...");
932 smart_str_appendc(&str,
'$');
940 smart_str_appends(&str,
" = ");
946 smart_str_appends(&str,
"<default>");
969 smart_str_appends(&str,
"false");
971 smart_str_appends(&str,
"true");
973 smart_str_appends(&str,
"null");
975 smart_str_appendc(&str,
'\'');
978 smart_str_appends(&str,
"...");
980 smart_str_appendc(&str,
'\'');
983 smart_str_appends(&str,
"[]");
985 smart_str_appends(&str,
"[...]");
990 smart_str_append(&str, zend_ast_get_constant_name(ast));
992 smart_str_append(&str, zend_ast_get_str(ast->
child[0]));
993 smart_str_appends(&str,
"::");
994 smart_str_append(&str, zend_ast_get_str(ast->
child[1]));
996 smart_str_appends(&str,
"<expression>");
1001 smart_str_append(&str, zv_str);
1002 zend_tmp_string_release(tmp_zv_str);
1009 smart_str_appends(&str,
", ");
1015 smart_str_appendc(&str,
')');
1018 smart_str_appends(&str,
": ");
1035static void ZEND_COLD emit_incompatible_method_error(
1039 zend_string *parent_prototype = zend_get_function_declaration(parent, parent_scope);
1040 zend_string *child_prototype = zend_get_function_declaration(child, child_scope);
1051 "Could not check compatibility between %s and %s, because class %s is not available",
1056 "returntypewillchange",
1057 sizeof(
"returntypewillchange")-1
1060 if (!return_type_will_change_attribute) {
1062 "Return type of %s should either be compatible with %s, "
1063 "or the #[\\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice",
1067 "During inheritance of %s",
ZSTR_VAL(parent_scope->
name));
1072 "Declaration of %s must be compatible with %s",
1075 zend_string_efree(child_prototype);
1076 zend_string_efree(parent_prototype);
1079static void perform_delayable_implementation_check(
1085 zend_do_perform_implementation_check(fe, fe_scope, proto, proto_scope);
1088 add_compatibility_obligation(ce, fe, fe_scope, proto, proto_scope);
1091 emit_incompatible_method_error(fe, fe_scope, proto, proto_scope,
status);
1096#define ZEND_INHERITANCE_LAZY_CHILD_CLONE (1<<0)
1097#define ZEND_INHERITANCE_CHECK_SILENT (1<<1)
1098#define ZEND_INHERITANCE_CHECK_PROTO (1<<2)
1099#define ZEND_INHERITANCE_CHECK_VISIBILITY (1<<3)
1100#define ZEND_INHERITANCE_SET_CHILD_CHANGED (1<<4)
1101#define ZEND_INHERITANCE_SET_CHILD_PROTO (1<<5)
1102#define ZEND_INHERITANCE_RESET_CHILD_OVERRIDE (1<<6)
1109 uint32_t child_flags;
1110 uint32_t parent_flags = parent->common.fn_flags;
1113#define SEPARATE_METHOD() do { \
1114 if ((flags & ZEND_INHERITANCE_LAZY_CHILD_CLONE) \
1115 && child_scope != ce && child->type == ZEND_USER_FUNCTION) { \
1117 zend_function *new_function = zend_arena_alloc(&CG(arena), sizeof(zend_op_array)); \
1118 memcpy(new_function, child, sizeof(zend_op_array)); \
1119 Z_PTR_P(child_zv) = child = new_function; \
1120 flags &= ~ZEND_INHERITANCE_LAZY_CHILD_CLONE; \
1138 "Cannot override final method %s::%s()",
1152 "Cannot make non static method %s::%s() static in class %s",
1156 "Cannot make static method %s::%s() non static in class %s",
1168 "Cannot make non abstract method %s::%s() abstract in class %s",
1203 "Access level to %s::%s() must be %s (as in class %s)%s",
1209 return zend_do_perform_implementation_check(child, child_scope, parent, parent_scope);
1211 perform_delayable_implementation_check(ce, child, child_scope, parent, parent_scope);
1220#undef SEPARATE_METHOD
1238 do_inheritance_check_on_method(
1239 func,
func->common.scope, parent, parent->common.scope, ce, child,
flags);
1246 parent = zend_duplicate_function(parent, ce);
1248 if (!is_interface) {
1272 child_info->
ce, child_info->
type, parent_info->
ce, parent_info->
type);
1275 parent_info->
ce, parent_info->
type, child_info->
ce, child_info->
type);
1286static ZEND_COLD void emit_incompatible_property_error(
1290 "Type of %s::$%s must be %s%s (as in class %s)",
1292 zend_get_unmangled_property_name(child->
name),
1304 "Set type of %s::$%s must be supertype of %s (as in %s %s)",
1306 zend_get_unmangled_property_name(child->
name),
1316 bool throw_on_error,
1317 bool throw_on_unresolved
1321 emit_incompatible_property_error(child_info, parent_info, variance);
1332 parent_info->
ce, set_type, child_info->
ce, child_info->
type);
1334 emit_set_hook_type_error(child_info, parent_info);
1348static void inherit_property_hook(
1359 && property_has_operation(parent_info,
kind)) {
1370 if (property_has_operation(child_info,
kind)) {
1375 if (!child_info->
hooks) {
1380 child_info->
hooks[
kind] = zend_duplicate_function(parent, ce);
1394 "Cannot override final property hook %s::%s()",
1395 ZSTR_VAL(parent->common.scope->name),
1396 ZSTR_VAL(parent->common.function_name));
1399 do_inheritance_check_on_method(
1450 "Cannot redeclare %s property %s::$%s as %s %s::$%s",
1463 if (!parent_set_visibility) {
1467 if (child_set_visibility > parent_set_visibility) {
1470 "Set access level of %s::$%s must be %s (as in class %s)%s",
1484 bool use_child_prop = !parent_info->
hooks && child_info->
hooks;
1500 if (use_child_prop) {
1516 if (!use_child_prop) {
1522 if (parent_info->
hooks || child_info->
hooks) {
1524 inherit_property_hook(ce, parent_info, child_info, i);
1531 parent_info, child_info, variance,
true,
false);
1533 add_property_compatibility_obligation(ce, child_info, parent_info, variance);
1537 "Type of %s::$%s must not be defined (as in class %s)",
1584 for (i = 0; i < ce_num; i++) {
1596 while (ce_num < ce->num_interfaces) {
1597 do_implement_interface(ce, ce->
interfaces[ce_num++]);
1602static void emit_incompatible_class_constant_error(
1606 "Type of %s::%s must be compatible with %s::%s of type %s",
1625static bool do_inherit_constant_check(
1635 bool inherit = do_inherit_constant_check(ce, parent_const,
name);
1680 table, parent_table,
1694 table[prop_table_offset] = prop;
1712 "Cannot specify default value for virtual hooked property %s::$%s",
ZSTR_VAL(ce->
name),
ZSTR_VAL(prop_name));
1733 abstract_error =
false;
1737 if (abstract_error) {
1739 "Abstract property %s::$%s must specify at least one abstract hook",
ZSTR_VAL(ce->
name),
ZSTR_VAL(prop_name));
1745 ?
"Write-only" :
"Read-only";
1747 "%s virtual property %s::$%s must not specify asymmetric visibility",
1755 ZSTR_VAL(value_param_name),
ZSTR_VAL(class_name), zend_get_unmangled_property_name(prop_name));
1781#ifdef ZEND_OPCACHE_SHM_REATTACHMENT
1789 if (
CG(current_linking_class) == ce) {
1796 CG(current_linking_class) =
NULL;
1855 }
while (dst !=
end);
1878 }
while (dst !=
end);
1889 }
while (dst !=
end);
1907 }
while (dst !=
end);
1928 }
while (dst !=
end);
1939 if (property_info->
ce == ce) {
1954 do_inherit_property(property_info,
key, ce);
1960 if (property_info->
ce == ce && property_info->
hooks) {
1974 do_inherit_class_constant(
key, c, ce);
1996 do_inherit_parent_constructor(ce);
2000 zend_do_inherit_interfaces(ce, parent_ce);
2014 zval op1_tmp, op2_tmp;
2034 is_compatible = fast_is_identical_function(
op1,
op2);
2036 if (
op1 == &op1_tmp) {
2037 zval_ptr_dtor_nogc(&op1_tmp);
2039 if (
op2 == &op2_tmp) {
2040 zval_ptr_dtor_nogc(&op2_tmp);
2043 return is_compatible;
2048static bool do_inherit_constant_check(
2064 if (child_constant->
ce != parent_constant->
ce && child_constant->
ce != ce) {
2066 "%s %s inherits both %s::%s and %s::%s, which is ambiguous",
2067 zend_get_object_type_uc(ce),
2077 zend_get_object_type(parent_constant->
ce),
2086 emit_incompatible_class_constant_error(child_constant, parent_constant,
name);
2088 add_class_constant_compatibility_obligation(ce, child_constant, parent_constant,
name);
2098 if (do_inherit_constant_check(ce, c,
name)) {
2141 do_inherit_iface_constant(
key, c, ce, iface);
2154 do_inherit_property(prop,
key, ce);
2157 do_implement_interface(ce, iface);
2159 zend_do_inherit_interfaces(ce, iface);
2166 uint32_t i, ignore = 0;
2179 if (
EXPECTED(i < parent_iface_num)) {
2189 do_inherit_constant_check(ce, c,
key);
2201 do_interface_implementation(ce, iface);
2210 uint32_t num_interfaces = num_parent_interfaces;
2216 iface = interfaces[num_parent_interfaces + i];
2218 add_dependency_obligation(ce, iface);
2225 for (
j = 0;
j < num_interfaces;
j++) {
2226 if (interfaces[
j] == iface) {
2227 if (
j >= num_parent_interfaces) {
2230 zend_get_object_type_uc(ce),
2237 do_inherit_constant_check(ce, c,
key);
2245 interfaces[num_interfaces] = iface;
2262 for (i = 0; i < num_parent_interfaces; i++) {
2263 do_implement_interface(ce, ce->
interfaces[i]);
2267 for (; i < num_interfaces; i++) {
2268 do_interface_implementation(ce, ce->
interfaces[i]);
2288 "%s::%s() has #[\\Override] attribute, but no matching parent method exists",
2306 "%s::%s() has #[\\Override] attribute, but no matching parent method exists",
2325 bool check_inheritance =
false;
2343 do_inheritance_check_on_method(
2344 existing_fn, fixup_trait_scope(existing_fn, ce), fn, fixup_trait_scope(fn, ce),
2360 check_inheritance =
true;
2381 if (check_inheritance) {
2389 do_inheritance_check_on_method(
2390 fn, fixup_trait_scope(fn, ce), existing_fn, fixup_trait_scope(existing_fn, ce),
2453 zend_add_trait_method(ce, alias->
alias,
lcname, &fn_copy);
2489 zend_traits_check_private_final_inheritance(fn->
common.
fn_flags, &fn_copy, fnname);
2506 if (traits[i] == trait) {
2533 while ((cur_precedence = precedences[i])) {
2536 lc_trait_name = zend_string_tolower(cur_method_ref->
class_name);
2537 trait = zend_hash_find_ptr(
EG(class_table), lc_trait_name);
2542 zend_check_trait_usage(ce, trait, traits);
2548 "A precedence rule was defined for %s::%s but this method does not exist",
2565 lc_trait_name = zend_string_tolower(class_name);
2566 exclude_ce = zend_hash_find_ptr(
EG(class_table), lc_trait_name);
2571 trait_num = zend_check_trait_usage(ce, exclude_ce, traits);
2572 if (!exclude_tables[trait_num]) {
2582 if (trait == exclude_ce) {
2584 "Inconsistent insteadof definition. "
2585 "The method %s is to be used from %s, but %s is also on the exclude list",
2610 lc_trait_name = zend_string_tolower(cur_method_ref->
class_name);
2611 trait = zend_hash_find_ptr(
EG(class_table), lc_trait_name);
2616 zend_check_trait_usage(ce, trait, traits);
2628 if (zend_hash_exists(&traits[
j]->function_table,
lcname)) {
2635 "An alias was defined for method %s(), which exists in both %s and %s. Use %s::%s or %s::%s to resolve the ambiguity",
2646 if (cur_alias->
alias) {
2648 "An alias (%s) was defined for method %s(), but this method does not exist",
2653 "The modifiers of the trait method %s() are changed, but this method does not exist. Error",
2665 *exclude_tables_ptr = exclude_tables;
2666 *aliases_ptr = aliases;
2676 if (exclude_tables) {
2681 zend_traits_copy_functions(
key, fn, ce, exclude_tables[i], aliases);
2684 if (exclude_tables[i]) {
2687 exclude_tables[i] =
NULL;
2695 zend_traits_copy_functions(
key, fn, ce,
NULL, aliases);
2702 zend_fixup_trait_method(fn, ce);
2718 if (colliding_ce == ce) {
2719 for (i = 0; i < current_trait; i++) {
2721 && zend_hash_exists(&traits[i]->constants_table, constant_name)) {
2727 return colliding_ce;
2731static void emit_incompatible_trait_constant_error(
2736 "%s and %s define the same constant (%s) in the composition of %s. However, the definition differs and is considered incompatible. Class was composed",
2737 ZSTR_VAL(find_first_constant_definition(ce, traits, current_trait,
name, existing_constant->
ce)->name),
2744static bool do_trait_constant_check(
2758 emit_incompatible_trait_constant_error(ce, existing_constant, trait_constant,
name, traits, current_trait);
2763 emit_incompatible_trait_constant_error(ce, existing_constant, trait_constant,
name, traits, current_trait);
2769 emit_incompatible_trait_constant_error(ce, existing_constant, trait_constant,
name, traits, current_trait);
2774 if (!check_trait_property_or_constant_value_compatibility(ce, &trait_constant->
value, &existing_constant->
value)) {
2776 emit_incompatible_trait_constant_error(ce, existing_constant, trait_constant,
name, traits, current_trait);
2797 if (do_trait_constant_check(ce,
constant, constant_name, traits, i)) {
2832 if (colliding_ce == ce) {
2833 for (i = 0; i < current_trait; i++) {
2835 && zend_hash_exists(&traits[i]->properties_info, prop_name)) {
2841 return colliding_ce;
2873 bool is_compatible =
false;
2876 if (colliding_prop->
hooks || property_info->
hooks) {
2878 "%s and %s define the same hooked property ($%s) in the composition of %s. Conflict resolution between hooked properties is currently not supported. Class was composed",
2879 ZSTR_VAL(find_first_property_definition(ce, traits, i, prop_name, colliding_prop->
ce)->name),
2885 if ((colliding_prop->
flags & flags_mask) == (
flags & flags_mask) &&
2900 is_compatible = check_trait_property_or_constant_value_compatibility(ce,
op1,
op2);
2903 if (!is_compatible) {
2905 "%s and %s define the same property ($%s) in the composition of %s. However, the definition differs and is considered incompatible. Class was composed",
2906 ZSTR_VAL(find_first_property_definition(ce, traits, i, prop_name, colliding_prop->
ce)->name),
2919 "Readonly class %s cannot use trait with a non-readonly property %s::$%s",
2927 zval tmp_prop_value;
2937 prop_value = &tmp_prop_value;
2944 zend_type_copy_ctor(&
type,
true,
false);
2954 if (property_info->
hooks) {
2973 zend_fixup_trait_method(new_fn, ce);
2994 zend_traits_init_trait_structures(ce, traits, &exclude_tables, &aliases);
2997 zend_do_traits_method_binding(ce, traits, exclude_tables, aliases);
3003 if (exclude_tables) {
3004 efree(exclude_tables);
3008 zend_do_traits_constant_binding(ce, traits);
3009 zend_do_traits_property_binding(ce, traits);
3013#define MAX_ABSTRACT_INFO_CNT 3
3014#define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
3015#define DISPLAY_ABSTRACT_FN(idx) \
3016 ai.afn[idx] ? ZEND_FN_SCOPE_NAME(ai.afn[idx]) : "", \
3017 ai.afn[idx] ? "::" : "", \
3018 ai.afn[idx] ? ZSTR_VAL(ai.afn[idx]->common.function_name) : "", \
3019 ai.afn[idx] && ai.afn[idx + 1] ? ", " : (ai.afn[idx] && ai.cnt > MAX_ABSTRACT_INFO_CNT ? ", ..." : "")
3041 memset(&ai, 0,
sizeof(ai));
3048 zend_verify_abstract_class_function(
func, &ai);
3053 if (!is_explicit_abstract) {
3060 zend_verify_abstract_class_function(fn, &ai);
3071 zend_get_object_type_uc(ce),
3073 ai.
cnt > 1 ?
"s" :
"",
3120static void variance_obligation_dtor(
zval *
zv) {
3124static void variance_obligation_ht_dtor(
zval *
zv) {
3132 if (!
CG(delayed_variance_obligations)) {
3138 ht = zend_hash_index_find_ptr(
CG(delayed_variance_obligations),
key);
3145 zend_hash_index_add_new_ptr(
CG(delayed_variance_obligations),
key,
ht);
3151 HashTable *obligations = get_or_init_obligations_for_class(ce);
3153 obligation->
type = OBLIGATION_DEPENDENCY;
3155 zend_hash_next_index_insert_ptr(obligations, obligation);
3158static void add_compatibility_obligation(
3162 HashTable *obligations = get_or_init_obligations_for_class(ce);
3164 obligation->
type = OBLIGATION_COMPATIBILITY;
3178 zend_hash_next_index_insert_ptr(obligations, obligation);
3181static void add_property_compatibility_obligation(
3184 HashTable *obligations = get_or_init_obligations_for_class(ce);
3186 obligation->
type = OBLIGATION_PROPERTY_COMPATIBILITY;
3190 zend_hash_next_index_insert_ptr(obligations, obligation);
3193static void add_class_constant_compatibility_obligation(
3196 HashTable *obligations = get_or_init_obligations_for_class(ce);
3198 obligation->
type = OBLIGATION_CLASS_CONSTANT_COMPATIBILITY;
3202 zend_hash_next_index_insert_ptr(obligations, obligation);
3205static void add_property_hook_obligation(
3207 HashTable *obligations = get_or_init_obligations_for_class(ce);
3209 obligation->
type = OBLIGATION_PROPERTY_HOOK;
3212 zend_hash_next_index_insert_ptr(obligations, obligation);
3218 if (obligation->
type == OBLIGATION_DEPENDENCY) {
3223 CG(current_linking_class) =
3225 resolve_delayed_variance_obligations(dependency_ce);
3226 CG(current_linking_class) = orig_linking_class;
3228 }
else if (obligation->
type == OBLIGATION_COMPATIBILITY) {
3233 emit_incompatible_method_error(
3238 }
else if (obligation->
type == OBLIGATION_PROPERTY_COMPATIBILITY) {
3240 }
else if (obligation->
type == OBLIGATION_CLASS_CONSTANT_COMPATIBILITY) {
3246 }
else if (obligation->
type == OBLIGATION_PROPERTY_HOOK) {
3257 HashTable *delayed_autoloads =
CG(delayed_autoloads);
3258 if (!delayed_autoloads) {
3272 zend_string_addref(
name);
3275 zend_string_release(
name);
3278 "During inheritance of %s, while autoloading %s",
3285 HashTable *all_obligations =
CG(delayed_variance_obligations), *obligations;
3289 obligations = zend_hash_index_find_ptr(all_obligations, num_key);
3294 check_variance_obligation(obligation);
3309 if (
CG(unlinked_uses)
3312 "During inheritance of %s with variance dependencies",
ZSTR_VAL(ce->name));
3316#define zend_update_inherited_handler(handler) do { \
3317 if (ce->handler == (zend_function*)op_array) { \
3318 ce->handler = (zend_function*)new_op_array; \
3360 for (; src !=
end; src++, dst++) {
3373 for (;
p !=
end;
p++) {
3400 for (; src !=
end; src++, dst++) {
3413 for (;
p !=
end;
p++) {
3420 Z_PTR(
p->val) = new_prop_info;
3422 new_prop_info->
ce = ce;
3423 new_prop_info->
prototype = new_prop_info;
3425 zend_type_copy_ctor(&new_prop_info->
type,
true,
false);
3426 if (new_prop_info->
hooks) {
3430 if (new_prop_info->
hooks[i]) {
3434 new_prop_info->
ce = ce;
3449 for (;
p !=
end;
p++) {
3464#ifndef ZEND_OPCACHE_SHM_REATTACHMENT
3465# define UPDATE_IS_CACHEABLE(ce) do { \
3466 if ((ce)->type == ZEND_USER_CLASS) { \
3467 is_cacheable &= (ce)->ce_flags; \
3472# define UPDATE_IS_CACHEABLE(ce) do { \
3473 is_cacheable &= (ce)->ce_flags; \
3499 check_unrecoverable_load_failure(ce);
3520 for (
j = 0;
j < i;
j++) {
3521 if (traits_and_interfaces[
j] == trait) {
3527 traits_and_interfaces[i] = trait;
3541 check_unrecoverable_load_failure(ce);
3545 traits_and_interfaces[ce->
num_traits + i] = iface;
3555 is_cacheable =
false;
3559 bool orig_record_errors =
EG(record_errors);
3565 if (traits_and_interfaces) {
3585 ce = zend_lazy_class_load(ce);
3590 ce = zend_lazy_class_load(ce);
3596 if (
CG(unlinked_uses)) {
3600 orig_linking_class =
CG(current_linking_class);
3601 CG(current_linking_class) = is_cacheable ? ce :
NULL;
3609#ifdef ZEND_OPCACHE_SHM_REATTACHMENT
3610 zend_link_hooked_object_iter(ce);
3615 add_dependency_obligation(ce, parent);
3617 zend_do_inheritance(ce, parent);
3620 zend_do_bind_traits(ce, traits_and_interfaces);
3624 uint32_t num_parent_interfaces = parent ? parent->num_interfaces : 0;
3628 if (num_parent_interfaces) {
3632 memcpy(interfaces + num_parent_interfaces, traits_and_interfaces + ce->
num_traits,
3635 zend_do_implement_interfaces(ce, interfaces);
3636 }
else if (parent && parent->num_interfaces) {
3637 zend_do_inherit_interfaces(ce, parent);
3683 if (!orig_record_errors) {
3684 EG(record_errors) =
false;
3690 EG(record_errors) = orig_record_errors;
3697 if (
CG(current_linking_class)) {
3700 load_delayed_classes(ce);
3702 resolve_delayed_variance_obligations(ce);
3707 CG(current_linking_class) =
NULL;
3711 if (!
CG(current_linking_class)) {
3714 CG(current_linking_class) = orig_linking_class;
3733 if (!orig_record_errors) {
3736 if (traits_and_interfaces) {
3762 do_inheritance_check_on_method(
3785 inheritance_status status = verify_property_type_compatibility(parent_info, child_info, prop_get_variance(parent_info),
false,
false);
3812 return overall_status;
3817 if (delayed_early_binding) {
3820 Z_CE_P(delayed_early_binding) = ce;
3825 if (zend_hash_add_ptr(
EG(class_table),
lcname, ce) !=
NULL) {
3834 if (zend_hash_add_ptr(
CG(class_table),
lcname, ce) !=
NULL) {
3848 if (
UNEXPECTED(!register_early_bound_ce(delayed_early_binding,
lcname, ce))) {
3851 zend_observer_class_linked_notify(ce,
lcname);
3864 zend_observer_class_linked_notify(
ret,
lcname);
3873 orig_linking_class =
CG(current_linking_class);
3874 CG(current_linking_class) =
NULL;
3875 status = zend_can_early_bind(ce, parent_ce);
3876 CG(current_linking_class) = orig_linking_class;
3880 ce = zend_lazy_class_load(ce);
3883 ce = zend_lazy_class_load(ce);
3887 if (
UNEXPECTED(!register_early_bound_ce(delayed_early_binding,
lcname, ce))) {
3891 orig_linking_class =
CG(current_linking_class);
3892 CG(current_linking_class) = is_cacheable ? ce :
NULL;
3901#ifdef ZEND_OPCACHE_SHM_REATTACHMENT
3902 zend_link_hooked_object_iter(ce);
3907 zend_do_inherit_interfaces(ce, parent_ce);
3917 CG(current_linking_class) = orig_linking_class;
3919 EG(record_errors) =
false;
3924 EG(record_errors) =
false;
3946 zend_observer_class_linked_notify(ce,
lcname);
memset(ptr, 0, type->size)
unsigned const char * end
unsigned const char * pos
php_output_handler * active
unsigned char key[REFLECTION_KEY_LEN]
const zend_function * afn[MAX_ABSTRACT_INFO_CNT+1]
HashTable constants_table
zend_function * __debugInfo
zend_object *(* create_object)(zend_class_entry *class_type)
zend_function * __tostring
struct _zend_module_entry * module
zval * default_static_members_table
struct _zend_class_entry::@126215362204241324314155352336150042254204116267::@166057154351252324007362117353350250255142166322 user
uint32_t num_hooked_props
HashTable properties_info
zend_trait_precedence ** trait_precedences
zend_object_iterator *(* get_iterator)(zend_class_entry *ce, zval *object, int by_ref)
zend_class_name * trait_names
zend_class_name * interface_names
zend_function * __unserialize
union _zend_class_entry::@126215362204241324314155352336150042254204116267 info
struct _zend_class_entry::@126215362204241324314155352336150042254204116267::@031207115026352130035014265255253014334154061307 internal
zend_string * parent_name
int default_properties_count
zend_function * __serialize
zend_trait_alias ** trait_aliases
zend_class_entry ** interfaces
int default_static_members_count
int(* interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type)
zend_function * constructor
uint32_t num_hooked_prop_variance_checks
zend_inheritance_cache_entry * inheritance_cache
struct _zend_property_info ** properties_info_table
zend_class_entry * parent
int(* serialize)(zval *object, unsigned char **buffer, size_t *buf_len, zend_serialize_data *data)
zval * default_properties_table
int(* unserialize)(zval *object, zend_class_entry *ce, const unsigned char *buf, size_t buf_len, zend_unserialize_data *data)
const zend_object_handlers * default_object_handlers
zend_function * __callstatic
zend_function * destructor
zend_function * prototype
HashTable * static_variables
const zend_property_info * prop_info
const zend_property_info * prototype
zend_string * doc_comment
zend_trait_method_reference trait_method
zend_string * method_name
zend_trait_method_reference trait_method
zend_string * exclude_class_names[1]
const zend_property_info * child_prop
const zend_class_constant * parent_const
const zend_property_info * hooked_prop
zend_class_entry * dependency_ce
enum variance_obligation::@330322236061147115211222154203135051132232375075 type
const zend_property_info * parent_prop
zend_class_entry * parent_scope
const zend_string * const_name
zend_class_entry * child_scope
const zend_class_constant * child_const
const zend_function * hook_func
@ OBLIGATION_CLASS_CONSTANT_COMPATIBILITY
@ OBLIGATION_PROPERTY_HOOK
@ OBLIGATION_COMPATIBILITY
@ OBLIGATION_PROPERTY_COMPATIBILITY
zend_function * prototype
uint32_t required_num_args
const zend_property_info * prop_info
zend_string * function_name
struct _zend_function::@236135173067030250234125302313220025134003177336 common
ZEND_API ZEND_COLD void zend_error_at(int type, zend_string *filename, uint32_t lineno, const char *format,...)
ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format,...)
ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_at_noreturn(int type, zend_string *filename, uint32_t lineno, const char *format,...)
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
ZEND_API void zend_free_recorded_errors(void)
ZEND_API void zend_begin_record_errors(void)
struct _zend_inheritance_cache_entry zend_inheritance_cache_entry
struct _zend_trait_precedence zend_trait_precedence
struct _zend_trait_alias zend_trait_alias
struct _zend_trait_method_reference zend_trait_method_reference
ZEND_API ZEND_COLD const char * zend_get_object_type_case(const zend_class_entry *ce, bool upper_case)
ZEND_API zend_property_info * zend_declare_typed_property(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, zend_type type)
ZEND_API ZEND_COLD void zend_class_redeclaration_error(int type, zend_class_entry *old_ce)
ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, zend_string *lcname)
#define perealloc(ptr, size, persistent)
#define ecalloc(nmemb, size)
#define pefree(ptr, persistent)
#define pemalloc(size, persistent)
#define FREE_HASHTABLE(ht)
#define erealloc(ptr, size)
#define ALLOC_HASHTABLE(ht)
ZEND_API zend_attribute * zend_get_attribute_str(HashTable *attributes, const char *str, size_t len)
struct _zend_attribute zend_attribute
zend_string_release_ex(func->internal_function.function_name, 0)
zend_string * zend_type_to_string_resolved(zend_type type, zend_class_entry *scope)
ZEND_API void function_add_ref(zend_function *function)
#define ZEND_PROPERTY_HOOK_COUNT
#define ZEND_ACC_UNRESOLVED_VARIANCE
#define OBJ_PROP_TO_NUM(offset)
#define ZEND_USER_CODE(type)
#define ZEND_ACC_CACHEABLE
#define ZEND_ACC_IMMUTABLE
#define ZEND_ACC_NOT_SERIALIZABLE
#define ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED
#define ZEND_COMPILE_PRELOAD
#define ZEND_HAS_STATIC_IN_METHODS
#define ZEND_ACC_HAS_TYPE_HINTS
#define ZEND_ACC_IMPLICIT_ABSTRACT_CLASS
#define ZEND_INTERNAL_FUNCTION
#define ZEND_ACC_ABSTRACT
#define ZEND_ACC_HAS_READONLY_PROPS
#define ZEND_CLASS_CONST_FLAGS(c)
#define ZEND_ACC_TRAIT_CLONE
#define ZEND_ACC_READONLY
#define ZEND_ACC_PROTECTED_SET
#define ZEND_ARG_SEND_MODE(arg_info)
#define ZEND_FETCH_CLASS_TRAIT
#define ZEND_ACC_PPP_SET_MASK
#define ZEND_COMPILE_IGNORE_OTHER_FILES
#define ZEND_ACC_NEARLY_LINKED
#define ZEND_FUNCTION_DTOR
#define ZEND_FETCH_CLASS_INTERFACE
#define ZEND_FETCH_CLASS_NO_AUTOLOAD
#define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS
#define ZEND_USER_FUNCTION
#define ZEND_ACC_INTERFACE
#define ZEND_ACC_PRIVATE_SET
#define ZEND_ACC_HAS_AST_CONSTANTS
struct _zend_op_array zend_op_array
#define ZEND_ACC_READONLY_CLASS
#define ZEND_PROPERTY_HOOK_STRUCT_SIZE
struct _zend_class_constant zend_class_constant
struct _zend_property_info zend_property_info
#define ZEND_ACC_HAS_AST_PROPERTIES
#define ZEND_ACC_RESOLVED_PARENT
#define ZEND_COMPILE_IGNORE_INTERNAL_CLASSES
#define ZEND_ACC_PRELOADED
#define ZEND_VIRTUAL_PROPERTY_OFFSET
#define ZEND_ACC_USE_GUARDS
#define ZEND_ARG_TYPE_IS_TENTATIVE(arg_info)
#define ZEND_ACC_CONSTANTS_UPDATED
struct _zend_internal_arg_info zend_internal_arg_info
#define ZEND_ACC_ANON_CLASS
#define ZEND_ACC_HAS_AST_STATICS
#define ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES
#define RT_CONSTANT(opline, node)
#define ZEND_ACC_PPP_MASK
#define ZEND_ARG_IS_VARIADIC(arg_info)
#define ZEND_FETCH_CLASS_EXCEPTION
#define ZEND_ACC_HAS_RETURN_TYPE
struct _zend_arg_info zend_arg_info
#define ZEND_ACC_PUBLIC_SET
#define ZEND_ACC_FILE_CACHED
#define ZEND_ACC_RESOLVED_INTERFACES
#define ZEND_ACC_ARENA_ALLOCATED
#define ZEND_ACC_VARIADIC
#define ZEND_FETCH_CLASS_ALLOW_UNLINKED
#define OBJ_PROP_TO_OFFSET(num)
#define ZEND_ACC_OVERRIDE
#define ZEND_INTERNAL_CLASS
#define ZEND_CONSTRUCTOR_FUNC_NAME
struct _zend_internal_function zend_internal_function
#define ZEND_ACC_RETURN_REFERENCE
char * zend_visibility_string(uint32_t fn_flags)
#define ZEND_FN_SCOPE_NAME(function)
#define ZEND_ACC_PROTECTED
void zend_verify_enum(const zend_class_entry *ce)
void zend_enum_register_funcs(zend_class_entry *ce)
#define E_COMPILE_WARNING
ZEND_NORETURN void zend_exception_uncaught_error(const char *format,...)
ZEND_API zend_class_entry * zend_lookup_class(zend_string *name)
ZEND_API zend_class_entry * zend_fetch_class_by_name(zend_string *class_name, zend_string *lcname, uint32_t fetch_type)
ZEND_API zend_result ZEND_FASTCALL zval_update_constant_ex(zval *pp, zend_class_entry *scope)
ZEND_API zend_class_entry * zend_lookup_class_ex(zend_string *name, zend_string *lcname, uint32_t flags)
union _zend_function zend_function
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_set_bucket_key(HashTable *ht, Bucket *b, zend_string *key)
ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, const HashPosition *pos)
ZEND_API zend_result ZEND_FASTCALL zend_hash_index_del(HashTable *ht, zend_ulong h)
ZEND_API zval *ZEND_FASTCALL zend_hash_find_known_hash(const HashTable *ht, const zend_string *key)
ZEND_API void ZEND_FASTCALL zend_hash_extend(HashTable *ht, uint32_t nSize, bool packed)
ZEND_API zval *ZEND_FASTCALL zend_hash_add_empty_element(HashTable *ht, zend_string *key)
ZEND_API zend_result ZEND_FASTCALL zend_hash_del(HashTable *ht, zend_string *key)
ZEND_API zval *ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *key)
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
#define HASH_KEY_NON_EXISTENT
#define ZEND_HASH_FOREACH_STR_KEY_PTR(ht, _key, _ptr)
#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr)
#define ZEND_HASH_FOREACH_PTR(ht, _ptr)
#define HASH_FLAG_UNINITIALIZED
#define ZEND_HASH_MAP_FOREACH_STR_KEY(ht, _key)
#define ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(ht, _key, _ptr)
#define ZEND_HASH_FOREACH_END()
ZEND_API zend_class_entry * zend_try_early_bind(zend_class_entry *ce, zend_class_entry *parent_ce, zend_string *lcname, zval *delayed_early_binding)
ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface)
#define MAX_ABSTRACT_INFO_CNT
#define ZEND_INHERITANCE_CHECK_PROTO
#define ZEND_INHERITANCE_LAZY_CHILD_CLONE
void zend_inheritance_check_override(zend_class_entry *ce)
struct _zend_abstract_info zend_abstract_info
ZEND_API inheritance_status zend_perform_covariant_type_check(zend_class_entry *fe_scope, zend_type fe_type, zend_class_entry *proto_scope, zend_type proto_type)
ZEND_API ZEND_COLD ZEND_NORETURN void zend_hooked_property_variance_error(const zend_property_info *prop_info)
void zend_build_properties_info_table(zend_class_entry *ce)
ZEND_API zend_class_entry *(* zend_inheritance_cache_add)(zend_class_entry *ce, zend_class_entry *proto, zend_class_entry *parent, zend_class_entry **traits_and_interfaces, HashTable *dependencies)
zend_inheritance_status inheritance_status
#define SEPARATE_METHOD()
#define ZEND_INHERITANCE_RESET_CHILD_OVERRIDE
ZEND_API void zend_verify_hooked_property(zend_class_entry *ce, zend_property_info *prop_info, zend_string *prop_name)
ZEND_API void zend_do_inheritance_ex(zend_class_entry *ce, zend_class_entry *parent_ce, bool checked)
ZEND_API zend_class_entry * zend_do_link_class(zend_class_entry *ce, zend_string *lc_parent_name, zend_string *key)
#define ZEND_INHERITANCE_CHECK_VISIBILITY
ZEND_API zend_class_entry *(* zend_inheritance_cache_get)(zend_class_entry *ce, zend_class_entry *parent, zend_class_entry **traits_and_interfaces)
#define ZEND_INHERITANCE_SET_CHILD_CHANGED
#define MAX_ABSTRACT_INFO_FMT
#define ZEND_INHERITANCE_SET_CHILD_PROTO
#define DISPLAY_ABSTRACT_FN(idx)
ZEND_API inheritance_status zend_verify_property_hook_variance(const zend_property_info *prop_info, const zend_function *func)
ZEND_API ZEND_COLD ZEND_NORETURN void zend_hooked_property_variance_error_ex(zend_string *value_param_name, zend_string *class_name, zend_string *prop_name)
#define zend_update_inherited_handler(handler)
#define ZEND_INHERITANCE_CHECK_SILENT
void zend_verify_abstract_class(zend_class_entry *ce)
#define UPDATE_IS_CACHEABLE(ce)
char * zend_visibility_string(uint32_t fn_flags)
ZEND_API zend_class_entry * zend_ce_stringable
struct _zend_string zend_string
#define ZEND_MAP_PTR_INIT(ptr, val)
#define ZEND_MAP_PTR_NEW(ptr)
#define ZEND_MAP_PTR(ptr)
#define MODULE_PERSISTENT
ZEND_API bool ZEND_FASTCALL zend_class_implements_interface(const zend_class_entry *class_ce, const zend_class_entry *interface_ce)
#define ALLOCA_FLAG(name)
#define EXPECTED(condition)
#define do_alloca(p, use_heap)
#define zend_always_inline
#define ZEND_UNREACHABLE()
#define free_alloca(p, use_heap)
#define EMPTY_SWITCH_DEFAULT_CASE()
#define UNEXPECTED(condition)
#define SET_ALLOCA_FLAG(name)
ZEND_API zend_object_iterator * zend_hooked_object_get_iterator(zend_class_entry *ce, zval *object, int by_ref)
struct _zend_class_entry zend_class_entry
#define zend_string_equals_ci(s1, s2)
#define zend_string_equals_literal_ci(str, c)
#define ZEND_TYPE_PURE_MASK(t)
#define Z_TRY_ADDREF_P(pz)
#define ZEND_TYPE_NAME(t)
#define Z_STRVAL_P(zval_p)
#define Z_CONSTANT_FLAGS(zval)
#define Z_ARRVAL_P(zval_p)
#define _ZEND_TYPE_ARENA_BIT
#define ZEND_TYPE_IS_INTERSECTION(t)
#define Z_REFCOUNTED_P(zval_p)
#define ZVAL_COPY_VALUE_PROP(z, v)
#define ZSTR_SET_CE_CACHE(s, ce)
#define ZVAL_INDIRECT(z, v)
struct _zend_array HashTable
#define ZVAL_COPY_OR_DUP(z, v)
#define ZEND_TYPE_LIST_SIZE(num_types)
#define ZEND_TYPE_HAS_NAME(t)
#define ZSTR_HAS_CE_CACHE(s)
#define ZEND_TYPE_FULL_MASK(t)
#define ZEND_TYPE_FOREACH(type, type_ptr)
#define ZEND_TYPE_HAS_LIST(t)
#define Z_STRLEN_P(zval_p)
#define ZEND_TYPE_LIST_FOREACH_END()
#define ZEND_TYPE_SET_LIST(t, list)
#define ZEND_TYPE_IS_SET(t)
#define ZEND_TYPE_FOREACH_END()
#define HT_GET_DATA_ADDR(ht)
#define Z_INDIRECT_P(zval_p)
#define HT_SET_DATA_ADDR(ht, ptr)
#define IS_ARRAY_IMMUTABLE
#define ZVAL_COPY_PROP(z, v)
#define ZEND_TYPE_LIST_FOREACH(list, type_ptr)
#define ZEND_TYPE_CONTAINS_CODE(t, code)
#define ZEND_TYPE_LIST(t)
struct _zend_ast zend_ast
#define Z_ASTVAL_P(zval_p)
#define ZVAL_COPY_VALUE(z, v)
#define ZVAL_DEINDIRECT(z)
#define Z_OPT_TYPE_P(zval_p)
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
zend_property_info * prop_info