Skip to content

Commit f09d41f

Browse files
committed
Fixed variance check for abstract constructor during erlay binding
1 parent ccbc121 commit f09d41f

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Variance check for abstract constructor
3+
--FILE--
4+
<?php
5+
class X {
6+
}
7+
abstract class A {
8+
abstract function __construct(X $x);
9+
}
10+
class B extends A {
11+
function __construct(object $x) {}
12+
}
13+
class C extends B {
14+
function __construct(Y $x) {}
15+
}
16+
?>
17+
--EXPECTF--
18+
Fatal error: Could not check compatibility between C::__construct(Y $x) and A::__construct(X $x), because class Y is not available in %s on line %d

Zend/zend_inheritance.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2395,9 +2395,19 @@ zend_bool zend_can_early_bind(zend_class_entry *ce, zend_class_entry *parent_ce)
23952395
zval *zv;
23962396
zend_string *unresolved_class;
23972397

2398-
if ((parent_flags & ZEND_ACC_PRIVATE) ||
2399-
((parent_flags & ZEND_ACC_CTOR) && !(parent_flags & ZEND_ACC_ABSTRACT))) {
2398+
if (parent_flags & ZEND_ACC_PRIVATE) {
24002399
continue;
2400+
} else if (parent_flags & ZEND_ACC_CTOR) {
2401+
zend_function *proto = parent_func->common.prototype ?
2402+
parent_func->common.prototype : parent_func;
2403+
2404+
/* ctors only have a prototype if is abstract (or comes from an interface) */
2405+
/* and if that is the case, we want to check inheritance against it */
2406+
if (proto->common.fn_flags & ZEND_ACC_ABSTRACT) {
2407+
parent_func = proto;
2408+
} else {
2409+
continue;
2410+
}
24012411
}
24022412

24032413
zv = zend_hash_find_ex(&ce->function_table, key, 1);

0 commit comments

Comments
 (0)