summaryrefslogtreecommitdiff
path: root/Zend/zend_inheritance.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-09-11 16:27:28 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-09-11 16:27:28 +0200
commit270e5e3c5b7b6bf39dfbef67381990b553a52a96 (patch)
tree3be47869ab46c9650ad488e7ea86c9c4a21f12f9 /Zend/zend_inheritance.c
parentb7c353c8d03595f544b0ce87bf46e741f6a45ebe (diff)
downloadphp-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.c10
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);