From: Dmitry Stogov Date: Wed, 12 Mar 2008 09:46:42 +0000 (+0000) Subject: Fixed bug #44414 (Incomplete reporting about abstract methods) X-Git-Tag: BEFORE_NEW_PARAMETER_PARSE~611 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0f2247ae9423d9ba38428b2dea9c46614d29265c;p=php Fixed bug #44414 (Incomplete reporting about abstract methods) --- diff --git a/NEWS b/NEWS index 579e4259e7..8dba72fb30 100644 --- a/NEWS +++ b/NEWS @@ -126,6 +126,7 @@ PHP NEWS - Fixed possible crash in ext/soap because of uninitialized value. (Zdash Urf) - Fixed PECL bug #12431 (OCI8 ping functionality is broken). (Oracle Corp.) +- Fixed bug #44414 (Incomplete reporting about abstract methods). (Dmitry) - Fixed bug #44394 (Last two bytes missing from output). (Felipe) - Fixed bug #44336 (Improve pcre UTF-8 string matching performance). (frode at coretrek dot com, Nuno) diff --git a/Zend/tests/bug44414.phpt b/Zend/tests/bug44414.phpt new file mode 100644 index 0000000000..1f3a2583d7 --- /dev/null +++ b/Zend/tests/bug44414.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #44414 (incomplete reporting about abstract methods) +--FILE-- + +--EXPECTF-- +Fatal error: Class C contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (A::foo, B::bar) in %sbug44414.php on line 9 diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 093a441f87..96af432ac6 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2588,7 +2588,8 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent if (ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS && ce->type == ZEND_INTERNAL_CLASS) { ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; - } else { + } else if (!(ce->ce_flags & ZEND_ACC_IMPLEMENT_INTERFACES)) { + /* The verification will be done in runtime by ZEND_VERIFY_ABSTRACT_CLASS */ zend_verify_abstract_class(ce TSRMLS_CC); } } @@ -2700,7 +2701,7 @@ ZEND_API zend_class_entry *do_bind_class(zend_op *opline, HashTable *class_table } return NULL; } else { - if (!(ce->ce_flags & ZEND_ACC_INTERFACE)) { + if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLEMENT_INTERFACES))) { zend_verify_abstract_class(ce TSRMLS_CC); } return ce; @@ -3246,10 +3247,13 @@ void zend_do_end_class_declaration(znode *class_token, znode *parent_token TSRML } } /* Inherit interfaces; reset number to zero, we need it for above check and - * will restore it during actual implementation. */ + * will restore it during actual implementation. + * The ZEND_ACC_IMPLEMENT_INTERFACES flag disables double call to + * zend_verify_abstract_class() */ if (ce->num_interfaces > 0) { ce->interfaces = NULL; ce->num_interfaces = 0; + ce->ce_flags |= ZEND_ACC_IMPLEMENT_INTERFACES; } CG(active_class_entry) = NULL; } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index fb87f5d8d2..80fb6d4c38 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -143,6 +143,10 @@ typedef struct _zend_try_catch_element { /* deprecation flag */ #define ZEND_ACC_DEPRECATED 0x40000 +/* class implement interface(s) flag */ +#define ZEND_ACC_IMPLEMENT_INTERFACES 0x80000 + + char *zend_visibility_string(zend_uint fn_flags);