From 39bbc16641b2690729354d8062fd4b5f9250cbb7 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 6 Jan 2025 15:18:00 +0100 Subject: [PATCH] Relax final+private warning for trait methods with inherited final Fixes GH-17214 --- Zend/tests/gh17214.phpt | 26 ++++++++++++++++++++++++++ Zend/tests/traits/gh12854.phpt | 2 -- Zend/zend_inheritance.c | 8 +++++--- 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 Zend/tests/gh17214.phpt diff --git a/Zend/tests/gh17214.phpt b/Zend/tests/gh17214.phpt new file mode 100644 index 0000000000000..ec63c0e9855ea --- /dev/null +++ b/Zend/tests/gh17214.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-17214: Relax final+private warning for trait methods with inherited final +--FILE-- +anotherMethod(); + } +} + +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/traits/gh12854.phpt b/Zend/tests/traits/gh12854.phpt index 471b4c6b56558..627f78ccae29f 100644 --- a/Zend/tests/traits/gh12854.phpt +++ b/Zend/tests/traits/gh12854.phpt @@ -39,8 +39,6 @@ foreach (['pub', 'prot', 'priv', 'final1', 'final2', 'final3'] as $method) { ?> --EXPECTF-- -Warning: Private methods cannot be final as they are never overridden by other classes in %s on line %d - Warning: Private methods cannot be final as they are never overridden by other classes in %s on line %d --- Method: pub --- bool(true) diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 6ff886adcfc44..5ba883addca55 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -2048,9 +2048,11 @@ static void zend_fixup_trait_method(zend_function *fn, zend_class_entry *ce) /* static void zend_traits_check_private_final_inheritance(uint32_t original_fn_flags, zend_function *fn_copy, zend_string *name) { - /* If the function was originally already private+final, then it will have already been warned about. - * If the function became private+final only after applying modifiers, we need to emit the same warning. */ - if ((original_fn_flags & (ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)) != (ZEND_ACC_PRIVATE | ZEND_ACC_FINAL) + /* If the function was originally already private+final, then it will have + * already been warned about. Only emit this error when the used trait method + * explicitly became final, avoiding errors for `as private` where it was + * already final. */ + if (!(original_fn_flags & ZEND_ACC_FINAL) && (fn_copy->common.fn_flags & (ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)) == (ZEND_ACC_PRIVATE | ZEND_ACC_FINAL) && !zend_string_equals_literal_ci(name, ZEND_CONSTRUCTOR_FUNC_NAME)) { zend_error(E_COMPILE_WARNING, "Private methods cannot be final as they are never overridden by other classes");