@@ -2642,6 +2642,53 @@ static void zend_compile_memoized_expr(znode *result, zend_ast *expr, uint32_t t
26422642}
26432643/* }}} */
26442644
2645+ static bool zend_is_this_instance_of_name (const zend_string * type_name )
2646+ {
2647+ if (zend_string_equals_ci (CG (active_class_entry )-> name , type_name )) {
2648+ return true;
2649+ }
2650+ if (zend_string_equals_ci (type_name , ZSTR_KNOWN (ZEND_STR_SELF ))) {
2651+ return true;
2652+ }
2653+ if (zend_string_equals_ci (type_name , ZSTR_KNOWN (ZEND_STR_PARENT ))) {
2654+ return true;
2655+ }
2656+
2657+ ZEND_ASSERT ((CG (active_class_entry )-> ce_flags & ZEND_ACC_LINKED ) == 0 );
2658+ if (CG (active_class_entry )-> num_interfaces ) {
2659+ for (uint32_t i = 0 ; i < CG (active_class_entry )-> num_interfaces ; i ++ ) {
2660+ if (zend_string_equals_ci (CG (active_class_entry )-> interface_names [i ].lc_name , type_name )) {
2661+ return true;
2662+ }
2663+ }
2664+ }
2665+ const zend_string * parent_name = CG (active_class_entry )-> parent_name ;
2666+ if (parent_name && zend_string_equals_ci (parent_name , type_name )) {
2667+ return true;
2668+ }
2669+
2670+ return false;
2671+ }
2672+
2673+ static bool zend_is_this_valid_for_return_type (zend_type type )
2674+ {
2675+ if (ZEND_TYPE_FULL_MASK (type ) & (MAY_BE_OBJECT |MAY_BE_STATIC )) {
2676+ return true;
2677+ }
2678+
2679+ const zend_type * single_type ;
2680+ ZEND_TYPE_FOREACH (type , single_type ) {
2681+ if (ZEND_TYPE_HAS_NAME (* single_type )) {
2682+ const zend_string * name = ZEND_TYPE_NAME (* single_type );
2683+ if (zend_is_this_instance_of_name (name )) {
2684+ return true;
2685+ }
2686+ }
2687+ } ZEND_TYPE_FOREACH_END ();
2688+
2689+ return false;
2690+ }
2691+
26452692static void zend_emit_return_type_check (
26462693 znode * expr , const zend_arg_info * return_info , bool implicit ) /* {{{ */
26472694{
@@ -2696,16 +2743,14 @@ static void zend_emit_return_type_check(
26962743 /* we don't need run-time check */
26972744 return ;
26982745 }
2699-
2746+
27002747 /* If return type contains static and we are returning $this
27012748 * (determined by checking if the previous opcode is ZEND_FETCH_THIS)
27022749 * then we don't need to check the return type */
2703- if (expr && ZEND_TYPE_CONTAINS_CODE (type , IS_STATIC )) {
2704- const zend_op_array * op_array = CG (active_op_array );
2705- zend_op previous = op_array -> opcodes [op_array -> last - 1 ];
2706- if (previous .opcode == ZEND_FETCH_THIS ) {
2707- return ;
2708- }
2750+ const zend_op_array * op_array = CG (active_op_array );
2751+ zend_op previous = op_array -> opcodes [op_array -> last - 1 ];
2752+ if (expr && previous .opcode == ZEND_FETCH_THIS && zend_is_this_valid_for_return_type (type )) {
2753+ return ;
27092754 }
27102755
27112756 opline = zend_emit_op (NULL , ZEND_VERIFY_RETURN_TYPE , expr , NULL );
0 commit comments