Skip to content

Commit 3397f29

Browse files
committed
Merge remote-tracking branch 'origin/master' into opcache/file_cache_read_only
2 parents 86e5178 + bfca4c7 commit 3397f29

32 files changed

+348
-81
lines changed

UPGRADING

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ PHP 8.5 UPGRADE NOTES
100100
9. Other Changes to Extensions
101101
========================================
102102

103+
- Readline:
104+
. The return types of readline_add_history(), readline_clear_history(), and
105+
readline_callback_handler_install() have been changed to true, rather
106+
than bool.
107+
103108
========================================
104109
10. New Global Constants
105110
========================================

Zend/tests/abstract_implicit.phpt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
Abstract methods not allowed in classes that are not abstract (GH-16067)
3+
--FILE--
4+
<?php
5+
6+
// Still allowed via trait
7+
trait TraitWithAbstract {
8+
abstract public function foo();
9+
}
10+
class TraitWorks {
11+
use TraitWithAbstract;
12+
}
13+
14+
class NotAbstract {
15+
abstract public function bar();
16+
}
17+
?>
18+
--EXPECTF--
19+
Fatal error: Class NotAbstract declares abstract method bar() and must therefore be declared abstract in %s on line %d

Zend/tests/anon/gh16067.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Compiler prevents explicit `abstract` methods on anonymous classes
3+
--FILE--
4+
<?php
5+
6+
$c = new class {
7+
abstract public function f();
8+
}
9+
?>
10+
--EXPECTF--
11+
Fatal error: Anonymous class method f() must not be abstract in %s on line 4

Zend/tests/enum/no-abstract.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Compiler prevents `abstract` methods on enums classes (GH-16067)
3+
--FILE--
4+
<?php
5+
6+
enum Example {
7+
abstract public function foo();
8+
}
9+
10+
?>
11+
--EXPECTF--
12+
Fatal error: Enum method Example::foo() must not be abstract in %s on line 4

Zend/tests/errmsg/errmsg_018.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ class test {
1010
echo "Done\n";
1111
?>
1212
--EXPECTF--
13-
Fatal error: Class test contains 1 abstract method and must therefore be declared abstract or implement the remaining method (test::foo) in %s on line %d
13+
Fatal error: Class test declares abstract method foo() and must therefore be declared abstract in %s on line %d

Zend/zend_compile.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3709,6 +3709,7 @@ static uint32_t zend_get_arg_num(zend_function *fn, zend_string *arg_name) {
37093709
}
37103710
}
37113711
} else {
3712+
ZEND_ASSERT(fn->common.num_args == 0 || fn->internal_function.arg_info);
37123713
for (uint32_t i = 0; i < fn->common.num_args; i++) {
37133714
zend_internal_arg_info *arg_info = &fn->internal_function.arg_info[i];
37143715
size_t len = strlen(arg_info->name);
@@ -8067,6 +8068,22 @@ static zend_string *zend_begin_method_decl(zend_op_array *op_array, zend_string
80678068
zend_error(E_COMPILE_WARNING, "Private methods cannot be final as they are never overridden by other classes");
80688069
}
80698070

8071+
if ((fn_flags & ZEND_ACC_ABSTRACT)
8072+
&& !(ce->ce_flags & (ZEND_ACC_EXPLICIT_ABSTRACT_CLASS|ZEND_ACC_TRAIT))) {
8073+
// Don't say that the class should be declared abstract if it is
8074+
// anonymous or an enum and can't be abstract
8075+
if (ce->ce_flags & ZEND_ACC_ANON_CLASS) {
8076+
zend_error_noreturn(E_COMPILE_ERROR, "Anonymous class method %s() must not be abstract",
8077+
ZSTR_VAL(name));
8078+
} else if (ce->ce_flags & (ZEND_ACC_ENUM|ZEND_ACC_INTERFACE)) {
8079+
zend_error_noreturn(E_COMPILE_ERROR, "%s method %s::%s() must not be abstract",
8080+
zend_get_object_type_case(ce, true), ZSTR_VAL(ce->name), ZSTR_VAL(name));
8081+
} else {
8082+
zend_error_noreturn(E_COMPILE_ERROR, "Class %s declares abstract method %s() and must therefore be declared abstract",
8083+
ZSTR_VAL(ce->name), ZSTR_VAL(name));
8084+
}
8085+
}
8086+
80708087
if (in_interface) {
80718088
if (!(fn_flags & ZEND_ACC_PUBLIC)) {
80728089
zend_error_noreturn(E_COMPILE_ERROR, "Access type for interface method "
@@ -8076,10 +8093,6 @@ static zend_string *zend_begin_method_decl(zend_op_array *op_array, zend_string
80768093
zend_error_noreturn(E_COMPILE_ERROR, "Interface method "
80778094
"%s::%s() must not be final", ZSTR_VAL(ce->name), ZSTR_VAL(name));
80788095
}
8079-
if (fn_flags & ZEND_ACC_ABSTRACT) {
8080-
zend_error_noreturn(E_COMPILE_ERROR, "Interface method "
8081-
"%s::%s() must not be abstract", ZSTR_VAL(ce->name), ZSTR_VAL(name));
8082-
}
80838096
op_array->fn_flags |= ZEND_ACC_ABSTRACT;
80848097
}
80858098

Zend/zend_execute.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5304,6 +5304,7 @@ static zend_always_inline uint32_t zend_get_arg_offset_by_name(
53045304
}
53055305
}
53065306
} else {
5307+
ZEND_ASSERT(num_args == 0 || fbc->internal_function.arg_info);
53075308
for (uint32_t i = 0; i < num_args; i++) {
53085309
zend_internal_arg_info *arg_info = &fbc->internal_function.arg_info[i];
53095310
size_t len = strlen(arg_info->name);

Zend/zend_max_execution_timer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121

2222
#include "zend_long.h"
2323

24+
BEGIN_EXTERN_C()
2425
/* Must be called after calls to fork() */
2526
ZEND_API void zend_max_execution_timer_init(void);
27+
END_EXTERN_C()
2628
void zend_max_execution_timer_settime(zend_long seconds);
2729
void zend_max_execution_timer_shutdown(void);
2830

Zend/zend_vm_def.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3634,7 +3634,7 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV,
36343634
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
36353635
if (UNEXPECTED(fbc == NULL)) {
36363636
if (EXPECTED(!EG(exception))) {
3637-
zend_undefined_method(obj->ce, Z_STR_P(function_name));
3637+
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
36383638
}
36393639
FREE_OP2();
36403640
if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {

Zend/zend_vm_execute.h

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)