return FAILURE;
} else {
ce->refcount++;
- if (ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS) {
- zend_do_bind_traits(ce);
- }
- if (ce->ce_flags & ZEND_ACC_IMPLEMENT_INTERFACES) {
- zend_do_implement_interfaces(ce);
- } else if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
- zend_verify_abstract_class(ce);
- }
+ zend_do_link_class(ce, NULL);
return SUCCESS;
}
}
ce = (zend_class_entry*)Z_PTR_P(zv);
- if (zend_hash_exists(EG(class_table), Z_STR_P(lcname))) {
- zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name));
- }
-
- zend_do_inheritance(ce, parent_ce);
-
ce->refcount++;
/* Register the derived class */
zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name));
}
- if (ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS) {
- zend_do_bind_traits(ce);
- }
- if (ce->ce_flags & ZEND_ACC_IMPLEMENT_INTERFACES) {
- zend_do_implement_interfaces(ce);
- }
+ zend_do_link_class(ce, parent_ce);
return SUCCESS;
}
if (implements_ast) {
zend_compile_implements(implements_ast);
- if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
- zend_verify_abstract_class(ce);
- }
- } else if (extends_ast) {
- if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
- zend_verify_abstract_class(ce);
- }
+ }
+
+ if ((ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) == ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) {
+ zend_verify_abstract_class(ce);
}
CG(active_class_entry) = original_ce;
if (EXPECTED(zend_hash_add_ptr(CG(class_table), lcname, ce) != NULL)) {
CG(zend_lineno) = decl->end_lineno;
zend_do_inheritance(ce, parent_ce);
+ if ((ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) == ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) {
+ zend_verify_abstract_class(ce);
+ }
CG(zend_lineno) = ast->lineno;
zend_string_release(lcname);
return;
}
}
} else {
- if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
- CG(zend_lineno) = decl->end_lineno;
- zend_verify_abstract_class(ce);
- CG(zend_lineno) = ast->lineno;
- }
if (EXPECTED(zend_hash_add_ptr(CG(class_table), lcname, ce) != NULL)) {
zend_string_release(lcname);
return;
do_inherit_parent_constructor(ce);
- if (ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS && ce->type == ZEND_INTERNAL_CLASS) {
- ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
- } else if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS|ZEND_ACC_IMPLEMENT_INTERFACES|ZEND_ACC_IMPLEMENT_TRAITS))) {
- /* The verification will be done in runtime by ZEND_VERIFY_ABSTRACT_CLASS */
- zend_verify_abstract_class(ce);
+ if (ce->type == ZEND_INTERNAL_CLASS) {
+ if (ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) {
+ ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
+ }
}
ce->ce_flags |= parent_ce->ce_flags & (ZEND_HAS_STATIC_IN_METHODS | ZEND_ACC_USE_GUARDS);
}
}
/* }}} */
-ZEND_API void zend_do_implement_interfaces(zend_class_entry *ce) /* {{{ */
+static void zend_do_implement_interfaces(zend_class_entry *ce) /* {{{ */
{
zend_class_entry **interfaces, *iface;
uint32_t num_interfaces = 0;
zend_do_inherit_interfaces(ce, iface);
}
}
-
- if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
- zend_verify_abstract_class(ce);
- }
}
/* }}} */
}
/* }}} */
-ZEND_API void zend_do_bind_traits(zend_class_entry *ce) /* {{{ */
+static void zend_do_bind_traits(zend_class_entry *ce) /* {{{ */
{
HashTable **exclude_tables;
zend_class_entry **aliases;
efree(traits);
- /* verify that all abstract methods from traits have been implemented */
- zend_verify_abstract_class(ce);
-
/* Emit E_DEPRECATED for PHP 4 constructors */
zend_check_deprecated_constructor(ce);
-
- /* now everything should be fine and an added ZEND_ACC_IMPLICIT_ABSTRACT_CLASS should be removed */
- if (ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) {
- ce->ce_flags -= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
- }
}
/* }}} */
zend_function *func;
zend_abstract_info ai;
- if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & (ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
- memset(&ai, 0, sizeof(ai));
+ ZEND_ASSERT((ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) == ZEND_ACC_IMPLICIT_ABSTRACT_CLASS);
+ memset(&ai, 0, sizeof(ai));
- ZEND_HASH_FOREACH_PTR(&ce->function_table, func) {
- zend_verify_abstract_class_function(func, &ai);
- } ZEND_HASH_FOREACH_END();
+ ZEND_HASH_FOREACH_PTR(&ce->function_table, func) {
+ zend_verify_abstract_class_function(func, &ai);
+ } ZEND_HASH_FOREACH_END();
- if (ai.cnt) {
- zend_error_noreturn(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")",
- ZSTR_VAL(ce->name), ai.cnt,
- ai.cnt > 1 ? "s" : "",
- DISPLAY_ABSTRACT_FN(0),
- DISPLAY_ABSTRACT_FN(1),
- DISPLAY_ABSTRACT_FN(2)
- );
- }
+ if (ai.cnt) {
+ zend_error_noreturn(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")",
+ ZSTR_VAL(ce->name), ai.cnt,
+ ai.cnt > 1 ? "s" : "",
+ DISPLAY_ABSTRACT_FN(0),
+ DISPLAY_ABSTRACT_FN(1),
+ DISPLAY_ABSTRACT_FN(2)
+ );
+ } else {
+ /* now everything should be fine and an added ZEND_ACC_IMPLICIT_ABSTRACT_CLASS should be removed */
+ ce->ce_flags &= ~ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
+ }
+}
+/* }}} */
+
+ZEND_API void zend_do_link_class(zend_class_entry *ce, zend_class_entry *parent) /* {{{ */
+{
+ if (parent) {
+ zend_do_inheritance(ce, parent);
+ }
+ if (ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS) {
+ zend_do_bind_traits(ce);
+ }
+ if (ce->ce_flags & ZEND_ACC_IMPLEMENT_INTERFACES) {
+ zend_do_implement_interfaces(ce);
+ }
+ if ((ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) == ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) {
+ zend_verify_abstract_class(ce);
}
}
/* }}} */
BEGIN_EXTERN_C()
ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface);
-
-ZEND_API void zend_do_bind_traits(zend_class_entry *ce);
-ZEND_API void zend_do_implement_interfaces(zend_class_entry *ce);
-
ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce);
+ZEND_API void zend_do_link_class(zend_class_entry *ce, zend_class_entry *parent_ce);
+
void zend_verify_abstract_class(zend_class_entry *ce);
void zend_check_deprecated_constructor(const zend_class_entry *ce);
ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
ZEND_VM_CONTINUE();
}
- if (ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS) {
- zend_do_bind_traits(ce);
- }
- if (ce->ce_flags & ZEND_ACC_IMPLEMENT_INTERFACES) {
- zend_do_implement_interfaces(ce);
- } else if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
- zend_verify_abstract_class(ce);
- }
+ zend_do_link_class(ce, NULL);
ce->ce_flags |= ZEND_ACC_ANON_BOUND;
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
HANDLE_EXCEPTION();
}
- zend_do_inheritance(ce, parent);
- if (ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS) {
- zend_do_bind_traits(ce);
- }
- if (ce->ce_flags & ZEND_ACC_IMPLEMENT_INTERFACES) {
- zend_do_implement_interfaces(ce);
- }
+ zend_do_link_class(ce, parent);
ce->ce_flags |= ZEND_ACC_ANON_BOUND;
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
ZEND_VM_CONTINUE();
}
- if (ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS) {
- zend_do_bind_traits(ce);
- }
- if (ce->ce_flags & ZEND_ACC_IMPLEMENT_INTERFACES) {
- zend_do_implement_interfaces(ce);
- } else if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
- zend_verify_abstract_class(ce);
- }
+ zend_do_link_class(ce, NULL);
ce->ce_flags |= ZEND_ACC_ANON_BOUND;
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
HANDLE_EXCEPTION();
}
- zend_do_inheritance(ce, parent);
- if (ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS) {
- zend_do_bind_traits(ce);
- }
- if (ce->ce_flags & ZEND_ACC_IMPLEMENT_INTERFACES) {
- zend_do_implement_interfaces(ce);
- }
+ zend_do_link_class(ce, parent);
ce->ce_flags |= ZEND_ACC_ANON_BOUND;
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}