From 2adaa11f2fcab72bf8dc4b5d875ce084e9080caa Mon Sep 17 00:00:00 2001 From: Zeev Suraski Date: Wed, 28 Jan 2004 10:25:45 +0000 Subject: [PATCH] Prevent classes from implementing interfaces that have the same function --- Zend/zend_compile.c | 28 +++++++++++++++++++++++++++- Zend/zend_compile.h | 1 + 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 35ad5e7e5d2..aae2eb4a75e 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1733,6 +1733,14 @@ static zend_bool do_inherit_method_check(HashTable *child_function_table, zend_f return 1; /* method doesn't exist in child, copy from parent */ } + if (parent->common.fn_flags & ZEND_ACC_ABSTRACT + && child->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_IMPLEMENTED_ABSTRACT)) { + zend_error(E_COMPILE_ERROR, "Can't inherit abstract function %s::%s() (previously declared abstract in %s)", + parent->common.scope->name, + child->common.function_name, + child->common.prototype->common.scope->name); + } + 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); } @@ -1766,8 +1774,9 @@ static zend_bool do_inherit_method_check(HashTable *child_function_table, zend_f } } - if (parent_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_ABSTRACT)) { + if (parent_flags & ZEND_ACC_ABSTRACT) { child->common.prototype = parent; + child->common.fn_flags |= ZEND_ACC_IMPLEMENTED_ABSTRACT; } else if (parent->common.prototype) { child->common.prototype = parent->common.prototype; } @@ -2427,6 +2436,23 @@ void zend_do_end_class_declaration(znode *class_token, znode *parent_token TSRML } +#if 0 +/* This is a part of an incomplete patch, coming soon */ +ZEND_API void zend_do_extends(znode *result, znode *class_token, zend_bool is_first_parent TSRMLS_DC) +{ + zend_bool is_class = CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE; + + if (is_class) { + if (!is_first_parent) { + zend_error(E_COMPILE_ERROR, "Classes may extend only one parent"); + } else { + *result = *class_token; + } + } else { /* interface */ + } +} +#endif + void zend_do_implements_interface(znode *interface_znode TSRMLS_DC) { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 8c2026dfe84..e90654b0981 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -100,6 +100,7 @@ typedef struct _zend_brk_cont_element { #define ZEND_ACC_INTERFACE 0x08 #define ZEND_ACC_ABSTRACT_CLASS 0x10 #define ZEND_ACC_FINAL_CLASS 0x20 +#define ZEND_ACC_IMPLEMENTED_ABSTRACT 0x40 #define ZEND_ACC_ALLOW_STATIC 0x80