--- /dev/null
+--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
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);
}
}
}
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;
}
}
/* 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;
}
/* 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);