diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-09-11 16:27:28 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-09-11 16:27:28 +0200 |
commit | 270e5e3c5b7b6bf39dfbef67381990b553a52a96 (patch) | |
tree | 3be47869ab46c9650ad488e7ea86c9c4a21f12f9 /Zend/zend_inheritance.c | |
parent | b7c353c8d03595f544b0ce87bf46e741f6a45ebe (diff) | |
download | php-git-270e5e3c5b7b6bf39dfbef67381990b553a52a96.tar.gz |
Only allow "nearly linked" classes for parent/interface
The requirements for parent/interface are difference than for the
variance checks in type declarations. The latter can work on fully
unlinked classes, but the former need inheritance to be essentially
finished, only variance checks may still be outstanding.
Adding a new flag for this because we have lots of space, but we
could also represent these "inheritance states" more compactly in
the future.
Diffstat (limited to 'Zend/zend_inheritance.c')
-rw-r--r-- | Zend/zend_inheritance.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 9c8acca865..a108b2e85e 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -1005,9 +1005,8 @@ static inline void do_implement_interface(zend_class_entry *ce, zend_class_entry if (!(ce->ce_flags & ZEND_ACC_INTERFACE) && iface->interface_gets_implemented && iface->interface_gets_implemented(iface, ce) == FAILURE) { zend_error_noreturn(E_CORE_ERROR, "Class %s could not implement interface %s", ZSTR_VAL(ce->name), ZSTR_VAL(iface->name)); } - if (UNEXPECTED(ce == iface)) { - zend_error_noreturn(E_ERROR, "Interface %s cannot implement itself", ZSTR_VAL(ce->name)); - } + /* This should be prevented by the class lookup logic. */ + ZEND_ASSERT(ce != iface); } /* }}} */ @@ -1457,7 +1456,7 @@ static void zend_do_implement_interfaces(zend_class_entry *ce) /* {{{ */ for (i = 0; i < ce->num_interfaces; i++) { iface = zend_fetch_class_by_name( ce->interface_names[i].name, ce->interface_names[i].lc_name, - ZEND_FETCH_CLASS_INTERFACE|ZEND_FETCH_CLASS_ALLOW_UNLINKED); + ZEND_FETCH_CLASS_INTERFACE|ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED); if (!(iface->ce_flags & ZEND_ACC_LINKED)) { add_dependency_obligation(ce, iface); } @@ -2404,7 +2403,7 @@ ZEND_API void zend_do_link_class(zend_class_entry *ce, zend_string *lc_parent_na { if (ce->parent_name) { zend_class_entry *parent = zend_fetch_class_by_name( - ce->parent_name, lc_parent_name, ZEND_FETCH_CLASS_ALLOW_UNLINKED); + ce->parent_name, lc_parent_name, ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED); if (!(parent->ce_flags & ZEND_ACC_LINKED)) { add_dependency_obligation(ce, parent); } @@ -2427,6 +2426,7 @@ ZEND_API void zend_do_link_class(zend_class_entry *ce, zend_string *lc_parent_na return; } + ce->ce_flags |= ZEND_ACC_NEARLY_LINKED; load_delayed_classes(); if (ce->ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE) { resolve_delayed_variance_obligations(ce); |