summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_compile.c3
-rw-r--r--Zend/zend_compile.h1
-rw-r--r--Zend/zend_language_parser.y1
3 files changed, 5 insertions, 0 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 3f2b804800..a876e941ac 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -1834,6 +1834,9 @@ void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce)
&& !(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) {
zend_error(E_ERROR, "Interface %s may not inherit from class (%s)", ce->name, parent_ce->name);
}
+ if (parent_ce->ce_flags & ZEND_ACC_FINAL_CLASS) {
+ zend_error(E_ERROR, "Class %s may not inherit from final class (%s)", ce->name, parent_ce->name);
+ }
ce->parent = parent_ce;
/* Inherit interfaces */
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 1a4ec937be..5f8f489030 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -99,6 +99,7 @@ typedef struct _zend_brk_cont_element {
#define ZEND_ACC_FINAL 0x04
#define ZEND_ACC_INTERFACE 0x08
#define ZEND_ACC_ABSTRACT_CLASS 0x10
+#define ZEND_ACC_FINAL_CLASS 0x20
/* The order of those must be kept - public < protected < private */
#define ZEND_ACC_PUBLIC 0x100
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index 0cd1e07033..c2beb4a264 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -277,6 +277,7 @@ unticked_class_declaration_statement:
class_entry_type:
T_CLASS { $$.u.constant.value.lval = 0; }
| T_ABSTRACT T_CLASS { $$.u.constant.value.lval = ZEND_ACC_ABSTRACT_CLASS; }
+ | T_FINAL T_CLASS { $$.u.constant.value.lval = ZEND_ACC_FINAL_CLASS; }
| T_INTERFACE { $$.u.constant.value.lval = ZEND_ACC_INTERFACE; }
;