Bug #22836 (returning references to NULL)
--SKIPIF--
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
---INI--
-error_reporting=4095
--FILE--
<?php
function &f()
$x = "foo";
var_dump($x);
print "'$x'\n";
- return $a;
+ return ($a);
}
for ($i = 0; $i < 8; $i++) {
$h =& f();
--EXPECTF--
string(3) "foo"
'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
string(3) "foo"
'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
string(3) "foo"
'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
string(3) "foo"
'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
string(3) "foo"
'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
string(3) "foo"
'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
string(3) "foo"
'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
string(3) "foo"
'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
-string(3) "foo"
-'foo'
-
-Notice: Undefined variable: a in %s on line %d
-
-Strict Standards: Only variable references should be returned by reference in %s on line %d
-
-
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (!(*retval_ptr_ptr)->is_ref) {
+ if (OP1_TYPE == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
|| (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
zend_error(E_STRICT, "Only variable references should be returned by reference");
ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
*EG(return_value_ptr_ptr) = ret;
} else if (!IS_OP1_TMP_FREE()) { /* Not a temp var */
- if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) {
+ if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
+ (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
zval *ret;
ALLOC_ZVAL(ret);
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (!(*retval_ptr_ptr)->is_ref) {
+ if (IS_CONST == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
|| (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
zend_error(E_STRICT, "Only variable references should be returned by reference");
ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
*EG(return_value_ptr_ptr) = ret;
} else if (!0) { /* Not a temp var */
- if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) {
+ if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
+ (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
zval *ret;
ALLOC_ZVAL(ret);
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (!(*retval_ptr_ptr)->is_ref) {
+ if (IS_TMP_VAR == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
|| (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
zend_error(E_STRICT, "Only variable references should be returned by reference");
ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
*EG(return_value_ptr_ptr) = ret;
} else if (!1) { /* Not a temp var */
- if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) {
+ if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
+ (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
zval *ret;
ALLOC_ZVAL(ret);
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (!(*retval_ptr_ptr)->is_ref) {
+ if (IS_VAR == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
|| (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
zend_error(E_STRICT, "Only variable references should be returned by reference");
ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
*EG(return_value_ptr_ptr) = ret;
} else if (!0) { /* Not a temp var */
- if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) {
+ if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
+ (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
zval *ret;
ALLOC_ZVAL(ret);
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (!(*retval_ptr_ptr)->is_ref) {
+ if (IS_CV == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
|| (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
zend_error(E_STRICT, "Only variable references should be returned by reference");
ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
*EG(return_value_ptr_ptr) = ret;
} else if (!0) { /* Not a temp var */
- if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) {
+ if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
+ (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
zval *ret;
ALLOC_ZVAL(ret);
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (!(*retval_ptr_ptr)->is_ref) {
+ if (opline->op1.op_type == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr
|| (opline->extended_value == ZEND_RETURNS_FUNCTION && !EX_T(opline->op1.u.var).var.fcall_returned_reference)) {
zend_error(E_STRICT, "Only variable references should be returned by reference");
ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
*EG(return_value_ptr_ptr) = ret;
} else if (!IS_TMP_FREE(free_op1)) { /* Not a temp var */
- if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) {
+ if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
+ (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
zval *ret;
ALLOC_ZVAL(ret);