summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-12-10 11:55:14 +0100
committerNikita Popov <nikita.ppv@gmail.com>2019-12-10 13:06:36 +0100
commitbaf3a9133bf0bc7069e5191b780c221485b2dda6 (patch)
tree57fabe030d1454468eb346afc7325784a04b3b71
parent3f86adb0efab3a68d87645941dc997d1e6314050 (diff)
downloadphp-git-baf3a9133bf0bc7069e5191b780c221485b2dda6.tar.gz
Add support for class_alias to preloading
Related to bug #78918.
-rw-r--r--ext/opcache/tests/preload_class_alias.inc3
-rw-r--r--ext/opcache/tests/preload_class_alias.phpt17
-rw-r--r--ext/opcache/zend_persist.c6
-rw-r--r--ext/opcache/zend_persist_calc.c6
4 files changed, 32 insertions, 0 deletions
diff --git a/ext/opcache/tests/preload_class_alias.inc b/ext/opcache/tests/preload_class_alias.inc
new file mode 100644
index 0000000000..2aaa5adafc
--- /dev/null
+++ b/ext/opcache/tests/preload_class_alias.inc
@@ -0,0 +1,3 @@
+<?php
+class A {}
+class_alias(A::class, 'B');
diff --git a/ext/opcache/tests/preload_class_alias.phpt b/ext/opcache/tests/preload_class_alias.phpt
new file mode 100644
index 0000000000..aee94426d0
--- /dev/null
+++ b/ext/opcache/tests/preload_class_alias.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #78918: Class alias during preloading causes assertion failure
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+opcache.preload={PWD}/preload_class_alias.inc
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+var_dump(class_exists('A'));
+var_dump(class_exists('B'));
+?>
+--EXPECT--
+bool(true)
+bool(true)
diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c
index 1571093419..bcbd2f270f 100644
--- a/ext/opcache/zend_persist.c
+++ b/ext/opcache/zend_persist.c
@@ -700,6 +700,12 @@ static void zend_persist_class_entry(zval *zv)
zend_class_entry *ce = Z_PTR_P(zv);
if (ce->type == ZEND_USER_CLASS) {
+ /* The same zend_class_entry may be reused by class_alias */
+ zend_class_entry *new_ce = zend_shared_alloc_get_xlat_entry(ce);
+ if (new_ce) {
+ Z_PTR_P(zv) = new_ce;
+ return;
+ }
if ((ce->ce_flags & ZEND_ACC_LINKED)
&& (ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)
&& (ce->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED)
diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c
index cc798b27de..dacc2376e8 100644
--- a/ext/opcache/zend_persist_calc.c
+++ b/ext/opcache/zend_persist_calc.c
@@ -352,6 +352,12 @@ static void zend_persist_class_entry_calc(zval *zv)
Bucket *p;
if (ce->type == ZEND_USER_CLASS) {
+ /* The same zend_class_entry may be reused by class_alias */
+ if (zend_shared_alloc_get_xlat_entry(ce)) {
+ return;
+ }
+ zend_shared_alloc_register_xlat_entry(ce, ce);
+
check_property_type_resolution(ce);
ZCG(is_immutable_class) =