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
No known key found for this signature in database
GPG Key ID: F9BA0ADA31CBD89E
4 changed files with
41 additions and
6 deletions
-
Zend/tests/bug62358.phpt
-
Zend/tests/bug73987.phpt
-
Zend/tests/bug73987_1.phpt
-
Zend/zend_inheritance.c
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -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; |
|
|
|