Skip to content

Commit a29be3c

Browse files
committed
Add return types to internal methods
1 parent 16c2afb commit a29be3c

21 files changed

+284
-124
lines changed

Zend/tests/parameter_default_values/internal_declaration_error_class_const.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ The default value is a class constant in the parent class method's signature.
44
<?php
55
class MyDateTimeZone extends DateTimeZone
66
{
7-
public static function listIdentifiers()
7+
public static function listIdentifiers(): array
88
{
99
}
1010
}
1111
?>
1212
--EXPECTF--
13-
Fatal error: Declaration of MyDateTimeZone::listIdentifiers() must be compatible with DateTimeZone::listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null) in %s on line %d
13+
Fatal error: Declaration of MyDateTimeZone::listIdentifiers(): array must be compatible with DateTimeZone::listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array in %s on line %d

Zend/tests/parameter_default_values/internal_declaration_error_const.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ The default value is a constant in the parent class method's signature.
44
<?php
55
class MyDateTimeZone extends DateTimeZone
66
{
7-
public function getTransitions()
7+
public function getTransitions(): array|false
88
{
99
}
1010
}
1111
?>
1212
--EXPECTF--
13-
Fatal error: Declaration of MyDateTimeZone::getTransitions() must be compatible with DateTimeZone::getTransitions(int $timestampBegin = PHP_INT_MIN, int $timestampEnd = PHP_INT_MAX) in %s on line %d
13+
Fatal error: Declaration of MyDateTimeZone::getTransitions(): array|false must be compatible with DateTimeZone::getTransitions(int $timestampBegin = PHP_INT_MIN, int $timestampEnd = PHP_INT_MAX): array|false in %s on line %d

Zend/tests/parameter_default_values/internal_declaration_error_false.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ The default value is false in the parent class method's signature.
55

66
interface MyDateTimeInterface extends DateTimeInterface
77
{
8-
public function diff();
8+
public function diff(): DateInterval|false;
99
}
1010
?>
1111
--EXPECTF--
12-
Fatal error: Declaration of MyDateTimeInterface::diff() must be compatible with DateTimeInterface::diff(DateTimeInterface $targetObject, bool $absolute = false) in %s on line %d
12+
Fatal error: Declaration of MyDateTimeInterface::diff(): DateInterval|false must be compatible with DateTimeInterface::diff(DateTimeInterface $targetObject, bool $absolute = false): DateInterval|false in %s on line %d

Zend/tests/parameter_default_values/internal_declaration_error_int.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ The default value is an integer in the parent class method's signature.
44
<?php
55
class MyDateTime extends DateTime
66
{
7-
public function setTime(int $hour, int $minute, int $second = 0, bool $microsecond = false)
7+
public function setTime(int $hour, int $minute, int $second = 0, bool $microsecond = false): DateTime
88
{
99
}
1010
}
1111
?>
1212
--EXPECTF--
13-
Fatal error: Declaration of MyDateTime::setTime(int $hour, int $minute, int $second = 0, bool $microsecond = false) must be compatible with DateTime::setTime(int $hour, int $minute, int $second = 0, int $microsecond = 0) in %s on line %d
13+
Fatal error: Declaration of MyDateTime::setTime(int $hour, int $minute, int $second = 0, bool $microsecond = false): DateTime must be compatible with DateTime::setTime(int $hour, int $minute, int $second = 0, int $microsecond = 0): DateTime in %s on line %d

Zend/tests/parameter_default_values/internal_declaration_error_null.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ The default value is null in the parent class method's signature.
44
<?php
55
class MyDateTime extends DateTime
66
{
7-
public static function createFromFormat()
7+
public static function createFromFormat(): DateTime|false
88
{
99
}
1010
}
1111
?>
1212
--EXPECTF--
13-
Fatal error: Declaration of MyDateTime::createFromFormat() must be compatible with DateTime::createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null) in %s on line %d
13+
Fatal error: Declaration of MyDateTime::createFromFormat(): DateTime|false must be compatible with DateTime::createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTime|false in %s on line %d
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Test that no notice is emitted when the return type/value of the overriding method is compatible with the optional return type/value of the overridden method
3+
--FILE--
4+
<?php
5+
class MyDateTimeZone extends DateTimeZone
6+
{
7+
public static function listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array
8+
{
9+
return [];
10+
}
11+
}
12+
13+
var_dump(MyDateTimeZone::listIdentifiers());
14+
?>
15+
--EXPECT--
16+
array(0) {
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Test that a notice is emitted when the return type/value of the overriding method is incompatible with the optional return type/value of the overridden method
3+
--FILE--
4+
<?php
5+
class MyDateTimeZone extends DateTimeZone
6+
{
7+
public static function listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): string
8+
{
9+
return "";
10+
}
11+
}
12+
13+
var_dump(MyDateTimeZone::listIdentifiers());
14+
?>
15+
--EXPECTF--
16+
Strict Standards: Declaration of MyDateTimeZone::listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): string should be compatible with DateTimeZone::listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array in %s on line %d
17+
string(0) ""

