]> granicus.if.org Git - php/commitdiff
Return "new" by reference now throws an E_STRICT error
authorDmitry Stogov <dmitry@php.net>
Thu, 16 Mar 2006 15:35:26 +0000 (15:35 +0000)
committerDmitry Stogov <dmitry@php.net>
Thu, 16 Mar 2006 15:35:26 +0000 (15:35 +0000)
NEWS
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_language_parser.y
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index e00d1d7dae5d3374dd3f576fe751d269458a073a..54015b2a30d7b2eb0aceeb29dcb26349796003d9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? ????, PHP 6.0
 - Unicode support. (Andrei, Dmitry, et al)
+- Return "new" by reference now throws an E_STRICT error. (Dmitry)
 - Added E_STRICT to E_ALL. (Dmitry)
 - Dropped safe_mode support (Ilia, Andi)
 - Dropped zend.ze1_compatibility_mode (Dmitry)
index f191def926099139744cf0e11c002e4594a8ea17..6389b68ce1b119473140925a42d6469b290d3b0a 100644 (file)
@@ -1807,10 +1807,12 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC)
 
        if (do_end_vparse) {
                if (zend_is_function_or_method_call(expr)) {
-                       opline->extended_value = ZEND_RETURNS_FUNCTION;
-               } else {
-                       opline->extended_value = 0;
+                       opline->extended_value = ZEND_RETURNS_FUNCTION;                 
                }
+       } else if (CG(active_op_array)->return_reference && 
+                  expr && expr->u.EA.type == ZEND_PARSED_NEW) {
+               opline->extended_value = ZEND_RETURNS_NEW;
+               zend_error(E_STRICT, "Returning the return value of new by reference is deprecated");
        }
 
        SET_UNUSED(opline->op2);
index 8f01b562b2cef1b8f4eb361927568cfe3805b1ab..a955a22fb5e93f6d762b8df3021a26f07f3bb1cb 100644 (file)
@@ -621,6 +621,7 @@ int zendlex(znode *zendlval TSRMLS_DC);
 #define ZEND_PARSED_FUNCTION_CALL              (1<<3)
 #define ZEND_PARSED_VARIABLE                   (1<<4)
 #define ZEND_PARSED_REFERENCE_VARIABLE (1<<5)
+#define ZEND_PARSED_NEW                                        (1<<6)
 
 
 /* unset types */
@@ -724,6 +725,7 @@ int zendlex(znode *zendlval TSRMLS_DC);
 
 
 #define ZEND_RETURNS_FUNCTION 1<<0
+#define ZEND_RETURNS_NEW      1<<1
 
 END_EXTERN_C()
 
index 0d371fbfa13f4625a107f0509d45acd469833866..d9d238a4d4cad29d6afcd5293a4080708c7677f3 100644 (file)
@@ -561,7 +561,7 @@ expr_without_variable:
        |       variable '=' expr               { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign(&$$, &$1, &$3 TSRMLS_CC); }
        |       variable '=' '&' variable { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); }
        |       variable '=' '&' T_NEW class_name_reference { zend_error(E_STRICT, "Assigning the return value of new by reference is deprecated");  zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
-       |       T_NEW class_name_reference { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$1, &$2 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+       |       T_NEW class_name_reference { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$1, &$2 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); $$.u.EA.type = ZEND_PARSED_NEW; }
        |       T_CLONE expr { zend_do_clone(&$$, &$2 TSRMLS_CC); }
        |       variable T_PLUS_EQUAL expr      { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 TSRMLS_CC); }
        |       variable T_MINUS_EQUAL expr     { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SUB, &$$, &$1, &$3 TSRMLS_CC); }
index 040f039ae2d5347408082e3cf0624a06254e76f5..926168efe59cffd5a797702a63fd635e5a7b2605 100644 (file)
@@ -2057,11 +2057,14 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
                if (OP1_TYPE == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
                        if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
                            EX_T(opline->op1.u.var).var.fcall_returned_reference) {
+                       } else if (opline->extended_value == ZEND_RETURNS_NEW) {
                        } else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
                                if (OP1_TYPE == IS_VAR && !OP1_FREE) {
                                        PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
                                }
-                               zend_error(E_NOTICE, "Only variable references should be returned by reference");
+//                             if (opline->extended_value != ZEND_RETURNS_NEW) {
+                                       zend_error(E_NOTICE, "Only variable references should be returned by reference");
+//                             }
                                ZEND_VM_C_GOTO(return_by_value);
                        }
                }
index cb2fdb732cdc6e174849fb384a44ba488086ea67..c47387dc99089f8f2c151f533d54d9c3c40ed842 100644 (file)
@@ -1634,11 +1634,14 @@ static int ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                if (IS_CONST == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
                        if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
                            EX_T(opline->op1.u.var).var.fcall_returned_reference) {
+                       } else if (opline->extended_value == ZEND_RETURNS_NEW) {
                        } else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
                                if (IS_CONST == IS_VAR && !0) {
                                        PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
                                }
-                               zend_error(E_NOTICE, "Only variable references should be returned by reference");
+//                             if (opline->extended_value != ZEND_RETURNS_NEW) {
+                                       zend_error(E_NOTICE, "Only variable references should be returned by reference");
+//                             }
                                goto return_by_value;
                        }
                }
@@ -4109,11 +4112,14 @@ static int ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                if (IS_TMP_VAR == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
                        if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
                            EX_T(opline->op1.u.var).var.fcall_returned_reference) {
+                       } else if (opline->extended_value == ZEND_RETURNS_NEW) {
                        } else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
                                if (IS_TMP_VAR == IS_VAR && !1) {
                                        PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
                                }
-                               zend_error(E_NOTICE, "Only variable references should be returned by reference");
+//                             if (opline->extended_value != ZEND_RETURNS_NEW) {
+                                       zend_error(E_NOTICE, "Only variable references should be returned by reference");
+//                             }
                                goto return_by_value;
                        }
                }
@@ -7091,11 +7097,14 @@ static int ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                if (IS_VAR == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
                        if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
                            EX_T(opline->op1.u.var).var.fcall_returned_reference) {
+                       } else if (opline->extended_value == ZEND_RETURNS_NEW) {
                        } else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
                                if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
                                        PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
                                }
-                               zend_error(E_NOTICE, "Only variable references should be returned by reference");
+//                             if (opline->extended_value != ZEND_RETURNS_NEW) {
+                                       zend_error(E_NOTICE, "Only variable references should be returned by reference");
+//                             }
                                goto return_by_value;
                        }
                }
@@ -19715,11 +19724,14 @@ static int ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                if (IS_CV == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
                        if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
                            EX_T(opline->op1.u.var).var.fcall_returned_reference) {
+                       } else if (opline->extended_value == ZEND_RETURNS_NEW) {
                        } else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
                                if (IS_CV == IS_VAR && !0) {
                                        PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
                                }
-                               zend_error(E_NOTICE, "Only variable references should be returned by reference");
+//                             if (opline->extended_value != ZEND_RETURNS_NEW) {
+                                       zend_error(E_NOTICE, "Only variable references should be returned by reference");
+//                             }
                                goto return_by_value;
                        }
                }