Check opcode rather than result_type for R/IS type inference

We may sometimes create FETCH_*_R opcodes with VAR type (e.g. if a
FUNC_ARG opcode is converted to BP_VAR_R fetch kind). Make sure we
don't infer overly conservative types in that case.
This commit is contained in:
Nikita Popov 2022-04-16 22:42:20 +02:00
parent 3f12d26e3a
commit df4c27642e

View file

@ -3368,7 +3368,8 @@ static zend_always_inline zend_result _zend_update_type_info(
tmp = zend_array_element_type(
opline->opcode != ZEND_FETCH_LIST_R ? t1 : ((t1 & ~MAY_BE_STRING) | MAY_BE_NULL),
opline->op1_type,
opline->result_type == IS_VAR,
opline->opcode != ZEND_FETCH_DIM_R && opline->opcode != ZEND_FETCH_DIM_IS
&& opline->opcode != ZEND_FETCH_LIST_R,
opline->op2_type == IS_UNUSED);
if (opline->opcode == ZEND_FETCH_DIM_IS && (t1 & MAY_BE_STRING)) {
tmp |= MAY_BE_NULL;
@ -3409,7 +3410,7 @@ static zend_always_inline zend_result _zend_update_type_info(
if (opline->op1_type == IS_UNUSED || (t1 & MAY_BE_OBJECT)) {
zend_property_info *prop_info = zend_fetch_prop_info(op_array, ssa, opline, ssa_op);
tmp |= zend_fetch_prop_type(script, prop_info, &ce);
if (opline->result_type == IS_VAR) {
if (opline->opcode != ZEND_FETCH_OBJ_R && opline->opcode != ZEND_FETCH_OBJ_IS) {
tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
ce = NULL;
} else if (!(opline->op1_type & (IS_VAR|IS_TMP_VAR)) || !(t1 & MAY_BE_RC1)) {
@ -3451,7 +3452,8 @@ static zend_always_inline zend_result _zend_update_type_info(
case ZEND_FETCH_STATIC_PROP_FUNC_ARG:
tmp = zend_fetch_prop_type(script,
zend_fetch_static_prop_info(script, op_array, ssa, opline), &ce);
if (opline->result_type == IS_VAR) {
if (opline->opcode != ZEND_FETCH_STATIC_PROP_R
&& opline->opcode != ZEND_FETCH_STATIC_PROP_IS) {
tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
} else {
if (!result_may_be_separated(ssa, ssa_op)) {