From b991ce9c1e19b912b4ca5a9b2ebc20bd5448ecd5 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sun, 5 Dec 2021 20:26:37 +0100 Subject: [PATCH] Improve final/abstract methods in interfaces error messages Closes #81683 Closes GH-7722 --- NEWS | 2 ++ Zend/tests/bug71871.phpt | 2 +- Zend/tests/bug71871_2.phpt | 2 +- Zend/zend_compile.c | 10 +++++++++- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index f1b6abbc3d9d5..472250212c8fc 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ PHP NEWS . Fixed bug #81684 (Using null coalesce assignment with $GLOBALS["x"] produces opcode error). (ilutov) . Fixed bug #81656 (GCC-11 silently ignores -R). (Michael Wallner) + . Fixed bug #81683 (Misleading "access type ... must be public" error message + on final or abstract interface methods). (ilutov) - MBString: . Fixed bug #81693 (mb_check_encoding(7bit) segfaults). (cmb) diff --git a/Zend/tests/bug71871.phpt b/Zend/tests/bug71871.phpt index 981e7519c7652..9d93f5dd9a6f1 100644 --- a/Zend/tests/bug71871.phpt +++ b/Zend/tests/bug71871.phpt @@ -9,4 +9,4 @@ interface test { ?> --EXPECTF-- -Fatal error: Access type for interface method test::test() must be public in %s on line %d +Fatal error: Interface method test::test() must not be final in %s on line %d diff --git a/Zend/tests/bug71871_2.phpt b/Zend/tests/bug71871_2.phpt index 2781a8d495503..d1ed08f0b6cfb 100644 --- a/Zend/tests/bug71871_2.phpt +++ b/Zend/tests/bug71871_2.phpt @@ -9,4 +9,4 @@ interface test { ?> --EXPECTF-- -Fatal error: Access type for interface method test::test() must be public in %s on line %d +Fatal error: Interface method test::test() must not be abstract in %s on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index c136d226e3c2d..0b025939ec457 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7039,10 +7039,18 @@ static zend_string *zend_begin_method_decl(zend_op_array *op_array, zend_string } if (in_interface) { - if (!(fn_flags & ZEND_ACC_PUBLIC) || (fn_flags & (ZEND_ACC_FINAL|ZEND_ACC_ABSTRACT))) { + if (!(fn_flags & ZEND_ACC_PUBLIC)) { zend_error_noreturn(E_COMPILE_ERROR, "Access type for interface method " "%s::%s() must be public", ZSTR_VAL(ce->name), ZSTR_VAL(name)); } + if (fn_flags & ZEND_ACC_FINAL) { + zend_error_noreturn(E_COMPILE_ERROR, "Interface method " + "%s::%s() must not be final", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + } + if (fn_flags & ZEND_ACC_ABSTRACT) { + zend_error_noreturn(E_COMPILE_ERROR, "Interface method " + "%s::%s() must not be abstract", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + } op_array->fn_flags |= ZEND_ACC_ABSTRACT; }