@@ -1877,6 +1877,9 @@ static uint32_t get_ssa_alias_types(zend_ssa_alias_kind alias) {
1877
1877
} \
1878
1878
} \
1879
1879
if (ssa_var_info [__var ].type != __type ) { \
1880
+ ZEND_ASSERT (__ssa_var -> var >= op_array -> last_var || \
1881
+ (ssa_var_info [__var ].type & MAY_BE_REF ) \
1882
+ == (__type & MAY_BE_REF )); \
1880
1883
if (ssa_var_info [__var ].type & ~__type ) { \
1881
1884
emit_type_narrowing_warning (op_array , ssa , __var ); \
1882
1885
return FAILURE ; \
@@ -4252,7 +4255,6 @@ void zend_func_return_info(const zend_op_array *op_array,
4252
4255
4253
4256
static int zend_infer_types (const zend_op_array * op_array , const zend_script * script , zend_ssa * ssa , zend_long optimization_level )
4254
4257
{
4255
- zend_ssa_var_info * ssa_var_info = ssa -> var_info ;
4256
4258
int ssa_vars_count = ssa -> vars_count ;
4257
4259
int j ;
4258
4260
zend_bitset worklist ;
@@ -4264,7 +4266,6 @@ static int zend_infer_types(const zend_op_array *op_array, const zend_script *sc
4264
4266
/* Type Inference */
4265
4267
for (j = op_array -> last_var ; j < ssa_vars_count ; j ++ ) {
4266
4268
zend_bitset_incl (worklist , j );
4267
- ssa_var_info [j ].type = 0 ;
4268
4269
}
4269
4270
4270
4271
if (zend_infer_types_ex (op_array , script , ssa , worklist , optimization_level ) != SUCCESS ) {
@@ -4322,12 +4323,12 @@ static int zend_mark_cv_references(const zend_op_array *op_array, const zend_scr
4322
4323
case ZEND_SEND_VAR_EX :
4323
4324
case ZEND_SEND_FUNC_ARG :
4324
4325
break ;
4326
+ case ZEND_INIT_ARRAY :
4325
4327
case ZEND_ADD_ARRAY_ELEMENT :
4326
4328
if (!(opline -> extended_value & ZEND_ARRAY_ELEMENT_REF )) {
4327
4329
continue ;
4328
4330
}
4329
4331
break ;
4330
- case ZEND_BIND_LEXICAL :
4331
4332
case ZEND_BIND_STATIC :
4332
4333
if (!(opline -> extended_value & ZEND_BIND_REF )) {
4333
4334
continue ;
@@ -4351,8 +4352,17 @@ static int zend_mark_cv_references(const zend_op_array *op_array, const zend_scr
4351
4352
continue ;
4352
4353
}
4353
4354
} else if (ssa -> ops [def ].op2_def == var ) {
4354
- if (opline -> opcode != ZEND_ASSIGN_REF ) {
4355
- continue ;
4355
+ switch (opline -> opcode ) {
4356
+ case ZEND_ASSIGN_REF :
4357
+ case ZEND_FE_FETCH_RW :
4358
+ break ;
4359
+ case ZEND_BIND_LEXICAL :
4360
+ if (!(opline -> extended_value & ZEND_BIND_REF )) {
4361
+ continue ;
4362
+ }
4363
+ break ;
4364
+ default :
4365
+ continue ;
4356
4366
}
4357
4367
} else {
4358
4368
ZEND_UNREACHABLE ();
@@ -4382,12 +4392,15 @@ static int zend_mark_cv_references(const zend_op_array *op_array, const zend_scr
4382
4392
4383
4393
if (ssa -> vars [var ].use_chain >= 0 ) {
4384
4394
int use = ssa -> vars [var ].use_chain ;
4385
- zend_ssa_op * op ;
4386
-
4387
- do {
4388
- op = ssa -> ops + use ;
4395
+ FOREACH_USE (& ssa -> vars [var ], use ) {
4396
+ zend_ssa_op * op = ssa -> ops + use ;
4389
4397
if (op -> op1_use == var && op -> op1_def >= 0 ) {
4390
4398
if (!(ssa -> var_info [op -> op1_def ].type & MAY_BE_REF )) {
4399
+ /* Unset breaks references (outside global scope). */
4400
+ if (op_array -> opcodes [use ].opcode == ZEND_UNSET_CV
4401
+ && op_array -> function_name ) {
4402
+ continue ;
4403
+ }
4391
4404
zend_bitset_incl (worklist , op -> op1_def );
4392
4405
}
4393
4406
}
@@ -4401,9 +4414,7 @@ static int zend_mark_cv_references(const zend_op_array *op_array, const zend_scr
4401
4414
zend_bitset_incl (worklist , op -> result_def );
4402
4415
}
4403
4416
}
4404
-
4405
- use = zend_ssa_next_use (ssa -> ops , var , use );
4406
- } while (use >= 0 );
4417
+ } FOREACH_USE_END ();
4407
4418
}
4408
4419
} WHILE_WORKLIST_END ();
4409
4420
0 commit comments