Browse Source

Inheritance checks should not ignore parents if these implement an interface

pull/2357/head
Pedro Magalhães 10 years ago
committed by Joe Watkins
parent
commit
b67eb3440b
No known key found for this signature in database GPG Key ID: F9BA0ADA31CBD89E
  1. 2
      Zend/tests/bug62358.phpt
  2. 18
      Zend/tests/bug73987.phpt
  3. 18
      Zend/tests/bug73987_1.phpt
  4. 9
      Zend/zend_inheritance.c

2
Zend/tests/bug62358.phpt

@ -23,4 +23,4 @@ class B extends A {
} }
?> ?>
--EXPECTF-- --EXPECTF--
Fatal error: Declaration of B::foo($var) must be compatible with I::foo() in %sbug62358.php on line 17
Fatal error: Declaration of B::foo($var) must be compatible with A::foo() in %sbug62358.php on line 17

18
Zend/tests/bug73987.phpt

@ -0,0 +1,18 @@
--TEST--
Bug #73987 (Method compatibility check looks to original definition and not parent)
--FILE--
<?php
interface I {
public function example($a, $b, $c);
}
class A implements I {
public function example($a, $b = null, $c = null) { } // compatible with I::example
}
class B extends A {
public function example($a, $b, $c = null) { } // compatible with I::example
}
?>
--EXPECTF--
Fatal error: Declaration of B::example($a, $b, $c = NULL) must be compatible with A::example($a, $b = NULL, $c = NULL) in %s

18
Zend/tests/bug73987_1.phpt

@ -0,0 +1,18 @@
--TEST--
Bug #73987 (Method compatibility check looks to original definition and not parent)
--FILE--
<?php
interface I {
public function example();
}
class A implements I {
public function example(): int { } // compatible with I::example
}
class B extends A {
public function example(): string { } // compatible with I::example
}
?>
--EXPECTF--
Fatal error: Declaration of B::example(): string must be compatible with A::example(): int in %s

9
Zend/zend_inheritance.c

@ -607,13 +607,12 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function *
} else if (!(parent->common.fn_flags & ZEND_ACC_CTOR) || (parent->common.prototype && (parent->common.prototype->common.scope->ce_flags & ZEND_ACC_INTERFACE))) { } else if (!(parent->common.fn_flags & ZEND_ACC_CTOR) || (parent->common.prototype && (parent->common.prototype->common.scope->ce_flags & ZEND_ACC_INTERFACE))) {
/* ctors only have a prototype if it comes from an interface */ /* ctors only have a prototype if it comes from an interface */
child->common.prototype = parent->common.prototype ? parent->common.prototype : parent; child->common.prototype = parent->common.prototype ? parent->common.prototype : parent;
/* and if that is the case, we want to check inheritance against it */
if (parent->common.fn_flags & ZEND_ACC_CTOR) {
parent = child->common.prototype;
}
} }
if (child->common.prototype && (
child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT
)) {
parent = child->common.prototype;
}
if (UNEXPECTED(!zend_do_perform_implementation_check(child, parent))) { if (UNEXPECTED(!zend_do_perform_implementation_check(child, parent))) {
int error_level; int error_level;
const char *error_verb; const char *error_verb;

Loading…
Cancel
Save