Skip to content

Commit

Permalink
Return "new" by reference now throws an E_STRICT error
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Mar 16, 2006
1 parent c9dfb79 commit 89a1a4c
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 9 deletions.
1 change: 1 addition & 0 deletions NEWS
Expand Up @@ -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)
Expand Down
8 changes: 5 additions & 3 deletions Zend/zend_compile.c
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions Zend/zend_compile.h
Expand Up @@ -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 */
Expand Down Expand Up @@ -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()

Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_language_parser.y
Expand Up @@ -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); }
Expand Down
5 changes: 4 additions & 1 deletion Zend/zend_vm_def.h
Expand Up @@ -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);
}
}
Expand Down
20 changes: 16 additions & 4 deletions Zend/zend_vm_execute.h
Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
}
}
Expand Down

0 comments on commit 89a1a4c

Please sign in to comment.