From: Dmitry Stogov Date: Tue, 15 Jan 2019 15:03:46 +0000 (+0300) Subject: Fixed uninitialized result of PRE_INC/PRE_DEC in case of exception. X-Git-Tag: php-7.4.0alpha1~1217 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=239305d12ee1f6d3fbfef72d2cfead9bb97141ef;p=php Fixed uninitialized result of PRE_INC/PRE_DEC in case of exception. Separated increment/decrement of typed reference into helper. --- diff --git a/Zend/tests/type_declarations/typed_properties_104.phpt b/Zend/tests/type_declarations/typed_properties_104.phpt new file mode 100644 index 0000000000..e7d69e3d7d --- /dev/null +++ b/Zend/tests/type_declarations/typed_properties_104.phpt @@ -0,0 +1,17 @@ +--TEST-- +Uninitialized result of PRE_INC/PRE_DEC in case of exception +--FILE-- +a; +try { + $ret = ++$x + 5; +} catch (TypeError $e) { +} +?> +OK +--EXPECT-- +OK diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index fbc50bd2f6..3dbcff34b6 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1613,6 +1613,34 @@ static ZEND_COLD void zend_throw_incdec_prop_error(zend_property_info *prop, zen inc ? "max" : "min"); } +static void zend_incdec_typed_ref(zend_reference *ref, zval *copy, int inc EXECUTE_DATA_DC) +{ + zval tmp; + zval *var_ptr = &ref->val; + + if (!copy) { + copy = &tmp; + } + + ZVAL_COPY(copy, var_ptr); + + if (inc) { + increment_function(var_ptr); + } else { + decrement_function(var_ptr); + } + + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(copy) == IS_LONG) { + zend_throw_incdec_ref_error(ref, inc); + ZVAL_COPY_VALUE(var_ptr, copy); + } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { + zval_ptr_dtor(var_ptr); + ZVAL_COPY_VALUE(var_ptr, copy); + } else if (copy == &tmp) { + zval_ptr_dtor(&tmp); + } +} + static void zend_pre_incdec_property_zval(zval *prop, zend_property_info *prop_info, int inc OPLINE_DC EXECUTE_DATA_DC) { if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index d94fe68435..884a8552e4 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1401,34 +1401,17 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY, SPEC(RETVAL)) ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval old; - ZVAL_COPY(&old, var_ptr); - - increment_function(var_ptr); - - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE(old) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 1); - ZVAL_COPY_VALUE(var_ptr, &old); - FREE_OP1_VAR_PTR(); - HANDLE_EXCEPTION(); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &old); - FREE_OP1_VAR_PTR(); - HANDLE_EXCEPTION(); - } else { - zval_ptr_dtor(&old); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, NULL, 1 EXECUTE_DATA_CC); + break; } - } else { - increment_function(var_ptr); } - } else { increment_function(var_ptr); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -1467,35 +1450,18 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY, SPEC(RETVAL)) ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval old; - ZVAL_COPY(&old, var_ptr); - - decrement_function(var_ptr); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE(old) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 0); - ZVAL_COPY_VALUE(var_ptr, &old); - FREE_OP1_VAR_PTR(); - HANDLE_EXCEPTION(); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &old); - FREE_OP1_VAR_PTR(); - HANDLE_EXCEPTION(); - } else { - zval_ptr_dtor(&old); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, NULL, 0 EXECUTE_DATA_CC); + break; } - } else { - decrement_function(var_ptr); } - } else { decrement_function(var_ptr); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -1530,28 +1496,20 @@ ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY) ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - - increment_function(var_ptr); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(EX_VAR(opline->result.var)) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 1); - ZVAL_COPY_VALUE(var_ptr, EX_VAR(opline->result.var)); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, EX_VAR(opline->result.var)); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, EX_VAR(opline->result.var), 1 EXECUTE_DATA_CC); + break; } } - } else { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); increment_function(var_ptr); - } + } while (0); FREE_OP1_VAR_PTR(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -1582,28 +1540,20 @@ ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY) ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - - decrement_function(var_ptr); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(EX_VAR(opline->result.var)) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 0); - ZVAL_COPY_VALUE(var_ptr, EX_VAR(opline->result.var)); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, EX_VAR(opline->result.var)); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, EX_VAR(opline->result.var), 0 EXECUTE_DATA_CC); + break; } } - } else { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); decrement_function(var_ptr); - } + } while (0); FREE_OP1_VAR_PTR(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index c298f5a068..22b96eb822 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -22580,34 +22580,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_RETVAL_UNUSED ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval old; - ZVAL_COPY(&old, var_ptr); - - increment_function(var_ptr); - - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE(old) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 1); - ZVAL_COPY_VALUE(var_ptr, &old); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &old); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); - } else { - zval_ptr_dtor(&old); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, NULL, 1 EXECUTE_DATA_CC); + break; } - } else { - increment_function(var_ptr); } - } else { increment_function(var_ptr); - } + } while (0); if (UNEXPECTED(0)) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -22646,34 +22629,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_RETVAL_USED_H ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval old; - ZVAL_COPY(&old, var_ptr); - - increment_function(var_ptr); - - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE(old) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 1); - ZVAL_COPY_VALUE(var_ptr, &old); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &old); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); - } else { - zval_ptr_dtor(&old); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, NULL, 1 EXECUTE_DATA_CC); + break; } - } else { - increment_function(var_ptr); } - } else { increment_function(var_ptr); - } + } while (0); if (UNEXPECTED(1)) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -22712,35 +22678,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_RETVAL_UNUSED ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval old; - ZVAL_COPY(&old, var_ptr); - - decrement_function(var_ptr); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE(old) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 0); - ZVAL_COPY_VALUE(var_ptr, &old); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &old); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); - } else { - zval_ptr_dtor(&old); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, NULL, 0 EXECUTE_DATA_CC); + break; } - } else { - decrement_function(var_ptr); } - } else { decrement_function(var_ptr); - } + } while (0); if (UNEXPECTED(0)) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -22779,35 +22728,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_RETVAL_USED_H ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval old; - ZVAL_COPY(&old, var_ptr); - - decrement_function(var_ptr); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE(old) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 0); - ZVAL_COPY_VALUE(var_ptr, &old); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &old); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); - } else { - zval_ptr_dtor(&old); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, NULL, 0 EXECUTE_DATA_CC); + break; } - } else { - decrement_function(var_ptr); } - } else { decrement_function(var_ptr); - } + } while (0); if (UNEXPECTED(1)) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -22842,28 +22774,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - - increment_function(var_ptr); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(EX_VAR(opline->result.var)) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 1); - ZVAL_COPY_VALUE(var_ptr, EX_VAR(opline->result.var)); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, EX_VAR(opline->result.var)); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, EX_VAR(opline->result.var), 1 EXECUTE_DATA_CC); + break; } } - } else { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); increment_function(var_ptr); - } + } while (0); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -22894,28 +22818,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - - decrement_function(var_ptr); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(EX_VAR(opline->result.var)) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 0); - ZVAL_COPY_VALUE(var_ptr, EX_VAR(opline->result.var)); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, EX_VAR(opline->result.var)); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, EX_VAR(opline->result.var), 0 EXECUTE_DATA_CC); + break; } } - } else { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); decrement_function(var_ptr); - } + } while (0); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -41699,34 +41615,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_RETVAL_UNUSED_ ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval old; - ZVAL_COPY(&old, var_ptr); - - increment_function(var_ptr); - - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE(old) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 1); - ZVAL_COPY_VALUE(var_ptr, &old); - - HANDLE_EXCEPTION(); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &old); - - HANDLE_EXCEPTION(); - } else { - zval_ptr_dtor(&old); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, NULL, 1 EXECUTE_DATA_CC); + break; } - } else { - increment_function(var_ptr); } - } else { increment_function(var_ptr); - } + } while (0); if (UNEXPECTED(0)) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -41764,34 +41663,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_RETVAL_USED_HA ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval old; - ZVAL_COPY(&old, var_ptr); - - increment_function(var_ptr); - - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE(old) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 1); - ZVAL_COPY_VALUE(var_ptr, &old); - - HANDLE_EXCEPTION(); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &old); - - HANDLE_EXCEPTION(); - } else { - zval_ptr_dtor(&old); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, NULL, 1 EXECUTE_DATA_CC); + break; } - } else { - increment_function(var_ptr); } - } else { increment_function(var_ptr); - } + } while (0); if (UNEXPECTED(1)) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -41829,35 +41711,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RETVAL_UNUSED_ ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval old; - ZVAL_COPY(&old, var_ptr); - - decrement_function(var_ptr); - - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE(old) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 0); - ZVAL_COPY_VALUE(var_ptr, &old); - - HANDLE_EXCEPTION(); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &old); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); - HANDLE_EXCEPTION(); - } else { - zval_ptr_dtor(&old); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, NULL, 0 EXECUTE_DATA_CC); + break; } - } else { - decrement_function(var_ptr); } - } else { decrement_function(var_ptr); - } + } while (0); if (UNEXPECTED(0)) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -41895,35 +41760,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RETVAL_USED_HA ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval old; - ZVAL_COPY(&old, var_ptr); - - decrement_function(var_ptr); - - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE(old) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 0); - ZVAL_COPY_VALUE(var_ptr, &old); - - HANDLE_EXCEPTION(); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &old); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); - HANDLE_EXCEPTION(); - } else { - zval_ptr_dtor(&old); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, NULL, 0 EXECUTE_DATA_CC); + break; } - } else { - decrement_function(var_ptr); } - } else { decrement_function(var_ptr); - } + } while (0); if (UNEXPECTED(1)) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -41957,28 +41805,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_ ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - - increment_function(var_ptr); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(EX_VAR(opline->result.var)) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 1); - ZVAL_COPY_VALUE(var_ptr, EX_VAR(opline->result.var)); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, EX_VAR(opline->result.var)); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, EX_VAR(opline->result.var), 1 EXECUTE_DATA_CC); + break; } } - } else { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); increment_function(var_ptr); - } + } while (0); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -42008,28 +41848,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_ ZVAL_UNDEFINED_OP1(); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - - decrement_function(var_ptr); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(EX_VAR(opline->result.var)) == IS_LONG) { - zend_throw_incdec_ref_error(ref, 0); - ZVAL_COPY_VALUE(var_ptr, EX_VAR(opline->result.var)); - } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, EX_VAR(opline->result.var)); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, EX_VAR(opline->result.var), 0 EXECUTE_DATA_CC); + break; } } - } else { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); decrement_function(var_ptr); - } + } while (0); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); }