gron                                     Mon, 15 Aug 2011 11:16:18 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=314943

Log:
Fixed Bug #55355: Inheritance chain was not regarded when checking whether the 
abstract method of a trait is satisfied.

Bug: https://bugs.php.net/55355 (Open) Unexpected fatal error when using 
abstract functions with traits
      
Changed paths:
    A   php/php-src/branches/PHP_5_4/Zend/tests/traits/bug55355.phpt
    U   php/php-src/branches/PHP_5_4/Zend/zend_compile.c
    A   php/php-src/trunk/Zend/tests/traits/bug55355.phpt
    U   php/php-src/trunk/Zend/zend_compile.c

Added: php/php-src/branches/PHP_5_4/Zend/tests/traits/bug55355.phpt
===================================================================
--- php/php-src/branches/PHP_5_4/Zend/tests/traits/bug55355.phpt                
                (rev 0)
+++ php/php-src/branches/PHP_5_4/Zend/tests/traits/bug55355.phpt        
2011-08-15 11:16:18 UTC (rev 314943)
@@ -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

Modified: php/php-src/branches/PHP_5_4/Zend/zend_compile.c
===================================================================
--- php/php-src/branches/PHP_5_4/Zend/zend_compile.c    2011-08-15 11:06:35 UTC 
(rev 314942)
+++ php/php-src/branches/PHP_5_4/Zend/zend_compile.c    2011-08-15 11:16:18 UTC 
(rev 314943)
@@ -3645,6 +3645,14 @@
                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;

Added: php/php-src/trunk/Zend/tests/traits/bug55355.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/traits/bug55355.phpt                           
(rev 0)
+++ php/php-src/trunk/Zend/tests/traits/bug55355.phpt   2011-08-15 11:16:18 UTC 
(rev 314943)
@@ -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

Modified: php/php-src/trunk/Zend/zend_compile.c
===================================================================
--- php/php-src/trunk/Zend/zend_compile.c       2011-08-15 11:06:35 UTC (rev 
314942)
+++ php/php-src/trunk/Zend/zend_compile.c       2011-08-15 11:16:18 UTC (rev 
314943)
@@ -3645,6 +3645,14 @@
                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;

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to