mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Merge branch 'PHP-7.4'
This commit is contained in:
commit
4e4cc9b480
56
Zend/tests/closure_062.phpt
Normal file
56
Zend/tests/closure_062.phpt
Normal file
@ -0,0 +1,56 @@
|
||||
--TEST--
|
||||
Closure $this unbinding deprecation
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Test {
|
||||
public function method() {
|
||||
echo "instance scoped, non-static, \$this used\n";
|
||||
$fn = function() {
|
||||
var_dump($this);
|
||||
};
|
||||
$fn->bindTo(null);
|
||||
echo "instance scoped, static, \$this used\n";
|
||||
$fn = static function() {
|
||||
var_dump($this);
|
||||
};
|
||||
$fn->bindTo(null);
|
||||
echo "instance scoped, non-static, \$this not used\n";
|
||||
$fn = function() {
|
||||
var_dump($notThis);
|
||||
};
|
||||
$fn->bindTo(null);
|
||||
}
|
||||
|
||||
public static function staticMethod() {
|
||||
echo "static scoped, non-static, \$this used\n";
|
||||
$fn = function() {
|
||||
var_dump($this);
|
||||
};
|
||||
$fn->bindTo(null);
|
||||
echo "static scoped, static, \$this used\n";
|
||||
$fn = static function() {
|
||||
var_dump($this);
|
||||
};
|
||||
$fn->bindTo(null);
|
||||
echo "static scoped, static, \$this not used\n";
|
||||
$fn = function() {
|
||||
var_dump($notThis);
|
||||
};
|
||||
$fn->bindTo(null);
|
||||
}
|
||||
}
|
||||
|
||||
(new Test)->method();
|
||||
Test::staticMethod();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
instance scoped, non-static, $this used
|
||||
|
||||
Deprecated: Unbinding $this of closure is deprecated in %s on line %d
|
||||
instance scoped, static, $this used
|
||||
instance scoped, non-static, $this not used
|
||||
static scoped, non-static, $this used
|
||||
static scoped, static, $this used
|
||||
static scoped, static, $this not used
|
@ -86,7 +86,8 @@ static zend_bool zend_valid_closure_binding(
|
||||
&& !(func->common.fn_flags & ZEND_ACC_STATIC)) {
|
||||
zend_error(E_WARNING, "Cannot unbind $this of method");
|
||||
return 0;
|
||||
} else if (!is_fake_closure && !Z_ISUNDEF(closure->this_ptr)) {
|
||||
} else if (!is_fake_closure && !Z_ISUNDEF(closure->this_ptr)
|
||||
&& (func->common.fn_flags & ZEND_ACC_USES_THIS)) {
|
||||
// TODO: Only deprecate if it had $this *originally*?
|
||||
zend_error(E_DEPRECATED, "Unbinding $this of closure is deprecated");
|
||||
}
|
||||
|
@ -2357,6 +2357,7 @@ static zend_op *zend_compile_simple_var(znode *result, zend_ast *ast, uint32_t t
|
||||
opline->result_type = IS_TMP_VAR;
|
||||
result->op_type = IS_TMP_VAR;
|
||||
}
|
||||
CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS;
|
||||
return opline;
|
||||
} else if (zend_try_compile_cv(result, ast) == FAILURE) {
|
||||
return zend_compile_simple_var_no_cv(result, ast, type, delayed);
|
||||
@ -2451,6 +2452,7 @@ static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t
|
||||
|
||||
if (is_this_fetch(obj_ast)) {
|
||||
obj_node.op_type = IS_UNUSED;
|
||||
CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS;
|
||||
} else {
|
||||
opline = zend_delayed_compile_var(&obj_node, obj_ast, type, 0);
|
||||
if (opline && type == BP_VAR_W && (opline->opcode == ZEND_FETCH_STATIC_PROP_W || opline->opcode == ZEND_FETCH_OBJ_W)) {
|
||||
@ -2987,6 +2989,7 @@ uint32_t zend_compile_args(zend_ast *ast, zend_function *fbc) /* {{{ */
|
||||
if (is_this_fetch(arg)) {
|
||||
zend_emit_op(&arg_node, ZEND_FETCH_THIS, NULL, NULL);
|
||||
opcode = ZEND_SEND_VAR_EX;
|
||||
CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS;
|
||||
break;
|
||||
} else if (zend_try_compile_cv(&arg_node, arg) == SUCCESS) {
|
||||
opcode = ZEND_SEND_VAR_EX;
|
||||
@ -3846,6 +3849,7 @@ void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type) /* {{
|
||||
|
||||
if (is_this_fetch(obj_ast)) {
|
||||
obj_node.op_type = IS_UNUSED;
|
||||
CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS;
|
||||
} else {
|
||||
zend_compile_expr(&obj_node, obj_ast);
|
||||
}
|
||||
@ -7654,6 +7658,7 @@ void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */
|
||||
case ZEND_AST_VAR:
|
||||
if (is_this_fetch(var_ast)) {
|
||||
opline = zend_emit_op(result, ZEND_ISSET_ISEMPTY_THIS, NULL, NULL);
|
||||
CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS;
|
||||
} else if (zend_try_compile_cv(&var_node, var_ast) == SUCCESS) {
|
||||
opline = zend_emit_op(result, ZEND_ISSET_ISEMPTY_CV, &var_node, NULL);
|
||||
} else {
|
||||
|
@ -333,6 +333,9 @@ typedef struct _zend_oparray_context {
|
||||
/* function is a destructor | | | */
|
||||
#define ZEND_ACC_DTOR (1 << 29) /* | X | | */
|
||||
/* | | | */
|
||||
/* closure uses $this | | | */
|
||||
#define ZEND_ACC_USES_THIS (1 << 30) /* | X | | */
|
||||
/* | | | */
|
||||
/* op_array uses strict mode types | | | */
|
||||
#define ZEND_ACC_STRICT_TYPES (1U << 31) /* | X | | */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user