diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-02-22 10:13:07 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-02-22 10:13:21 +0100 |
commit | bd2a00acdf8de2968425716d071074876b03a24d (patch) | |
tree | d25cb1072a8b60456ebb774fd95a4128c58d62fc /Zend/zend_compile.c | |
parent | 5c221bcd01eea196263d4231ba079c49f3e27469 (diff) | |
parent | 538814385569525443c96e131d346a8fd7b6cbe3 (diff) | |
download | php-git-bd2a00acdf8de2968425716d071074876b03a24d.tar.gz |
Merge branch 'PHP-7.2' into PHP-7.3
Diffstat (limited to 'Zend/zend_compile.c')
-rw-r--r-- | Zend/zend_compile.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index fccc45c994..b7fa412d9f 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6440,10 +6440,32 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */ if (!zend_hash_exists(CG(class_table), lcname)) { zend_hash_add_ptr(CG(class_table), lcname, ce); } else { - /* this anonymous class has been included */ + /* This anonymous class has been included, reuse the existing definition. + * NB: This behavior is buggy, and this should always result in a separate + * class declaration. However, until the problem of RTD key collisions is + * solved, this gives a behavior close to what is expected. */ zval zv; ZVAL_PTR(&zv, ce); destroy_zend_class(&zv); + ce = zend_hash_find_ptr(CG(class_table), lcname); + + /* Manually replicate emission of necessary inheritance opcodes here. We cannot + * reuse the general code, as we only want to emit the opcodes, without modifying + * the reused class definition. */ + if (ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS) { + zend_emit_op(NULL, ZEND_BIND_TRAITS, &declare_node, NULL); + } + if (implements_ast) { + zend_ast_list *iface_list = zend_ast_get_list(implements_ast); + uint32_t i; + for (i = 0; i < iface_list->children; i++) { + opline = zend_emit_op(NULL, ZEND_ADD_INTERFACE, &declare_node, NULL); + opline->op2_type = IS_CONST; + opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), + zend_resolve_class_name_ast(iface_list->child[i])); + } + zend_emit_op(NULL, ZEND_VERIFY_ABSTRACT_CLASS, &declare_node, NULL); + } return; } } else { |