Skip to content

Commit bb8b95b

Browse files
committed
Fix bug #79925
If the expected return type of a magic method is "object", we also need to allow class types and "static" to comply with covariance.
1 parent 5d4659c commit bb8b95b

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

Zend/tests/magic_methods_021.phpt

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
__set_state return type should support covariance
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
public static function __set_state(array $data): self {}
8+
}
9+
10+
class Foo2 {
11+
public static function __set_state(array $data): static {}
12+
}
13+
14+
class Foo3 {
15+
public static function __set_state(array $data): Foo3|self {}
16+
}
17+
18+
?>
19+
===DONE===
20+
--EXPECT--
21+
===DONE===

Zend/zend_API.c

+13-4
Original file line numberDiff line numberDiff line change
@@ -2063,10 +2063,19 @@ static void zend_check_magic_method_arg_type(uint32_t arg_num, const zend_class_
20632063

20642064
static void zend_check_magic_method_return_type(const zend_class_entry *ce, const zend_function *fptr, int error_type, int return_type)
20652065
{
2066-
if (
2067-
(fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)
2068-
&& (ZEND_TYPE_FULL_MASK(fptr->common.arg_info[-1].type) & ~return_type)
2069-
) {
2066+
if (!(fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) {
2067+
/* For backwards compatibility reasons, do not enforce the return type if it is not set. */
2068+
return;
2069+
}
2070+
2071+
bool has_class_type = ZEND_TYPE_HAS_CLASS(fptr->common.arg_info[-1].type);
2072+
uint32_t extra_types = ZEND_TYPE_PURE_MASK(fptr->common.arg_info[-1].type) & ~return_type;
2073+
if (extra_types & MAY_BE_STATIC) {
2074+
extra_types &= ~MAY_BE_STATIC;
2075+
has_class_type = 1;
2076+
}
2077+
2078+
if (extra_types || (has_class_type && return_type != MAY_BE_OBJECT)) {
20702079
zend_error(error_type, "%s::%s(): Return type must be %s when declared",
20712080
ZSTR_VAL(ce->name), ZSTR_VAL(fptr->common.function_name),
20722081
ZSTR_VAL(zend_type_to_string((zend_type) ZEND_TYPE_INIT_MASK(return_type))));

0 commit comments

Comments
 (0)