]> granicus.if.org Git - php/commitdiff
Fixed variance check for abstract constructor during erlay binding
authorDmitry Stogov <dmitry@zend.com>
Tue, 25 Jun 2019 14:43:46 +0000 (17:43 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 25 Jun 2019 14:43:46 +0000 (17:43 +0300)
Zend/tests/type_declarations/variance/abstract_constructor.phpt [new file with mode: 0644]
Zend/zend_inheritance.c

diff --git a/Zend/tests/type_declarations/variance/abstract_constructor.phpt b/Zend/tests/type_declarations/variance/abstract_constructor.phpt
new file mode 100644 (file)
index 0000000..f061517
--- /dev/null
@@ -0,0 +1,18 @@
+--TEST--
+Variance check for abstract constructor
+--FILE--
+<?php
+class X {
+}
+abstract class A {
+    abstract function __construct(X $x);
+}
+class B extends A {
+    function __construct(object $x) {}
+}
+class C extends B {
+    function __construct(Y $x) {}
+}
+?>
+--EXPECTF--
+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
index af893bc112379c14c0e70aa25dbdb872f5e25ddc..c57d061793ed596672e3efb4c81d5e1755322409 100644 (file)
@@ -2395,9 +2395,19 @@ zend_bool zend_can_early_bind(zend_class_entry *ce, zend_class_entry *parent_ce)
                zval *zv;
                zend_string *unresolved_class;
 
-               if ((parent_flags & ZEND_ACC_PRIVATE) ||
-                       ((parent_flags & ZEND_ACC_CTOR) && !(parent_flags & ZEND_ACC_ABSTRACT))) {
+               if (parent_flags & ZEND_ACC_PRIVATE) {
                        continue;
+               } else if (parent_flags & ZEND_ACC_CTOR) {
+                       zend_function *proto = parent_func->common.prototype ?
+                               parent_func->common.prototype : parent_func;
+
+                       /* ctors only have a prototype if is abstract (or comes from an interface) */
+                       /* and if that is the case, we want to check inheritance against it */
+                       if (proto->common.fn_flags & ZEND_ACC_ABSTRACT) {
+                               parent_func = proto;
+                       } else {
+                               continue;
+                       }
                }
 
                zv = zend_hash_find_ex(&ce->function_table, key, 1);