&& ((current_access_type->u.constant.value.lval & ZEND_ACC_PPP_MASK) != (new_modifier->u.constant.value.lval & ZEND_ACC_PPP_MASK))) {
zend_error(E_COMPILE_ERROR, "Multiple access type modifiers are not allowed");
}
+ if ((current_access_type->u.constant.value.lval | new_modifier->u.constant.value.lval) && (ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)) {
+ zend_error(E_COMPILE_ERROR, "Cannot use the final modifier on a private class member");
+ }
return (current_access_type->u.constant.value.lval | new_modifier->u.constant.value.lval);
}
}
return 1; /* method doesn't exist in child, copy from parent */
}
+
+ if (parent_flags & ZEND_ACC_FINAL) {
+ zend_error(E_COMPILE_ERROR, "Cannot override final method %s::%s()", ZEND_FN_SCOPE_NAME(parent), child->common.function_name);
+ }
+
child_flags = child->common.fn_flags;
/* You cannot change from static to non static and vice versa.
*/
}
if (zend_hash_quick_find(&ce->properties_info, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void **) &child_info)==SUCCESS) {
+ if (parent_info->flags & ZEND_ACC_FINAL) {
+ zend_error(E_COMPILE_ERROR, "Cannot override final property %s::$%s", parent_ce->name, hash_key->arKey);
+ }
if ((child_info->flags & ZEND_ACC_PPP_MASK) > (parent_info->flags & ZEND_ACC_PPP_MASK)) {
zend_error(E_COMPILE_ERROR, "Access level to %s::$%s must be %s (as in class %s)%s", ce->name, hash_key->arKey, zend_visibility_string(parent_info->flags), parent_ce->name, (parent_info->flags&ZEND_ACC_PUBLIC) ? "" : " or weaker");
} else if (child_info->flags & ZEND_ACC_IMPLICIT_PUBLIC) {
#define ZEND_ACC_STATIC 0x01
#define ZEND_ACC_ABSTRACT 0x02
+#define ZEND_ACC_FINAL 0x04
/* The order of those must be kept - public < protected < private */
#define ZEND_ACC_PUBLIC 0x10
%token T_THROW
%token T_USE
%token T_GLOBAL
-%right T_STATIC T_ABSTRACT T_PRIVATE T_PROTECTED T_PUBLIC
+%right T_STATIC T_ABSTRACT T_FINAL T_PRIVATE T_PROTECTED T_PUBLIC
%token T_VAR
%token T_UNSET
%token T_ISSET
| T_PRIVATE { $$.u.constant.value.lval = ZEND_ACC_PRIVATE; }
| T_STATIC { $$.u.constant.value.lval = ZEND_ACC_STATIC; }
| T_ABSTRACT { $$.u.constant.value.lval = ZEND_ACC_ABSTRACT; }
+ | T_FINAL { $$.u.constant.value.lval = ZEND_ACC_FINAL; }
;
class_variable_declaration: