Fix iface const visibility variance check

This commit is contained in:
Ilija Tovilo 2023-07-12 14:02:08 +02:00
parent 7343ae5d3c
commit d9db446065
No known key found for this signature in database
GPG Key ID: A4F5D403F118200A
3 changed files with 25 additions and 10 deletions

View File

@ -43,6 +43,8 @@ PHP 8.3 UPGRADE NOTES
next index is n+1 instead of 0.
. Static variable initializers can now contain arbitrary expressions.
RFC: https://wiki.php.net/rfc/arbitrary_static_variable_initializers
. Class constant visibility variance is now correctly checked when inherited
from interfaces.
- FFI:
. C functions that have a return type of void now return null instead of

View File

@ -0,0 +1,14 @@
--TEST--
Interface constant visibility should be invariant
--FILE--
<?php
interface I {
public const FOO = 'foo';
}
class C implements I {
private const FOO = 'foo';
}
?>
--EXPECTF--
Fatal error: Access level to C::FOO must be public (as in interface I) in %s on line %d

View File

@ -1404,16 +1404,6 @@ static void do_inherit_class_constant(zend_string *name, zend_class_constant *pa
if (zv != NULL) {
c = (zend_class_constant*)Z_PTR_P(zv);
if (UNEXPECTED((ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_PPP_MASK) > (ZEND_CLASS_CONST_FLAGS(parent_const) & ZEND_ACC_PPP_MASK))) {
zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::%s must be %s (as in class %s)%s",
ZSTR_VAL(ce->name), ZSTR_VAL(name),
zend_visibility_string(ZEND_CLASS_CONST_FLAGS(parent_const)),
ZSTR_VAL(parent_const->ce->name),
(ZEND_CLASS_CONST_FLAGS(parent_const) & ZEND_ACC_PUBLIC) ? "" : " or weaker"
);
}
bool inherit = do_inherit_constant_check(ce, parent_const, name);
ZEND_ASSERT(!inherit);
} else if (!(ZEND_CLASS_CONST_FLAGS(parent_const) & ZEND_ACC_PRIVATE)) {
@ -1734,6 +1724,15 @@ static bool do_inherit_constant_check(
ZSTR_VAL(parent_constant->ce->name), ZSTR_VAL(name));
}
if (UNEXPECTED((ZEND_CLASS_CONST_FLAGS(child_constant) & ZEND_ACC_PPP_MASK) > (ZEND_CLASS_CONST_FLAGS(parent_constant) & ZEND_ACC_PPP_MASK))) {
zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::%s must be %s (as in %s %s)%s",
ZSTR_VAL(ce->name), ZSTR_VAL(name),
zend_visibility_string(ZEND_CLASS_CONST_FLAGS(parent_constant)),
zend_get_object_type(parent_constant->ce),
ZSTR_VAL(parent_constant->ce->name),
(ZEND_CLASS_CONST_FLAGS(parent_constant) & ZEND_ACC_PUBLIC) ? "" : " or weaker"
);
}
if (!(ZEND_CLASS_CONST_FLAGS(parent_constant) & ZEND_ACC_PRIVATE) && UNEXPECTED(ZEND_TYPE_IS_SET(parent_constant->type))) {
inheritance_status status = class_constant_types_compatible(parent_constant, child_constant);