Zend/tests/type_declarations/variance/internal_parent.phpt renamed to Zend/tests/type_declarations/variance/internal_parent/internal_parent.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ class Test extends DateTime {
99

1010
?>
1111
--EXPECTF--
12-
Fatal error: Could not check compatibility between Test::createFromFormat($format, $datetime, ?Wrong $timezone = null) and DateTime::createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null), because class Wrong is not available in %s on line %d
12+
Fatal error: Could not check compatibility between Test::createFromFormat($format, $datetime, ?Wrong $timezone = null) and DateTime::createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTime|false, because class Wrong is not available in %s on line %d
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Internal class as parent
3+
--FILE--
4+
<?php
5+
6+
class Test extends DateTime {
7+
public static function createFromFormat($format, $datetime, $timezone = null): Wrong { }
8+
}
9+
10+
?>
11+
--EXPECTF--
12+
Fatal error: Could not check compatibility between Test::createFromFormat($format, $datetime, $timezone = null): Wrong and DateTime::createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTime|false, because class Wrong is not available in %s on line %d
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Test that a notice is emitted when the optional return type of the overridden method is omitted
3+
--FILE--
4+
<?php
5+
class MyDateTimeZone extends DateTimeZone
6+
{
7+
public static function listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null)
8+
{
9+
}
10+
}
11+
?>
12+
--EXPECTF--
13+
Strict Standards: Declaration of MyDateTimeZone::listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null) should be compatible with DateTimeZone::listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array in %s on line %d

