mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-7.4'
This commit is contained in:
commit
c3ee12e786
7 changed files with 36 additions and 7 deletions
|
@ -10,4 +10,4 @@ var_dump($a instanceOf A);
|
||||||
echo "ok\n";
|
echo "ok\n";
|
||||||
?>
|
?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Fatal error: Interface RecurisiveFooFar cannot implement itself in %sbug30922.php on line %d
|
Fatal error: Interface 'RecurisiveFooFar' not found in %sbug30922.php on line %d
|
||||||
|
|
20
Zend/tests/use_unlinked_class.phpt
Normal file
20
Zend/tests/use_unlinked_class.phpt
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
--TEST--
|
||||||
|
Classes can only be used once they are fully linked
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
spl_autoload_register(function($class) {
|
||||||
|
echo new ReflectionClass(A::class), "\n";
|
||||||
|
});
|
||||||
|
|
||||||
|
class A implements I {
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Fatal error: During class fetch: Uncaught ReflectionException: Class A does not exist in %s:%d
|
||||||
|
Stack trace:
|
||||||
|
#0 %s(%d): ReflectionClass->__construct('A')
|
||||||
|
#1 [internal function]: {closure}('I')
|
||||||
|
#2 %s(%d): spl_autoload_call('I')
|
||||||
|
#3 {main} in %s on line %d
|
|
@ -269,6 +269,9 @@ typedef struct _zend_oparray_context {
|
||||||
/* Children must reuse parent get_iterator() | | | */
|
/* Children must reuse parent get_iterator() | | | */
|
||||||
#define ZEND_ACC_REUSE_GET_ITERATOR (1 << 18) /* X | | | */
|
#define ZEND_ACC_REUSE_GET_ITERATOR (1 << 18) /* X | | | */
|
||||||
/* | | | */
|
/* | | | */
|
||||||
|
/* Class is being linked. Don't free strings. | | | */
|
||||||
|
#define ZEND_ACC_LINKING_IN_PROGRESS (1 << 19) /* X | | | */
|
||||||
|
/* | | | */
|
||||||
/* Function Flags (unused: 28...30) | | | */
|
/* Function Flags (unused: 28...30) | | | */
|
||||||
/* ============== | | | */
|
/* ============== | | | */
|
||||||
/* | | | */
|
/* | | | */
|
||||||
|
|
|
@ -861,7 +861,11 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *
|
||||||
if (!key) {
|
if (!key) {
|
||||||
zend_string_release_ex(lc_name, 0);
|
zend_string_release_ex(lc_name, 0);
|
||||||
}
|
}
|
||||||
return (zend_class_entry*)Z_PTR_P(zv);
|
ce = (zend_class_entry*)Z_PTR_P(zv);
|
||||||
|
if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_LINKED))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return ce;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The compiler is not-reentrant. Make sure we __autoload() only during run-time
|
/* The compiler is not-reentrant. Make sure we __autoload() only during run-time
|
||||||
|
|
|
@ -1961,7 +1961,7 @@ void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */
|
||||||
|
|
||||||
ZEND_API void zend_do_link_class(zend_class_entry *ce, zend_class_entry *parent) /* {{{ */
|
ZEND_API void zend_do_link_class(zend_class_entry *ce, zend_class_entry *parent) /* {{{ */
|
||||||
{
|
{
|
||||||
ce->ce_flags |= ZEND_ACC_LINKED;
|
ce->ce_flags |= ZEND_ACC_LINKING_IN_PROGRESS;
|
||||||
if (parent) {
|
if (parent) {
|
||||||
zend_do_inheritance(ce, parent);
|
zend_do_inheritance(ce, parent);
|
||||||
}
|
}
|
||||||
|
@ -1976,5 +1976,7 @@ ZEND_API void zend_do_link_class(zend_class_entry *ce, zend_class_entry *parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
zend_build_properties_info_table(ce);
|
zend_build_properties_info_table(ce);
|
||||||
|
ce->ce_flags &= ~ZEND_ACC_LINKING_IN_PROGRESS;
|
||||||
|
ce->ce_flags |= ZEND_ACC_LINKED;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
|
@ -291,7 +291,7 @@ static int zend_implement_traversable(zend_class_entry *interface, zend_class_en
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
if (class_type->num_interfaces) {
|
if (class_type->num_interfaces) {
|
||||||
ZEND_ASSERT(class_type->ce_flags & ZEND_ACC_LINKED);
|
ZEND_ASSERT(class_type->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_LINKING_IN_PROGRESS));
|
||||||
for (i = 0; i < class_type->num_interfaces; i++) {
|
for (i = 0; i < class_type->num_interfaces; i++) {
|
||||||
if (class_type->interfaces[i] == zend_ce_aggregate || class_type->interfaces[i] == zend_ce_iterator) {
|
if (class_type->interfaces[i] == zend_ce_aggregate || class_type->interfaces[i] == zend_ce_iterator) {
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
@ -321,7 +321,7 @@ static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entr
|
||||||
} else if (class_type->get_iterator != zend_user_it_get_new_iterator) {
|
} else if (class_type->get_iterator != zend_user_it_get_new_iterator) {
|
||||||
/* c-level get_iterator cannot be changed (exception being only Traversable is implemented) */
|
/* c-level get_iterator cannot be changed (exception being only Traversable is implemented) */
|
||||||
if (class_type->num_interfaces) {
|
if (class_type->num_interfaces) {
|
||||||
ZEND_ASSERT(class_type->ce_flags & ZEND_ACC_LINKED);
|
ZEND_ASSERT(class_type->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_LINKING_IN_PROGRESS));
|
||||||
for (i = 0; i < class_type->num_interfaces; i++) {
|
for (i = 0; i < class_type->num_interfaces; i++) {
|
||||||
if (class_type->interfaces[i] == zend_ce_iterator) {
|
if (class_type->interfaces[i] == zend_ce_iterator) {
|
||||||
zend_error_noreturn(E_ERROR, "Class %s cannot implement both %s and %s at the same time",
|
zend_error_noreturn(E_ERROR, "Class %s cannot implement both %s and %s at the same time",
|
||||||
|
|
|
@ -238,7 +238,7 @@ ZEND_API void destroy_zend_class(zval *zv)
|
||||||
}
|
}
|
||||||
switch (ce->type) {
|
switch (ce->type) {
|
||||||
case ZEND_USER_CLASS:
|
case ZEND_USER_CLASS:
|
||||||
if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_LINKED)) {
|
if (ce->parent_name && !(ce->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_LINKING_IN_PROGRESS))) {
|
||||||
zend_string_release_ex(ce->parent_name, 0);
|
zend_string_release_ex(ce->parent_name, 0);
|
||||||
}
|
}
|
||||||
if (ce->default_properties_table) {
|
if (ce->default_properties_table) {
|
||||||
|
@ -298,7 +298,7 @@ ZEND_API void destroy_zend_class(zval *zv)
|
||||||
}
|
}
|
||||||
zend_hash_destroy(&ce->constants_table);
|
zend_hash_destroy(&ce->constants_table);
|
||||||
if (ce->num_interfaces > 0) {
|
if (ce->num_interfaces > 0) {
|
||||||
if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
|
if (!(ce->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_LINKING_IN_PROGRESS))) {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < ce->num_interfaces; i++) {
|
for (i = 0; i < ce->num_interfaces; i++) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue