]> granicus.if.org Git - php/commitdiff
Fix incdec of referenced properties
authorNikita Popov <nikic@php.net>
Sun, 12 Oct 2014 18:39:07 +0000 (20:39 +0200)
committerNikita Popov <nikic@php.net>
Sun, 12 Oct 2014 18:55:52 +0000 (20:55 +0200)
I thought these SEPARATE_ZVAL_IF_NOT_REF usages were safe at first,
because incdec op supports reference variables. However this
violates the constraint that IS_TMP_VAR variables may not be
references (which is an issue if you use the result of the incdec
op).

Still need to fix the cases where read_property/write_property is
used.

.gdbinit
Zend/tests/incdec_ref_property.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 98bb173a5a672921f73a2c36f22a31d3b63bdf64..498099a411536f93d49cc1ce2a6c73c294f6ef4b 100644 (file)
--- a/.gdbinit
+++ b/.gdbinit
@@ -53,11 +53,11 @@ define dump_bt
                printf "[%p] ", $ex
                set $func = $ex->func
                if $func
-                       if $ex->object
+                       if $ex->This->value.obj
                                if $func->common.scope
                                        printf "%s->", $func->common.scope->name->val
                                else
-                                       printf "%s->", $ex->object->ce.name->val
+                                       printf "%s->", $ex->This->value.obj->ce.name->val
                                end
                        else
                                if $func->common.scope
diff --git a/Zend/tests/incdec_ref_property.phpt b/Zend/tests/incdec_ref_property.phpt
new file mode 100644 (file)
index 0000000..a73b291
--- /dev/null
@@ -0,0 +1,27 @@
+--TEST--
+Incrementing and decrementing a referenced property
+--FILE--
+<?php
+
+$obj = new stdClass;
+$obj->prop = 1;
+$ref =& $obj->prop;
+var_dump(++$obj->prop);
+var_dump($obj->prop);
+var_dump($obj->prop++);
+var_dump($obj->prop);
+var_dump(--$obj->prop);
+var_dump($obj->prop);
+var_dump($obj->prop--);
+var_dump($obj->prop);
+
+?>
+--EXPECT--
+int(2)
+int(2)
+int(2)
+int(3)
+int(2)
+int(2)
+int(2)
+int(1)
index 736ce178d68bf07ff793f3a2cbd9b9c412427af3..091b384c3357a0246371ea8d3f0b1937ad26b874 100644 (file)
@@ -719,7 +719,8 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
+                       ZVAL_DEREF(zptr);
+                       SEPARATE_ZVAL_NOREF(zptr);
 
                        have_get_ptr = 1;
                        incdec_op(zptr);
@@ -812,12 +813,11 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
                        have_get_ptr = 1;
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
-
-                       ZVAL_DUP(retval, zptr);
+                       ZVAL_DEREF(zptr);
+                       ZVAL_COPY(retval, zptr);
 
+                       SEPARATE_ZVAL_NOREF(zptr);
                        incdec_op(zptr);
-
                }
        }
 
index af0cd96bbfc444b0f3bbdc7a6fc0f4ee34cc191f..9f8be5ceb0afc4fddcfaa18da0e55bb387366418 100644 (file)
@@ -17918,7 +17918,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
+                       ZVAL_DEREF(zptr);
+                       SEPARATE_ZVAL_NOREF(zptr);
 
                        have_get_ptr = 1;
                        incdec_op(zptr);
@@ -18010,12 +18011,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
                        have_get_ptr = 1;
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
-
-                       ZVAL_DUP(retval, zptr);
+                       ZVAL_DEREF(zptr);
+                       ZVAL_COPY(retval, zptr);
 
+                       SEPARATE_ZVAL_NOREF(zptr);
                        incdec_op(zptr);
-
                }
        }
 
@@ -20356,7 +20356,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
+                       ZVAL_DEREF(zptr);
+                       SEPARATE_ZVAL_NOREF(zptr);
 
                        have_get_ptr = 1;
                        incdec_op(zptr);
@@ -20449,12 +20450,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
                        have_get_ptr = 1;
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
-
-                       ZVAL_DUP(retval, zptr);
+                       ZVAL_DEREF(zptr);
+                       ZVAL_COPY(retval, zptr);
 
+                       SEPARATE_ZVAL_NOREF(zptr);
                        incdec_op(zptr);
-
                }
        }
 
@@ -22368,7 +22368,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
+                       ZVAL_DEREF(zptr);
+                       SEPARATE_ZVAL_NOREF(zptr);
 
                        have_get_ptr = 1;
                        incdec_op(zptr);
@@ -22461,12 +22462,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
                        have_get_ptr = 1;
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
-
-                       ZVAL_DUP(retval, zptr);
+                       ZVAL_DEREF(zptr);
+                       ZVAL_COPY(retval, zptr);
 
+                       SEPARATE_ZVAL_NOREF(zptr);
                        incdec_op(zptr);
-
                }
        }
 
@@ -25946,7 +25946,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
+                       ZVAL_DEREF(zptr);
+                       SEPARATE_ZVAL_NOREF(zptr);
 
                        have_get_ptr = 1;
                        incdec_op(zptr);
