Skip to content

Commit 0585548

Browse files
committed
Treat abstract ctors the same, regardless of origin
Abstract ctor signatures should always be respected by all children, independently of whether it comes from an interface or an abstract class. Previously abstract ctor signatures (if they didn't come from an interface) were only checked to one level of inheritance.
1 parent d1e5006 commit 0585548

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

Zend/tests/bug61970_2.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ class Baz extends Bar {
1515
protected function __construct(){}
1616
}
1717
--EXPECTF--
18-
Fatal error: Access level to Baz::__construct() must be public (as in class Bar) in %s on line 12
18+
Fatal error: Access level to Baz::__construct() must be public (as in class Foo) in %s on line 12
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
LSP checks are performed against an abstract constructor even if it is not a direct parent
3+
--FILE--
4+
<?php
5+
6+
abstract class A {
7+
abstract function __construct(X $x);
8+
}
9+
class B extends A {
10+
function __construct(X $x) {}
11+
}
12+
class C extends B {
13+
function __construct() {}
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
Fatal error: Declaration of C::__construct() must be compatible with A::__construct(X $x) in %s on line 10

Zend/zend_inheritance.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -597,11 +597,11 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function *
597597
proto = parent;
598598
}
599599
} else if (proto) {
600-
if (proto->common.scope->ce_flags & ZEND_ACC_INTERFACE) {
601-
/* ctors only have a prototype if it comes from an interface */
602-
/* and if that is the case, we want to check inheritance against it */
600+
/* ctors only have a prototype if is abstract (or comes from an interface) */
601+
/* and if that is the case, we want to check inheritance against it */
602+
if (proto->common.fn_flags & ZEND_ACC_ABSTRACT) {
603603
parent = proto;
604-
} else if (!(proto->common.fn_flags & ZEND_ACC_ABSTRACT)) {
604+
} else {
605605
break;
606606
}
607607
} else {

0 commit comments

Comments
 (0)