From 89a1a4cbc4ba43f05b4615c9793e7786f4350268 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 16 Mar 2006 15:35:26 +0000 Subject: [PATCH] Return "new" by reference now throws an E_STRICT error --- NEWS | 1 + Zend/zend_compile.c | 8 +++++--- Zend/zend_compile.h | 2 ++ Zend/zend_language_parser.y | 2 +- Zend/zend_vm_def.h | 5 ++++- Zend/zend_vm_execute.h | 20 ++++++++++++++++---- 6 files changed, 29 insertions(+), 9 deletions(-) diff --git a/NEWS b/NEWS index e00d1d7dae..54015b2a30 100644 --- 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) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index f191def926..6389b68ce1 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 8f01b562b2..a955a22fb5 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -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() diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 0d371fbfa1..d9d238a4d4 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -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); } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 040f039ae2..926168efe5 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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); } } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index cb2fdb732c..c47387dc99 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -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; } } -- 2.50.1