mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Remove assignment of new by reference
This commit is contained in:
1
NEWS
1
NEWS
@@ -37,6 +37,7 @@
|
||||
. Removed scoped calls of non-static methods from an incompatible $this
|
||||
context. (Nikita)
|
||||
. Removed support for #-style comments in ini files. (Nikita)
|
||||
. Removed support for assigning the result of new by reference. (Nikita)
|
||||
. Invalid octal literals in source code now produce compile errors, fixes PHPSadness #31. (Andrea)
|
||||
|
||||
- Date:
|
||||
|
||||
@@ -54,6 +54,7 @@ PHP X.Y UPGRADE NOTES
|
||||
. zend_function.common.num_args don't include the variadic argument anymore.
|
||||
. ob_start() no longer issues an E_ERROR, but instead an E_RECOVERABLE_ERROR in case an
|
||||
output buffer is created in an output buffer handler.
|
||||
. Removed support for assigning the result of new by reference.
|
||||
. Removed support for scoped calls to non-static methods from an incompatible
|
||||
$this context. See details in https://wiki.php.net/rfc/incompat_ctx.
|
||||
. Removed support for #-style comments in ini files. Use ;-style comments
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
--TEST--
|
||||
Bug #45178 memory corruption on assignment result of "new" by reference
|
||||
--FILE--
|
||||
<?php
|
||||
class Foo {
|
||||
function __construct() {
|
||||
$this->error = array($this,$this);
|
||||
}
|
||||
}
|
||||
$a =& new Foo();
|
||||
|
||||
class Bar {
|
||||
function __construct() {
|
||||
$this->_rme2 = $this;
|
||||
}
|
||||
}
|
||||
|
||||
$b =& new Bar();
|
||||
$b->_rme2 = 0;
|
||||
var_dump($b);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Assigning the return value of new by reference is deprecated in %sbug45178.php on line 7
|
||||
|
||||
Deprecated: Assigning the return value of new by reference is deprecated in %sbug45178.php on line 15
|
||||
object(Bar)#%d (1) {
|
||||
["_rme2"]=>
|
||||
int(0)
|
||||
}
|
||||
@@ -2341,9 +2341,6 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */
|
||||
|
||||
if (zend_is_call(source_ast)) {
|
||||
opline->extended_value = ZEND_RETURNS_FUNCTION;
|
||||
} else if (source_ast->kind == ZEND_AST_NEW) {
|
||||
zend_error(E_DEPRECATED, "Assigning the return value of new by reference is deprecated");
|
||||
opline->extended_value = ZEND_RETURNS_NEW;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@@ -6361,11 +6358,8 @@ void zend_compile_var(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
|
||||
if (type == BP_VAR_W || type == BP_VAR_REF
|
||||
|| type == BP_VAR_RW || type == BP_VAR_UNSET
|
||||
) {
|
||||
/* For BC reasons =& new Foo is allowed */
|
||||
if (type != BP_VAR_REF || ast->kind != ZEND_AST_NEW) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR,
|
||||
"Cannot use temporary expression in write context");
|
||||
}
|
||||
zend_error_noreturn(E_COMPILE_ERROR,
|
||||
"Cannot use temporary expression in write context");
|
||||
}
|
||||
|
||||
zend_compile_expr(result, ast);
|
||||
|
||||
@@ -858,8 +858,7 @@ static zend_always_inline int zend_check_arg_send_type(const zend_function *zf,
|
||||
|
||||
|
||||
#define ZEND_RETURNS_FUNCTION 1<<0
|
||||
#define ZEND_RETURNS_NEW 1<<1
|
||||
#define ZEND_RETURNS_VALUE 1<<2
|
||||
#define ZEND_RETURNS_VALUE 1<<1
|
||||
|
||||
#define ZEND_FAST_RET_TO_CATCH 1
|
||||
#define ZEND_FAST_RET_TO_FINALLY 2
|
||||
|
||||
@@ -769,8 +769,6 @@ expr_without_variable:
|
||||
{ $$ = zend_ast_create(ZEND_AST_ASSIGN, $1, $3); }
|
||||
| variable '=' '&' variable
|
||||
{ $$ = zend_ast_create(ZEND_AST_ASSIGN_REF, $1, $4); }
|
||||
| variable '=' '&' new_expr
|
||||
{ $$ = zend_ast_create(ZEND_AST_ASSIGN_REF, $1, $4); }
|
||||
| T_CLONE expr { $$ = zend_ast_create(ZEND_AST_CLONE, $2); }
|
||||
| variable T_PLUS_EQUAL expr
|
||||
{ $$ = zend_ast_create_assign_op(ZEND_ASSIGN_ADD, $1, $3); }
|
||||
|
||||
@@ -1818,10 +1818,6 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ASSIGN);
|
||||
} else if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
if (!OP2_FREE) {
|
||||
PZVAL_LOCK(value_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
|
||||
@@ -1840,12 +1836,6 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
|
||||
zend_assign_to_variable_reference(variable_ptr, value_ptr);
|
||||
}
|
||||
|
||||
if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
if (!OP2_FREE) {
|
||||
Z_DELREF_P(variable_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
|
||||
}
|
||||
|
||||
@@ -14200,10 +14200,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
return ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
if (!(free_op2 != NULL)) {
|
||||
PZVAL_LOCK(value_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1);
|
||||
@@ -14222,12 +14218,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
|
||||
zend_assign_to_variable_reference(variable_ptr, value_ptr);
|
||||
}
|
||||
|
||||
if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
if (!(free_op2 != NULL)) {
|
||||
Z_DELREF_P(variable_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
|
||||
}
|
||||
@@ -16210,10 +16200,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
return ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
if (!0) {
|
||||
PZVAL_LOCK(value_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1);
|
||||
@@ -16232,12 +16218,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
|
||||
zend_assign_to_variable_reference(variable_ptr, value_ptr);
|
||||
}
|
||||
|
||||
if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
if (!0) {
|
||||
Z_DELREF_P(variable_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
|
||||
}
|
||||
@@ -27366,10 +27346,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
return ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
if (!(free_op2 != NULL)) {
|
||||
PZVAL_LOCK(value_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var);
|
||||
@@ -27388,12 +27364,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
|
||||
zend_assign_to_variable_reference(variable_ptr, value_ptr);
|
||||
}
|
||||
|
||||
if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
if (!(free_op2 != NULL)) {
|
||||
Z_DELREF_P(variable_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
|
||||
}
|
||||
@@ -30132,10 +30102,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
return ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
if (!0) {
|
||||
PZVAL_LOCK(value_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var);
|
||||
@@ -30154,12 +30120,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
|
||||
zend_assign_to_variable_reference(variable_ptr, value_ptr);
|
||||
}
|
||||
|
||||
if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
if (!0) {
|
||||
Z_DELREF_P(variable_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
--TEST--
|
||||
Bug #31402 (unserialize() generates references when it should not)
|
||||
--INI--
|
||||
error_reporting=E_ALL&~E_STRICT&~E_DEPRECATED
|
||||
error_reporting=E_ALL
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
@@ -19,7 +19,8 @@ class TestY {
|
||||
|
||||
function __construct() {
|
||||
$this->A[1] = new TestX(1);
|
||||
$this->A[2] = & new TestX(2);
|
||||
$obj = new TestX(2);
|
||||
$this->A[2] = & $obj;
|
||||
$this->A[3] = & $this->A[2];
|
||||
$this->B = $this->A[1];
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
--TEST--
|
||||
Confirm difference between assigning new directly and by reference.
|
||||
--INI--
|
||||
error_reporting=E_ALL | E_DEPRECATED
|
||||
--FILE--
|
||||
<?php
|
||||
echo "Compile-time strict error message should precede this.\n";
|
||||
|
||||
class Inc
|
||||
{
|
||||
private static $counter = 0;
|
||||
function __construct()
|
||||
{
|
||||
$this->id = ++Inc::$counter;
|
||||
}
|
||||
}
|
||||
|
||||
$f = new Inc();
|
||||
$k =& $f;
|
||||
echo "\$f initially points to the first object:\n";
|
||||
var_dump($f);
|
||||
|
||||
echo "Assigning new object directly to \$k affects \$f:\n";
|
||||
$k = new Inc();
|
||||
var_dump($f);
|
||||
|
||||
echo "Assigning new object by ref to \$k removes it from \$f's reference set, so \$f is unchanged:\n";
|
||||
$k =& new Inc();
|
||||
var_dump($f);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Assigning the return value of new by reference is deprecated in %s on line 23
|
||||
Compile-time strict error message should precede this.
|
||||
$f initially points to the first object:
|
||||
object(Inc)#%d (1) {
|
||||
["id"]=>
|
||||
int(1)
|
||||
}
|
||||
Assigning new object directly to $k affects $f:
|
||||
object(Inc)#%d (1) {
|
||||
["id"]=>
|
||||
int(2)
|
||||
}
|
||||
Assigning new object by ref to $k removes it from $f's reference set, so $f is unchanged:
|
||||
object(Inc)#%d (1) {
|
||||
["id"]=>
|
||||
int(2)
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
--TEST--
|
||||
Bug #20175 (Static vars can't store ref to new instance)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(),'2.0.0-dev','<')) die('skip ZE1 does not have static class members'); ?>
|
||||
--INI--
|
||||
error_reporting=E_ALL | E_STRICT | E_DEPRECATED
|
||||
error_reporting=E_ALL
|
||||
--FILE--
|
||||
<?php
|
||||
print zend_version()."\n";
|
||||
@@ -114,7 +112,7 @@ class oop_test {
|
||||
function oop_static() {
|
||||
echo "oop_static()\n";
|
||||
if (!isset(self::$oop_value)) {
|
||||
self::$oop_value = & new oop_class;
|
||||
self::$oop_value = new oop_class;
|
||||
}
|
||||
echo self::$oop_value->oop_name;
|
||||
}
|
||||
@@ -139,7 +137,6 @@ $oop_tester = new oop_test; // repeated.
|
||||
print $oop_tester->oop_static()."\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Assigning the return value of new by reference is deprecated in %s.php on line %d
|
||||
%s
|
||||
foo_static()
|
||||
foo_global()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
--TEST--
|
||||
Bug #22231 (segfault when returning a global variable by reference)
|
||||
--INI--
|
||||
error_reporting=E_ALL | E_DEPRECATED
|
||||
error_reporting=E_ALL
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
@@ -9,7 +9,8 @@ class foo {
|
||||
}
|
||||
|
||||
function &foo(){
|
||||
$GLOBALS['foo'] = &new foo();
|
||||
$obj = new foo();
|
||||
$GLOBALS['foo'] = &$obj;
|
||||
return $GLOBALS['foo'];
|
||||
}
|
||||
$bar = &foo();
|
||||
@@ -27,7 +28,6 @@ $foo = &foo();
|
||||
var_dump($foo->fubar);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Assigning the return value of new by reference is deprecated in %s on line %d
|
||||
object(foo)#%d (1) {
|
||||
["fubar"]=>
|
||||
string(5) "fubar"
|
||||
|
||||
@@ -76,7 +76,8 @@ function ok3(&$bar) {
|
||||
$bar->run3();
|
||||
}
|
||||
|
||||
$bar = &new bar();
|
||||
$foo = new bar();
|
||||
$bar =& $foo;
|
||||
ok1($bar);
|
||||
$bar->instance->finalize();
|
||||
print "done!\n";
|
||||
@@ -91,7 +92,6 @@ $bar->instance->finalize();
|
||||
print "I'm alive!\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Assigning the return value of new by reference is deprecated in %s on line %d
|
||||
ok1
|
||||
bar::run1
|
||||
foo::method1
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
--TEST--
|
||||
Check key execution order with &new.
|
||||
Check key execution order with new.
|
||||
--FILE--
|
||||
<?php
|
||||
$a[2][3] = 'stdClass';
|
||||
$a[$i=0][++$i] =& new $a[++$i][++$i];
|
||||
$a[$i=0][++$i] = new $a[++$i][++$i];
|
||||
print_r($a);
|
||||
|
||||
$o = new stdClass;
|
||||
$o->a =& new $a[$i=2][++$i];
|
||||
$o->a->b =& new $a[$i=2][++$i];
|
||||
$o->a = new $a[$i=2][++$i];
|
||||
$o->a->b = new $a[$i=2][++$i];
|
||||
print_r($o);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Assigning the return value of new by reference is deprecated in %s.php on line 3
|
||||
|
||||
Deprecated: Assigning the return value of new by reference is deprecated in %s.php on line 7
|
||||
|
||||
Deprecated: Assigning the return value of new by reference is deprecated in %s.php on line 8
|
||||
Array
|
||||
(
|
||||
[2] => Array
|
||||
|
||||
Reference in New Issue
Block a user