@@ -6365,10 +6365,32 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
6365
6365
if (!zend_hash_exists (CG (class_table ), lcname )) {
6366
6366
zend_hash_add_ptr (CG (class_table ), lcname , ce );
6367
6367
} else {
6368
- /* this anonymous class has been included */
6368
+ /* This anonymous class has been included, reuse the existing definition.
6369
+ * NB: This behavior is buggy, and this should always result in a separate
6370
+ * class declaration. However, until the problem of RTD key collisions is
6371
+ * solved, this gives a behavior close to what is expected. */
6369
6372
zval zv ;
6370
6373
ZVAL_PTR (& zv , ce );
6371
6374
destroy_zend_class (& zv );
6375
+ ce = zend_hash_find_ptr (CG (class_table ), lcname );
6376
+
6377
+ /* Manually replicate emission of necessary inheritance opcodes here. We cannot
6378
+ * reuse the general code, as we only want to emit the opcodes, without modifying
6379
+ * the reused class definition. */
6380
+ if (ce -> ce_flags & ZEND_ACC_IMPLEMENT_TRAITS ) {
6381
+ zend_emit_op (NULL , ZEND_BIND_TRAITS , & declare_node , NULL );
6382
+ }
6383
+ if (implements_ast ) {
6384
+ zend_ast_list * iface_list = zend_ast_get_list (implements_ast );
6385
+ uint32_t i ;
6386
+ for (i = 0 ; i < iface_list -> children ; i ++ ) {
6387
+ opline = zend_emit_op (NULL , ZEND_ADD_INTERFACE , & declare_node , NULL );
6388
+ opline -> op2_type = IS_CONST ;
6389
+ opline -> op2 .constant = zend_add_class_name_literal (CG (active_op_array ),
6390
+ zend_resolve_class_name_ast (iface_list -> child [i ]));
6391
+ }
6392
+ zend_emit_op (NULL , ZEND_VERIFY_ABSTRACT_CLASS , & declare_node , NULL );
6393
+ }
6372
6394
return ;
6373
6395
}
6374
6396
} else {
0 commit comments