@@ -4568,6 +4568,75 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_VERIFY_RETURN_TYPE, (((res_info & MAY_BE_REF)
45684568 ZEND_VM_NEXT_OPCODE ();
45694569}
45704570
4571+ ZEND_VM_HOT_TYPE_SPEC_HANDLER (ZEND_VERIFY_RETURN_TYPE , (((res_info & MAY_BE_REF ) == 0 ) && op1_info == MAY_BE_STRING ), ZEND_VERIFY_RETURN_TYPE_FOR_STRING , CONST |TMP |VAR |CV , UNUSED )
4572+ {
4573+ USE_OPLINE
4574+ zval * op , * result ;
4575+ uint32_t pure_type_mask = opline -> extended_value ;
4576+
4577+ if (UNEXPECTED (EX_USES_STRICT_TYPES () || ((pure_type_mask & MAY_BE_LONG |MAY_BE_DOUBLE |MAY_BE_BOOL ) == 0 ))) {
4578+ SAVE_OPLINE ();
4579+ zend_verify_return_error (EX (func ), result );
4580+ HANDLE_EXCEPTION ();
4581+ }
4582+
4583+ op = GET_OP1_ZVAL_PTR (BP_VAR_R );
4584+ result = EX_VAR (opline -> result .var );
4585+
4586+ /* Would have been elided by optimizer */
4587+ ZEND_ASSERT ((pure_type_mask & MAY_BE_STRING ) == 0 );
4588+
4589+ /* Type preference order: int -> float -> bool */
4590+ zend_long lval = 0 ;
4591+ double dval = 0 ;
4592+ uint8_t type = is_numeric_str_function (Z_STR_P (op ), & lval , & dval );
4593+ if (type == IS_LONG ) {
4594+ if (pure_type_mask & MAY_BE_LONG ) {
4595+ ZVAL_LONG (result , lval );
4596+ } else if (pure_type_mask & MAY_BE_DOUBLE ) {
4597+ ZVAL_DOUBLE (result , (double )lval );
4598+ } else {
4599+ ZEND_ASSERT (pure_type_mask & MAY_BE_BOOL );
4600+ ZVAL_BOOL (result , lval );
4601+ }
4602+ ZEND_VM_NEXT_OPCODE ();
4603+ } else if (type == IS_DOUBLE ) {
4604+ if (pure_type_mask & MAY_BE_DOUBLE ) {
4605+ ZVAL_DOUBLE (result , dval );
4606+ ZEND_VM_NEXT_OPCODE ();
4607+ } else if (pure_type_mask & MAY_BE_LONG ) {
4608+ if (!zend_isnan (dval ) && ZEND_DOUBLE_FITS_LONG (dval )) {
4609+ SAVE_OPLINE ();
4610+ /* May warn */
4611+ ZVAL_LONG (result , zend_dval_to_lval_safe (dval ));
4612+ ZEND_VM_NEXT_OPCODE ();
4613+ }
4614+ } else {
4615+ ZVAL_BOOL (result , dval );
4616+ ZEND_VM_NEXT_OPCODE ();
4617+ }
4618+ } else {
4619+ if (pure_type_mask & MAY_BE_BOOL ) {
4620+ ZVAL_BOOL (result , i_zend_is_true (op ));
4621+ ZEND_VM_NEXT_OPCODE ();
4622+ }
4623+ }
4624+ SAVE_OPLINE ();
4625+ zend_verify_return_error (EX (func ), op );
4626+ HANDLE_EXCEPTION ();
4627+ /* int to float is always valid even with strict types */
4628+ if (pure_type_mask & MAY_BE_LONG ) {
4629+ ZVAL_LONG (result , lval );
4630+ ZEND_VM_NEXT_OPCODE ();
4631+ } else if (pure_type_mask & MAY_BE_DOUBLE ) {
4632+ ZVAL_DOUBLE (result , (double )lval );
4633+ ZEND_VM_NEXT_OPCODE ();
4634+ } else if (pure_type_mask & MAY_BE_BOOL ) {
4635+ ZVAL_BOOL (result , lval );
4636+ } else {
4637+ }
4638+ }
4639+
45714640ZEND_VM_COLD_HANDLER (201 , ZEND_VERIFY_NEVER_TYPE , UNUSED , UNUSED )
45724641{
45734642 SAVE_OPLINE ();
0 commit comments