@@ -2105,7 +2105,9 @@ ZEND_API uint32_t ZEND_FASTCALL zend_array_type_info(const zval *zv)
21052105 } else if (HT_IS_PACKED (ht )) {
21062106 tmp |= MAY_BE_ARRAY_PACKED ;
21072107 ZEND_HASH_PACKED_FOREACH_VAL (ht , val ) {
2108- tmp |= 1 << (Z_TYPE_P (val ) + MAY_BE_ARRAY_SHIFT );
2108+ if (Z_TYPE_P (val ) != _IS_ERROR ) {
2109+ tmp |= 1 << (Z_TYPE_P (val ) + MAY_BE_ARRAY_SHIFT );
2110+ }
21092111 } ZEND_HASH_FOREACH_END ();
21102112 } else {
21112113 ZEND_HASH_MAP_FOREACH_STR_KEY_VAL (ht , str , val ) {
@@ -2114,7 +2116,9 @@ ZEND_API uint32_t ZEND_FASTCALL zend_array_type_info(const zval *zv)
21142116 } else {
21152117 tmp |= MAY_BE_ARRAY_NUMERIC_HASH ;
21162118 }
2117- tmp |= 1 << (Z_TYPE_P (val ) + MAY_BE_ARRAY_SHIFT );
2119+ if (Z_TYPE_P (val ) != _IS_ERROR ) {
2120+ tmp |= 1 << (Z_TYPE_P (val ) + MAY_BE_ARRAY_SHIFT );
2121+ }
21182122 } ZEND_HASH_FOREACH_END ();
21192123 }
21202124 return tmp ;
@@ -3443,12 +3447,36 @@ static zend_always_inline zend_result _zend_update_type_info(
34433447 UPDATE_SSA_TYPE (tmp , ssa_op -> result_def );
34443448 }
34453449 break ;
3446- case ZEND_ARRAY_DUP :
3447- case ZEND_ARRAY_SET_PLACEHOLDER :
3448- /* FIXME: This can of course be more specific. However, one challenge
3449- * will be removing filled NULL slots from type inference. */
3450- UPDATE_SSA_TYPE (MAY_BE_RC1 |MAY_BE_ARRAY |MAY_BE_ARRAY_KEY_ANY |MAY_BE_ARRAY_OF_ANY , ssa_op -> result_def );
3450+ case ZEND_ARRAY_DUP : {
3451+ ZEND_ASSERT (opline -> op1_type == IS_CONST );
3452+ zval * template = CRT_CONSTANT_EX (op_array , opline , opline -> op1 );
3453+ uint32_t tmp = zend_array_type_info (template );
3454+ tmp &= ~MAY_BE_RCN ;
3455+ tmp |= MAY_BE_RC1 ;
3456+ if (!(tmp & MAY_BE_ARRAY_OF_ANY )) {
3457+ tmp |= MAY_BE_ARRAY_OF_ANY ;
3458+ }
3459+ UPDATE_SSA_TYPE (tmp , ssa_op -> result_def );
34513460 break ;
3461+ }
3462+ case ZEND_ARRAY_SET_PLACEHOLDER : {
3463+ // FIXME: op1 RC inference
3464+ uint32_t tmp = RES_USE_INFO ();
3465+ if ((tmp & MAY_BE_ARRAY_OF_ANY ) == MAY_BE_ARRAY_OF_ANY ) {
3466+ ZEND_ASSERT (ssa_op -> result_use != -1 );
3467+ zend_op * dup_op = op_array -> opcodes + ssa_vars [ssa_op -> result_use ].definition ;
3468+ if (dup_op -> opcode == ZEND_ARRAY_DUP ) {
3469+ zval * template = CRT_CONSTANT_EX (op_array , dup_op , dup_op -> op1 );
3470+ tmp = zend_array_type_info (template );
3471+ tmp &= ~MAY_BE_RCN ;
3472+ tmp |= MAY_BE_RC1 ;
3473+ }
3474+ }
3475+ uint32_t dim_type = ((tmp & MAY_BE_ARRAY_KEY_LONG ) ? MAY_BE_LONG : 0 ) | ((tmp & MAY_BE_ARRAY_KEY_STRING ) ? MAY_BE_STRING : 0 );
3476+ tmp |= assign_dim_array_result_type (tmp , dim_type , t1 , IS_CONST );
3477+ UPDATE_SSA_TYPE (tmp , ssa_op -> result_def );
3478+ break ;
3479+ }
34523480 case ZEND_ADD_ARRAY_UNPACK :
34533481 tmp = ssa_var_info [ssa_op -> result_use ].type ;
34543482 ZEND_ASSERT (tmp & MAY_BE_ARRAY );
0 commit comments