@@ -2612,7 +2612,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce, zend_class_e
2612
2612
}
2613
2613
/* }}} */
2614
2614
2615
- static void zend_do_traits_method_binding (zend_class_entry * ce , zend_class_entry * * traits , HashTable * * exclude_tables , zend_class_entry * * aliases ) /* {{{ */
2615
+ static void zend_do_traits_method_binding (zend_class_entry * ce , zend_class_entry * * traits , HashTable * * exclude_tables , zend_class_entry * * aliases , bool verify_abstract ) /* {{{ */
2616
2616
{
2617
2617
uint32_t i ;
2618
2618
zend_string * key ;
@@ -2623,6 +2623,9 @@ static void zend_do_traits_method_binding(zend_class_entry *ce, zend_class_entry
2623
2623
if (traits [i ]) {
2624
2624
/* copies functions, applies defined aliasing, and excludes unused trait methods */
2625
2625
ZEND_HASH_MAP_FOREACH_STR_KEY_PTR (& traits [i ]-> function_table , key , fn ) {
2626
+ if (verify_abstract != (bool ) (fn -> common .fn_flags & ZEND_ACC_ABSTRACT )) {
2627
+ continue ;
2628
+ }
2626
2629
zend_traits_copy_functions (key , fn , ce , exclude_tables [i ], aliases );
2627
2630
} ZEND_HASH_FOREACH_END ();
2628
2631
@@ -2637,15 +2640,14 @@ static void zend_do_traits_method_binding(zend_class_entry *ce, zend_class_entry
2637
2640
for (i = 0 ; i < ce -> num_traits ; i ++ ) {
2638
2641
if (traits [i ]) {
2639
2642
ZEND_HASH_MAP_FOREACH_STR_KEY_PTR (& traits [i ]-> function_table , key , fn ) {
2643
+ if (verify_abstract != (bool ) (fn -> common .fn_flags & ZEND_ACC_ABSTRACT )) {
2644
+ continue ;
2645
+ }
2640
2646
zend_traits_copy_functions (key , fn , ce , NULL , aliases );
2641
2647
} ZEND_HASH_FOREACH_END ();
2642
2648
}
2643
2649
}
2644
2650
}
2645
-
2646
- ZEND_HASH_MAP_FOREACH_PTR (& ce -> function_table , fn ) {
2647
- zend_fixup_trait_method (fn , ce );
2648
- } ZEND_HASH_FOREACH_END ();
2649
2651
}
2650
2652
/* }}} */
2651
2653
@@ -2927,7 +2929,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
2927
2929
}
2928
2930
/* }}} */
2929
2931
2930
- static void zend_do_bind_traits (zend_class_entry * ce , zend_class_entry * * traits ) /* {{{ */
2932
+ static void zend_do_bind_traits (zend_class_entry * ce , zend_class_entry * * traits , bool verify_abstract ) /* {{{ */
2931
2933
{
2932
2934
HashTable * * exclude_tables ;
2933
2935
zend_class_entry * * aliases ;
@@ -2938,7 +2940,7 @@ static void zend_do_bind_traits(zend_class_entry *ce, zend_class_entry **traits)
2938
2940
zend_traits_init_trait_structures (ce , traits , & exclude_tables , & aliases );
2939
2941
2940
2942
/* Flatten all methods into the class */
2941
- zend_do_traits_method_binding (ce , traits , exclude_tables , aliases );
2943
+ zend_do_traits_method_binding (ce , traits , exclude_tables , aliases , verify_abstract );
2942
2944
2943
2945
if (aliases ) {
2944
2946
efree (aliases );
@@ -3559,8 +3561,7 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
3559
3561
}
3560
3562
3561
3563
if (ce -> num_traits ) {
3562
- /* Bind all constants and properties first, so that parent inheritance treats them as if
3563
- * they were declared in the child class. */
3564
+ zend_do_bind_traits (ce , traits_and_interfaces , false);
3564
3565
zend_do_traits_constant_binding (ce , traits_and_interfaces );
3565
3566
zend_do_traits_property_binding (ce , traits_and_interfaces );
3566
3567
}
@@ -3571,7 +3572,12 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
3571
3572
zend_do_inheritance (ce , parent );
3572
3573
}
3573
3574
if (ce -> num_traits ) {
3574
- zend_do_bind_traits (ce , traits_and_interfaces );
3575
+ zend_do_bind_traits (ce , traits_and_interfaces , true);
3576
+
3577
+ zend_function * fn ;
3578
+ ZEND_HASH_MAP_FOREACH_PTR (& ce -> function_table , fn ) {
3579
+ zend_fixup_trait_method (fn , ce );
3580
+ } ZEND_HASH_FOREACH_END ();
3575
3581
}
3576
3582
if (ce -> num_interfaces ) {
3577
3583
/* Also copy the parent interfaces here, so we don't need to reallocate later. */
0 commit comments