Zend/zend_API.h

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -107,66 +107,97 @@ typedef struct _zend_fcall_info_cache {
107107

108108
#define ZEND_FE_END { NULL, NULL, NULL, 0, 0 }
109109

110-
#define _ZEND_ARG_INFO_FLAGS(pass_by_ref, is_variadic) \
111-
(((pass_by_ref) << _ZEND_SEND_MODE_SHIFT) | ((is_variadic) ? _ZEND_IS_VARIADIC_BIT : 0))
110+
#define _ZEND_ARG_INFO_FLAGS(pass_by_ref, is_variadic, is_optional) \
111+
(((pass_by_ref) << _ZEND_SEND_MODE_SHIFT) | ((is_variadic) ? _ZEND_IS_VARIADIC_BIT : 0) | ((is_optional) ? _ZEND_IS_OPTIONAL_BIT : 0))
112112

113113
/* Arginfo structures without type information */
114114
#define ZEND_ARG_INFO(pass_by_ref, name) \
115-
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
115+
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), NULL },
116116
#define ZEND_ARG_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, default_value) \
117-
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
117+
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), default_value },
118118
#define ZEND_ARG_VARIADIC_INFO(pass_by_ref, name) \
119-
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)), NULL },
119+
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 1, 0)), NULL },
120120
/* Arginfo structures with simple type information */
121121
#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
122-
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
122+
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), NULL },
123123
#define ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, type_hint, allow_null, default_value) \
124-
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
124+
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), default_value },
125125
#define ZEND_ARG_VARIADIC_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
126-
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)), NULL },
126+
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1, 0)), NULL },
127127
/* Arginfo structures with complex type information */
128128
#define ZEND_ARG_TYPE_MASK(pass_by_ref, name, type_mask, default_value) \
129-
{ #name, ZEND_TYPE_INIT_MASK(type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
129+
{ #name, ZEND_TYPE_INIT_MASK(type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), default_value },
130130
#define ZEND_ARG_OBJ_TYPE_MASK(pass_by_ref, name, class_name, type_mask, default_value) \
131-
{ #name, ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
131+
{ #name, ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), default_value },
132132
/* Arginfo structures with object type information */
133133
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) \
134-
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
134+
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), NULL },
135135
#define ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, classname, allow_null, default_value) \
136-
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
136+
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), default_value },
137137
#define ZEND_ARG_VARIADIC_OBJ_INFO(pass_by_ref, name, classname, allow_null) \
138-
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)), NULL },
138+
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1, 0)), NULL },
139139
/* Legacy arginfo structures */
140140
#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) \
141-
{ #name, ZEND_TYPE_INIT_CODE(IS_ARRAY, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
141+
{ #name, ZEND_TYPE_INIT_CODE(IS_ARRAY, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), NULL },
142142
#define ZEND_ARG_CALLABLE_INFO(pass_by_ref, name, allow_null) \
143-
{ #name, ZEND_TYPE_INIT_CODE(IS_CALLABLE, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
143+
{ #name, ZEND_TYPE_INIT_CODE(IS_CALLABLE, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), NULL },
144144

145-
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
145+
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX2(name, return_reference, required_num_args, class_name, allow_null, is_optional_return_type) \
146146
static const zend_internal_arg_info name[] = { \
147147
{ (const char*)(zend_uintptr_t)(required_num_args), \
148-
ZEND_TYPE_INIT_CLASS_CONST(#class_name, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
148+
ZEND_TYPE_INIT_CLASS_CONST(#class_name, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0, is_optional_return_type)), NULL },
149+
150+
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
151+
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX2(name, return_reference, required_num_args, class_name, allow_null, 0)
152+
153+
#define ZEND_BEGIN_ARG_WITH_OPTIONAL_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
154+
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX2(name, return_reference, required_num_args, class_name, allow_null, 1)
149155

150156
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO(name, class_name, allow_null) \
151-
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, 0, -1, class_name, allow_null)
157+
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX2(name, 0, -1, class_name, allow_null, 0)
158+
159+
#define ZEND_BEGIN_ARG_WITH_OPTIONAL_RETURN_OBJ_INFO(name, class_name, allow_null) \
160+
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX2(name, 0, -1, class_name, allow_null, 1)
161+
162+
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX2(name, return_reference, required_num_args, type, is_optional_return_type) \
163+
static const zend_internal_arg_info name[] = { \
164+
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_MASK(type | _ZEND_ARG_INFO_FLAGS(return_reference, 0, is_optional_return_type)), NULL },
152165

153166
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(name, return_reference, required_num_args, type) \
167+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX2(name, return_reference, required_num_args, type, 0)
168+
169+
#define ZEND_BEGIN_ARG_WITH_OPTIONAL_RETURN_TYPE_MASK_EX(name, return_reference, required_num_args, type) \
170+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX2(name, return_reference, required_num_args, type, 1)
171+
172+
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX2(name, return_reference, required_num_args, class_name, type, is_optional_return_type) \
154173
static const zend_internal_arg_info name[] = { \
155-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_MASK(type | _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
174+
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type | _ZEND_ARG_INFO_FLAGS(return_reference, 0, is_optional_return_type)), NULL },
156175

157176
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(name, return_reference, required_num_args, class_name, type) \
177+
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX2(name, return_reference, required_num_args, class_name, type, 0)
178+
179+
#define ZEND_BEGIN_ARG_WITH_OPTIONAL_RETURN_OBJ_TYPE_MASK_EX(name, return_reference, required_num_args, class_name, type) \
180+
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX2(name, return_reference, required_num_args, class_name, type, 1)
181+
182+
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX2(name, return_reference, required_num_args, type, allow_null, is_optional_return_type) \
158183
static const zend_internal_arg_info name[] = { \
159-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type | _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
184+
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CODE(type, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0, is_optional_return_type)), NULL },
160185

161186
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \
162-
static const zend_internal_arg_info name[] = { \
163-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CODE(type, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
187+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX2(name, return_reference, required_num_args, type, allow_null, 0)
188+
189+
#define ZEND_BEGIN_ARG_WITH_OPTIONAL_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \
190+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX2(name, return_reference, required_num_args, type, allow_null, 1)
191+
164192
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(name, type, allow_null) \
165-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, 0, -1, type, allow_null)
193+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX2(name, 0, -1, type, allow_null, 0)
194+
195+
#define ZEND_BEGIN_ARG_WITH_OPTIONAL_RETURN_TYPE_INFO(name, type, allow_null) \
196+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX2(name, 0, -1, type, allow_null, 1)
166197

167198
#define ZEND_BEGIN_ARG_INFO_EX(name, _unused, return_reference, required_num_args) \
168199
static const zend_internal_arg_info name[] = { \
169-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
200+
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(return_reference, 0, 0)), NULL },
170201
#define ZEND_BEGIN_ARG_INFO(name, _unused) \
171202
ZEND_BEGIN_ARG_INFO_EX(name, {}, ZEND_RETURN_VALUE, -1)
172203
#define ZEND_END_ARG_INFO() };

Zend/zend_compile.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6462,7 +6462,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32_t fall
64626462
arg_infos->type = zend_compile_typename(
64636463
return_type_ast, /* force_allow_null */ 0);
64646464
ZEND_TYPE_FULL_MASK(arg_infos->type) |= _ZEND_ARG_INFO_FLAGS(
6465-
(op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0, /* is_variadic */ 0);
6465+
(op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0, /* is_variadic */ 0, 0);
64666466
} else {
64676467
arg_infos->type = (zend_type) ZEND_TYPE_INIT_CODE(fallback_return_type, 0, 0);
64686468
}
@@ -6588,7 +6588,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32_t fall
65886588
zend_alloc_cache_slots(zend_type_get_num_classes(arg_info->type));
65896589
}
65906590

6591-
uint32_t arg_info_flags = _ZEND_ARG_INFO_FLAGS(is_ref, is_variadic)
6591+
uint32_t arg_info_flags = _ZEND_ARG_INFO_FLAGS(is_ref, is_variadic, 0)
65926592
| (visibility ? _ZEND_IS_PROMOTED_BIT : 0);
65936593
ZEND_TYPE_FULL_MASK(arg_info->type) |= arg_info_flags;
65946594
if (opcode == ZEND_RECV) {

Zend/zend_compile.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -975,16 +975,19 @@ ZEND_API zend_string *zend_type_to_string(zend_type type);
975975

976976
#define ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS 1
977977

978-
/* The send mode and is_variadic flag are stored as part of zend_type */
978+
/* The send mode, the is_variadic, and the is_optional flags are stored as part of zend_type */
979979
#define _ZEND_SEND_MODE_SHIFT _ZEND_TYPE_EXTRA_FLAGS_SHIFT
980980
#define _ZEND_IS_VARIADIC_BIT (1 << (_ZEND_TYPE_EXTRA_FLAGS_SHIFT + 2))
981981
#define _ZEND_IS_PROMOTED_BIT (1 << (_ZEND_TYPE_EXTRA_FLAGS_SHIFT + 3))
982+
#define _ZEND_IS_OPTIONAL_BIT (1 << (_ZEND_TYPE_EXTRA_FLAGS_SHIFT + 4))
982983
#define ZEND_ARG_SEND_MODE(arg_info) \
983984
((ZEND_TYPE_FULL_MASK((arg_info)->type) >> _ZEND_SEND_MODE_SHIFT) & 3)
984985
#define ZEND_ARG_IS_VARIADIC(arg_info) \
985986
((ZEND_TYPE_FULL_MASK((arg_info)->type) & _ZEND_IS_VARIADIC_BIT) != 0)
986987
#define ZEND_ARG_IS_PROMOTED(arg_info) \
987988
((ZEND_TYPE_FULL_MASK((arg_info)->type) & _ZEND_IS_PROMOTED_BIT) != 0)
989+
#define ZEND_ARG_TYPE_IS_OPTIONAL(arg_info) \
990+
((ZEND_TYPE_FULL_MASK((arg_info)->type) & _ZEND_IS_OPTIONAL_BIT) != 0)
988991

989992
#define ZEND_DIM_IS (1 << 0) /* isset fetch needed for null coalesce */
990993
#define ZEND_DIM_ALTERNATIVE_SYNTAX (1 << 1) /* deprecated curly brace usage */

0 commit comments

Comments
 (0)