@@ -26038,12 +26039,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
                        have_get_ptr = 1;
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
-
-                       ZVAL_DUP(retval, zptr);
+                       ZVAL_DEREF(zptr);
+                       ZVAL_COPY(retval, zptr);
 
+                       SEPARATE_ZVAL_NOREF(zptr);
                        incdec_op(zptr);
-
                }
        }
 
@@ -27815,7 +27815,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
+                       ZVAL_DEREF(zptr);
+                       SEPARATE_ZVAL_NOREF(zptr);
 
                        have_get_ptr = 1;
                        incdec_op(zptr);
@@ -27907,12 +27908,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
                        have_get_ptr = 1;
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
-
-                       ZVAL_DUP(retval, zptr);
+                       ZVAL_DEREF(zptr);
+                       ZVAL_COPY(retval, zptr);
 
+                       SEPARATE_ZVAL_NOREF(zptr);
                        incdec_op(zptr);
-
                }
        }
 
@@ -29206,7 +29206,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
+                       ZVAL_DEREF(zptr);
+                       SEPARATE_ZVAL_NOREF(zptr);
 
                        have_get_ptr = 1;
                        incdec_op(zptr);
@@ -29299,12 +29300,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
                        have_get_ptr = 1;
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
-
-                       ZVAL_DUP(retval, zptr);
+                       ZVAL_DEREF(zptr);
+                       ZVAL_COPY(retval, zptr);
 
+                       SEPARATE_ZVAL_NOREF(zptr);
                        incdec_op(zptr);
-
                }
        }
 
@@ -30514,7 +30514,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
+                       ZVAL_DEREF(zptr);
+                       SEPARATE_ZVAL_NOREF(zptr);
 
                        have_get_ptr = 1;
                        incdec_op(zptr);
@@ -30607,12 +30608,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
                        have_get_ptr = 1;
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
-
-                       ZVAL_DUP(retval, zptr);
+                       ZVAL_DEREF(zptr);
+                       ZVAL_COPY(retval, zptr);
 
+                       SEPARATE_ZVAL_NOREF(zptr);
                        incdec_op(zptr);
-
                }
        }
 
@@ -32340,7 +32340,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
+                       ZVAL_DEREF(zptr);
+                       SEPARATE_ZVAL_NOREF(zptr);
 
                        have_get_ptr = 1;
                        incdec_op(zptr);
@@ -32432,12 +32433,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
                        have_get_ptr = 1;
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
-
-                       ZVAL_DUP(retval, zptr);
+                       ZVAL_DEREF(zptr);
+                       ZVAL_COPY(retval, zptr);
 
+                       SEPARATE_ZVAL_NOREF(zptr);
                        incdec_op(zptr);
-
                }
        }
 
@@ -35321,7 +35321,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
+                       ZVAL_DEREF(zptr);
+                       SEPARATE_ZVAL_NOREF(zptr);
 
                        have_get_ptr = 1;
                        incdec_op(zptr);
@@ -35413,12 +35414,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
                        have_get_ptr = 1;
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
-
-                       ZVAL_DUP(retval, zptr);
+                       ZVAL_DEREF(zptr);
+                       ZVAL_COPY(retval, zptr);
 
+                       SEPARATE_ZVAL_NOREF(zptr);
                        incdec_op(zptr);
-
                }
        }
 
@@ -37592,7 +37592,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
+                       ZVAL_DEREF(zptr);
+                       SEPARATE_ZVAL_NOREF(zptr);
 
                        have_get_ptr = 1;
                        incdec_op(zptr);
@@ -37685,12 +37686,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
                        have_get_ptr = 1;
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
-
-                       ZVAL_DUP(retval, zptr);
+                       ZVAL_DEREF(zptr);
+                       ZVAL_COPY(retval, zptr);
 
+                       SEPARATE_ZVAL_NOREF(zptr);
                        incdec_op(zptr);
-
                }
        }
 
@@ -39476,7 +39476,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
+                       ZVAL_DEREF(zptr);
+                       SEPARATE_ZVAL_NOREF(zptr);
 
                        have_get_ptr = 1;
                        incdec_op(zptr);
@@ -39569,12 +39570,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
                        have_get_ptr = 1;
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
-
-                       ZVAL_DUP(retval, zptr);
+                       ZVAL_DEREF(zptr);
+                       ZVAL_COPY(retval, zptr);
 
+                       SEPARATE_ZVAL_NOREF(zptr);
                        incdec_op(zptr);
-
                }
        }
 
@@ -42781,7 +42781,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
+                       ZVAL_DEREF(zptr);
+                       SEPARATE_ZVAL_NOREF(zptr);
 
                        have_get_ptr = 1;
                        incdec_op(zptr);
@@ -42873,12 +42874,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in
                zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
                        have_get_ptr = 1;
-                       SEPARATE_ZVAL_IF_NOT_REF(zptr);
-
-                       ZVAL_DUP(retval, zptr);
+                       ZVAL_DEREF(zptr);
+                       ZVAL_COPY(retval, zptr);
 
+                       SEPARATE_ZVAL_NOREF(zptr);
                        incdec_op(zptr);
-
                }
        }