]> granicus.if.org Git - php/commitdiff
Fixed bug #44414 (Incomplete reporting about abstract methods)
authorDmitry Stogov <dmitry@php.net>
Wed, 12 Mar 2008 09:46:57 +0000 (09:46 +0000)
committerDmitry Stogov <dmitry@php.net>
Wed, 12 Mar 2008 09:46:57 +0000 (09:46 +0000)
Zend/tests/bug44414.phpt [new file with mode: 0644]
Zend/zend_compile.c
Zend/zend_compile.h

diff --git a/Zend/tests/bug44414.phpt b/Zend/tests/bug44414.phpt
new file mode 100644 (file)
index 0000000..1f3a258
--- /dev/null
@@ -0,0 +1,15 @@
+--TEST--
+Bug #44414 (incomplete reporting about abstract methods)
+--FILE--
+<?php
+abstract class A {
+  abstract function foo();
+}
+interface B {
+  function bar();
+}
+class C extends A implements B {
+}
+?>
+--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
index e8ce63671fb267f872f6f0e548ed585ac4660f4d..70de9a705627358f3b7b28a77ea26d6a45cdcb2e 100644 (file)
@@ -2803,7 +2803,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);
        }
 }
@@ -2919,7 +2920,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;
@@ -3478,10 +3479,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;
 }
index beb91e69f3362ebb5d5602a0304b12b6aa532980..d322151247bb2bb4220948aaed6cde002c93caef 100644 (file)
@@ -147,6 +147,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);