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/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) 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));