Skip to content

Commit

Permalink
Merge branch 'PHP-8.2'
Browse files Browse the repository at this point in the history
* PHP-8.2:
  Allow FETCH_OBJ_W and FETCH_STATIC_PROP_W to return INDIRECT/UNDEF zval for uninitialized typed properties (#11048)
  • Loading branch information
dstogov committed Apr 10, 2023
2 parents 0bd826a + e14ac1c commit 0660fb5
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 38 deletions.
6 changes: 6 additions & 0 deletions Zend/Optimizer/zend_inference.c
Original file line number Diff line number Diff line change
Expand Up @@ -3472,6 +3472,9 @@ static zend_always_inline zend_result _zend_update_type_info(
tmp |= zend_fetch_prop_type(script, prop_info, &ce);
if (opline->opcode != ZEND_FETCH_OBJ_R && opline->opcode != ZEND_FETCH_OBJ_IS) {
tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
if ((opline->extended_value & ZEND_FETCH_OBJ_FLAGS) == ZEND_FETCH_DIM_WRITE) {
tmp |= MAY_BE_UNDEF;
}
ce = NULL;
} else if (!(opline->op1_type & (IS_VAR|IS_TMP_VAR)) || !(t1 & MAY_BE_RC1)) {
const zend_class_entry *ce = NULL;
Expand Down Expand Up @@ -3511,6 +3514,9 @@ static zend_always_inline zend_result _zend_update_type_info(
if (opline->opcode != ZEND_FETCH_STATIC_PROP_R
&& opline->opcode != ZEND_FETCH_STATIC_PROP_IS) {
tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
if ((opline->extended_value & ZEND_FETCH_OBJ_FLAGS) == ZEND_FETCH_DIM_WRITE) {
tmp |= MAY_BE_UNDEF;
}
ce = NULL;
} else {
if (!result_may_be_separated(ssa, ssa_op)) {
Expand Down
7 changes: 2 additions & 5 deletions Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -3106,7 +3106,7 @@ static zend_never_inline bool zend_handle_fetch_obj_flags(
return 1;
}

static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type, uint32_t flags, bool init_undef OPLINE_DC EXECUTE_DATA_DC)
static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type, uint32_t flags OPLINE_DC EXECUTE_DATA_DC)
{
zval *ptr;
zend_object *zobj;
Expand Down Expand Up @@ -3226,9 +3226,6 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
}
}
}
if (init_undef && UNEXPECTED(Z_TYPE_P(ptr) == IS_UNDEF)) {
ZVAL_NULL(ptr);
}

end:
if (prop_op_type != IS_CONST) {
Expand All @@ -3243,7 +3240,7 @@ static zend_always_inline void zend_assign_to_property_reference(zval *container
zend_refcounted *garbage = NULL;

zend_fetch_property_address(variable_ptr, container, container_op_type, prop_ptr, prop_op_type,
cache_addr, BP_VAR_W, 0, 0 OPLINE_CC EXECUTE_DATA_CC);
cache_addr, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC);

if (EXPECTED(Z_TYPE_P(variable_ptr) == IS_INDIRECT)) {
variable_ptr = Z_INDIRECT_P(variable_ptr);
Expand Down
2 changes: 2 additions & 0 deletions Zend/zend_object_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,8 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
} else if (prop_info && UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) {
/* Readonly property, delegate to read_property + write_property. */
retval = NULL;
} else if (!prop_info || !ZEND_TYPE_IS_SET(prop_info->type)) {
ZVAL_NULL(retval);
}
} else {
/* we do have getter - fail and let it try again with usual get/set */
Expand Down
6 changes: 3 additions & 3 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -2169,7 +2169,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, FETCH
zend_fetch_property_address(
result, container, OP1_TYPE, property, OP2_TYPE,
((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
BP_VAR_W, opline->extended_value, 1 OPLINE_CC EXECUTE_DATA_CC);
BP_VAR_W, opline->extended_value OPLINE_CC EXECUTE_DATA_CC);
FREE_OP2();
if (OP1_TYPE == IS_VAR) {
FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
Expand All @@ -2186,7 +2186,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACH
container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
property = GET_OP2_ZVAL_PTR(BP_VAR_R);
result = EX_VAR(opline->result.var);
zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, 1 OPLINE_CC EXECUTE_DATA_CC);
zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC);
FREE_OP2();
if (OP1_TYPE == IS_VAR) {
FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
Expand Down Expand Up @@ -2332,7 +2332,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, C
container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_UNSET);
property = GET_OP2_ZVAL_PTR(BP_VAR_R);
result = EX_VAR(opline->result.var);
zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, 1 OPLINE_CC EXECUTE_DATA_CC);
zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0 OPLINE_CC EXECUTE_DATA_CC);
FREE_OP2();
if (OP1_TYPE == IS_VAR) {
FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
Expand Down
Loading

0 comments on commit 0660fb5

Please sign in to comment.