]> granicus.if.org Git - php/commitdiff
Fixed Bug #55355: Inheritance chain was not regarded when checking whether the abstra...
authorStefan Marr <gron@php.net>
Mon, 15 Aug 2011 11:16:18 +0000 (11:16 +0000)
committerStefan Marr <gron@php.net>
Mon, 15 Aug 2011 11:16:18 +0000 (11:16 +0000)
Zend/tests/traits/bug55355.phpt [new file with mode: 0644]
Zend/zend_compile.c

diff --git a/Zend/tests/traits/bug55355.phpt b/Zend/tests/traits/bug55355.phpt
new file mode 100644 (file)
index 0000000..301ceee
--- /dev/null
@@ -0,0 +1,46 @@
+--TEST--
+Bug #55355 (Abstract functions required by a trait are not correctly found when implemented in an ancestor class)
+--FILE--
+<?php
+
+// A trait that has a abstract function
+trait ATrait {
+       function bar() {
+               $this->foo();
+       }
+       abstract function foo(); 
+}
+
+// A class on the second level in the
+// inheritance chain
+class Level2Impl {
+       function foo() {}
+}
+
+class Level1Indirect extends Level2Impl {}
+
+// A class on the first level in the
+// inheritance chain
+class Level1Direct {
+    function foo() {}
+}
+
+// Trait Uses
+
+class Direct {
+    use ATrait;
+    function foo() {}
+}
+
+class BaseL2 extends Level1Indirect {
+    use ATrait;
+}
+
+class BaseL1 extends Level1Direct {
+    use ATrait;
+}
+
+echo 'DONE';
+?>
+--EXPECT--
+DONE
index 1b8b2dd04e37f45a04e1ede49f846511c5d7970e..59e0193194856f22e0c0211256c8a952c9043b33 100644 (file)
@@ -3645,6 +3645,14 @@ static int zend_traits_merge_functions_to_class(zend_function *fn TSRMLS_DC, int
                zend_function* parent_function;
                if (ce->parent && zend_hash_quick_find(&ce->parent->function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void**) &parent_function) != FAILURE) {
                        prototype = parent_function; /* ->common.fn_flags |= ZEND_ACC_ABSTRACT; */
+                       
+                       /* we got that method in the parent class, and are going to override it,
+                          except, if the trait is just asking to have an abstract method implemented. */
+                       if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
+                               /* then we clean up an skip this method */
+                               zend_function_dtor(fn);
+                               return ZEND_HASH_APPLY_REMOVE;
+                       }
                }
 
                fn->common.scope = ce;