]> granicus.if.org Git - php/commitdiff
Fix bug #74607: Don't check for bi-directional compatibility in traits
authorPedro Magalhães <mail@pmmaga.net>
Sun, 21 May 2017 12:41:55 +0000 (14:41 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 2 Jun 2017 22:24:43 +0000 (00:24 +0200)
NEWS
Zend/tests/traits/bug60217b.phpt
Zend/tests/traits/bug74607.phpt [new file with mode: 0644]
Zend/tests/traits/bug74607a.phpt [new file with mode: 0644]
Zend/tests/traits/bugs/abstract-methods05.phpt
Zend/zend_inheritance.c

diff --git a/NEWS b/NEWS
index 7c75a2566ead7476bd01ddf50538df60e9fd9191..2a65522381ad0cfec86aaec02c7ec8f65a05c619 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -55,6 +55,7 @@ PHP                                                                        NEWS
     a fatal error). (pmmaga)
   . Fixed bug #63384 (Cannot override an abstract method with an abstract
     method). (pmmaga, wes)
+  . Fixed bug #74607 (Traits enforce different inheritance rules). (pmmaga)
   . Fixed misparsing of abstract unix domain socket names. (Sara)
 
 - BCMath:
index eb852a4fb43c81cd529994c95bc3b0a60e3c9a2b..8b2b64e5348fc1e84fe948658f4839e365a51c69 100644 (file)
@@ -23,4 +23,4 @@ $o = new CBroken;
 $o->foo(1);
 
 --EXPECTF--
-Fatal error: Declaration of TBroken2::foo($a, $b = 0) must be compatible with TBroken1::foo($a) in %s on line %d
+Fatal error: Declaration of TBroken1::foo($a) must be compatible with TBroken2::foo($a, $b = 0) in %s
diff --git a/Zend/tests/traits/bug74607.phpt b/Zend/tests/traits/bug74607.phpt
new file mode 100644 (file)
index 0000000..6f158db
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+Bug #74607 (Traits enforce different inheritance rules - return types)
+--FILE--
+<?php
+
+abstract class L1{ 
+abstract function m3($x);
+} 
+
+trait L2t{ 
+function m3($x): int{}
+} 
+
+class L2 extends L1{ 
+use L2t; 
+}
+
+echo "DONE";
+
+?>
+--EXPECT--
+DONE
diff --git a/Zend/tests/traits/bug74607a.phpt b/Zend/tests/traits/bug74607a.phpt
new file mode 100644 (file)
index 0000000..efdced9
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+Bug #74607 (Traits enforce different inheritance rules - number of required parameters)
+--FILE--
+<?php
+
+abstract class L1{ 
+abstract function m3($x);
+} 
+
+trait L2t{ 
+function m3($x, $y = 0){}
+} 
+
+class L2 extends L1{ 
+use L2t; 
+}
+
+echo "DONE";
+
+?>
+--EXPECT--
+DONE
index 9a1315f8688d2899b3c52107a6ad3d114419f767..839be75c2b507110e74ad9bdc0871466f29cdc37 100644 (file)
@@ -22,4 +22,4 @@ class TraitsTest1 {
 
 ?>
 --EXPECTF--    
-Fatal error: Declaration of THelloA::hello($a) must be compatible with THelloB::hello() in %s on line %d
+Fatal error: Declaration of THelloB::hello() must be compatible with THelloA::hello($a) in %s on line %d
index 8f43d1560099d3874d3534d1b4e12febd3f9b1e8..868a0bddf07a220336e563e704c65a42d870e083 100644 (file)
@@ -1088,7 +1088,6 @@ static zend_bool zend_traits_method_compatibility_check(zend_function *fn, zend_
        uint32_t other_flags = other_fn->common.scope->ce_flags;
 
        return zend_do_perform_implementation_check(fn, other_fn)
-               && ((other_fn->common.scope->ce_flags & ZEND_ACC_INTERFACE) || zend_do_perform_implementation_check(other_fn, fn))
                && ((fn_flags & (ZEND_ACC_FINAL|ZEND_ACC_STATIC)) ==
                    (other_flags & (ZEND_ACC_FINAL|ZEND_ACC_STATIC))); /* equal final and static qualifier */
 }
@@ -1158,12 +1157,13 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s
                                                                ZSTR_VAL(zend_get_function_declaration(fn)),
                                                                ZSTR_VAL(zend_get_function_declaration(existing_fn)));
                                                }
-                                       } else if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
+                                       }
+                                       if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
                                                /* Make sure the abstract declaration is compatible with previous declaration */
                                                if (UNEXPECTED(!zend_traits_method_compatibility_check(existing_fn, fn))) {
                                                        zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s",
-                                                               ZSTR_VAL(zend_get_function_declaration(fn)),
-                                                               ZSTR_VAL(zend_get_function_declaration(existing_fn)));
+                                                               ZSTR_VAL(zend_get_function_declaration(existing_fn)),
+                                                               ZSTR_VAL(zend_get_function_declaration(fn)));
                                                }
                                                return;
                                        }
@@ -1186,8 +1186,8 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s
                        /* Make sure the abstract declaration is compatible with previous declaration */
                        if (UNEXPECTED(!zend_traits_method_compatibility_check(existing_fn, fn))) {
                                zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s",
-                                       ZSTR_VAL(zend_get_function_declaration(fn)),
-                                       ZSTR_VAL(zend_get_function_declaration(existing_fn)));
+                                       ZSTR_VAL(zend_get_function_declaration(existing_fn)),
+                                       ZSTR_VAL(zend_get_function_declaration(fn)));
                        }
                        return;
                } else if (UNEXPECTED(existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT)) {