From 274e168d0073ebbc57987a56bb971197fe00498c Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Thu, 17 Oct 2024 20:09:26 -0700 Subject: [PATCH 1/2] GH-16315: improve error messages for extending enums --- Zend/tests/enum/extending-builtin-error.phpt | 10 ++++++++++ Zend/tests/enum/extending-user-error.phpt | 12 ++++++++++++ Zend/zend_inheritance.c | 7 ++++++- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/enum/extending-builtin-error.phpt create mode 100644 Zend/tests/enum/extending-user-error.phpt diff --git a/Zend/tests/enum/extending-builtin-error.phpt b/Zend/tests/enum/extending-builtin-error.phpt new file mode 100644 index 0000000000000..89931945977da --- /dev/null +++ b/Zend/tests/enum/extending-builtin-error.phpt @@ -0,0 +1,10 @@ +--TEST-- +Error message when extending enums (GH-16315) (extending built in enum) +--FILE-- + +--EXPECTF-- +Fatal error: Class Demo cannot extend enum RoundingMode in %s on line 3 diff --git a/Zend/tests/enum/extending-user-error.phpt b/Zend/tests/enum/extending-user-error.phpt new file mode 100644 index 0000000000000..6c6c902e482af --- /dev/null +++ b/Zend/tests/enum/extending-user-error.phpt @@ -0,0 +1,12 @@ +--TEST-- +Error message when extending enums (GH-16315) (extending userland enum) +--FILE-- + +--EXPECTF-- +Fatal error: Class Demo cannot extend enum MyEnum in %s on line 5 diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 88f1d3447c2a7..96f820b228cbe 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -1757,7 +1757,12 @@ ZEND_API void zend_do_inheritance_ex(zend_class_entry *ce, zend_class_entry *par if (UNEXPECTED(!(parent_ce->ce_flags & ZEND_ACC_INTERFACE))) { zend_error_noreturn(E_COMPILE_ERROR, "Interface %s cannot extend class %s", ZSTR_VAL(ce->name), ZSTR_VAL(parent_ce->name)); } - } else if (UNEXPECTED(parent_ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_FINAL))) { + } else if (UNEXPECTED(parent_ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_FINAL|ZEND_ACC_ENUM))) { + /* Class must not extend an enum (GH-16315); check enums first since + enums are implemented as final classes */ + if (parent_ce->ce_flags & ZEND_ACC_ENUM) { + zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend enum %s", ZSTR_VAL(ce->name), ZSTR_VAL(parent_ce->name)); + } /* Class must not extend a final class */ if (parent_ce->ce_flags & ZEND_ACC_FINAL) { zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend final class %s", ZSTR_VAL(ce->name), ZSTR_VAL(parent_ce->name)); From 101c741626a0681d12f70b591615a365d4326516 Mon Sep 17 00:00:00 2001 From: DanielEScherzer Date: Thu, 17 Oct 2024 21:18:29 -0700 Subject: [PATCH 2/2] Update Zend/tests/enum/final.phpt Since the error message changed, verify finality with Reflection --- Zend/tests/enum/final.phpt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Zend/tests/enum/final.phpt b/Zend/tests/enum/final.phpt index 353e1868d2fa8..f0ce8fed19f0b 100644 --- a/Zend/tests/enum/final.phpt +++ b/Zend/tests/enum/final.phpt @@ -5,8 +5,8 @@ Enum is final enum Foo {} -class Bar extends Foo {} - +$final = new ReflectionClass(Foo::class)->isFinal(); +var_dump( $final ); ?> ---EXPECTF-- -Fatal error: Class Bar cannot extend final class Foo in %s on line %d +--EXPECT-- +bool(true)