Skip to content

Commit da1e254

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: Fix `ReflectionFunction::isDeprecated()` for materialized `__call()` (php#17914)
2 parents 2b2a70d + 2e999ba commit da1e254

File tree

2 files changed

+74
-2
lines changed

2 files changed

+74
-2
lines changed

Zend/zend_closures.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -366,11 +366,12 @@ static zend_result zend_create_closure_from_callable(zval *return_value, zval *c
366366

367367
memset(&call, 0, sizeof(zend_internal_function));
368368
call.type = ZEND_INTERNAL_FUNCTION;
369-
call.fn_flags = mptr->common.fn_flags & ZEND_ACC_STATIC;
369+
call.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC | ZEND_ACC_DEPRECATED);
370370
call.handler = zend_closure_call_magic;
371371
call.function_name = mptr->common.function_name;
372372
call.scope = mptr->common.scope;
373373
call.doc_comment = NULL;
374+
call.attributes = mptr->common.attributes;
374375

375376
zend_free_trampoline(mptr);
376377
mptr = (zend_function *) &call;
@@ -876,14 +877,15 @@ void zend_closure_from_frame(zval *return_value, zend_execute_data *call) { /* {
876877

877878
memset(&trampoline, 0, sizeof(zend_internal_function));
878879
trampoline.type = ZEND_INTERNAL_FUNCTION;
879-
trampoline.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC | ZEND_ACC_VARIADIC | ZEND_ACC_RETURN_REFERENCE);
880+
trampoline.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC | ZEND_ACC_VARIADIC | ZEND_ACC_RETURN_REFERENCE | ZEND_ACC_DEPRECATED);
880881
trampoline.handler = zend_closure_call_magic;
881882
trampoline.function_name = mptr->common.function_name;
882883
trampoline.scope = mptr->common.scope;
883884
trampoline.doc_comment = NULL;
884885
if (trampoline.fn_flags & ZEND_ACC_VARIADIC) {
885886
trampoline.arg_info = trampoline_arg_info;
886887
}
888+
trampoline.attributes = mptr->common.attributes;
887889

888890
zend_free_trampoline(mptr);
889891
mptr = (zend_function *) &trampoline;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
--TEST--
2+
GH-17913: ReflectionClassConstant::isDeprecated() with __call() and __callStatic()
3+
--FILE--
4+
<?php
5+
6+
class Clazz {
7+
#[\Deprecated]
8+
function __call(string $name, array $params) {
9+
}
10+
11+
#[\Deprecated("due to some reason")]
12+
static function __callStatic(string $name, array $params) {
13+
}
14+
}
15+
16+
$foo = new Clazz;
17+
$closure = Closure::fromCallable([$foo, 'test']);
18+
19+
$rc = new ReflectionFunction($closure);
20+
var_dump($rc->getAttributes()[0]->newInstance());
21+
var_dump($rc->isDeprecated());
22+
23+
$closure = $foo->test(...);
24+
25+
$rc = new ReflectionFunction($closure);
26+
var_dump($rc->getAttributes()[0]->newInstance());
27+
var_dump($rc->isDeprecated());
28+
29+
$closure = Closure::fromCallable('Clazz::test');
30+
31+
$rc = new ReflectionFunction($closure);
32+
var_dump($rc->getAttributes()[0]->newInstance());
33+
var_dump($rc->isDeprecated());
34+
35+
$closure = Clazz::test(...);
36+
37+
$rc = new ReflectionFunction($closure);
38+
var_dump($rc->getAttributes()[0]->newInstance());
39+
var_dump($rc->isDeprecated());
40+
41+
?>
42+
--EXPECTF--
43+
object(Deprecated)#%d (2) {
44+
["message"]=>
45+
NULL
46+
["since"]=>
47+
NULL
48+
}
49+
bool(true)
50+
object(Deprecated)#%d (2) {
51+
["message"]=>
52+
NULL
53+
["since"]=>
54+
NULL
55+
}
56+
bool(true)
57+
object(Deprecated)#%d (2) {
58+
["message"]=>
59+
string(18) "due to some reason"
60+
["since"]=>
61+
NULL
62+
}
63+
bool(true)
64+
object(Deprecated)#%d (2) {
65+
["message"]=>
66+
string(18) "due to some reason"
67+
["since"]=>
68+
NULL
69+
}
70+
bool(true)

0 commit comments

Comments
 (0)