svn: /php/php-src/ branches/PHP_5_4/Zend/tests/traits/bug55424.phpt branches/PHP_5_4/Zend/zend_compile.c trunk/Zend/tests/traits/bug55424.phpt
trunk/Zend/zend_compile.c
| From: | Stefan Marr | Date: | Mon, 15 Aug 2011 22:16:58 +0000 |
| Subject: | svn: /php/php-src/ branches/PHP_5_4/Zend/tests/traits/bug55424.phpt branches/PHP_5_4/Zend/zend_compile.c trunk/Zend/tests/traits/bug55424.phpt trunk/Zend/zend_compile.c |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-65859@lists.php.net to get a copy of this message | ||
gron Mon, 15 Aug 2011 22:16:58 +0000
Revision: http://svn.php.net/viewvc?view=revision&revision=314981
Log:
Bug #55424 Fatal error when calling a method from a trait that is defined in parent class and
required by using an abstract method in the trait.
# The method got unconditionally deleted from the class, since it was assumed that we override it,
but we did not in case of abstract methods coming from a trait. Thus, dont delete when we try to
merge in an abstract method.
Bug: https://bugs.php.net/55424 (Open) Fatal error when
calling a method from a trait that is defined in parent class
Changed paths:
A php/php-src/branches/PHP_5_4/Zend/tests/traits/bug55424.phpt
U php/php-src/branches/PHP_5_4/Zend/zend_compile.c
A php/php-src/trunk/Zend/tests/traits/bug55424.phpt
U php/php-src/trunk/Zend/zend_compile.c
Added: php/php-src/branches/PHP_5_4/Zend/tests/traits/bug55424.phpt
===================================================================
--- php/php-src/branches/PHP_5_4/Zend/tests/traits/bug55424.phpt (rev 0)
+++ php/php-src/branches/PHP_5_4/Zend/tests/traits/bug55424.phpt 2011-08-15 22:16:58 UTC (rev
314981)
@@ -0,0 +1,35 @@
+--TEST--
+Bug #55424 (Method got missing from class when a trait defined an abstract method to express a
requirement)
+--FILE--
+<?php
+
+ trait ATrait
+ {
+ function setRequired()
+ {
+ $this->setAttribute();
+ }
+
+ abstract function setAttribute();
+ }
+
+ class Base
+ {
+ function setAttribute() { }
+ }
+
+ class MyClass extends Base
+ {
+ use ATrait;
+ }
+
+ $i = new Base();
+ $i->setAttribute();
+
+ $t = new MyClass();
+ /* setAttribute used to disappear for no good reason. */
+ $t->setRequired();
+ 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 20:41:33 UTC (rev 314980)
+++ php/php-src/branches/PHP_5_4/Zend/zend_compile.c 2011-08-15 22:16:58 UTC (rev 314981)
@@ -3635,10 +3635,13 @@
} else if (existing_fn->common.scope != ce) {
add = 1; /* or inherited from other class or interface */
/* it is just a reference which was added to the subclass while doing the inheritance */
- /* prototype = existing_fn; */
- /* memory is scrambled anyway???? */
- /* function_add_ref(prototype); */
- zend_hash_quick_del(&ce->function_table, hash_key->arKey, hash_key->nKeyLength,
hash_key->h);
+ /* so we can deleted now, and will add the overriding method afterwards */
+
+ /* except, if we try to add an abstract function, then we should not delete the inherited one */
+ /* delete inherited fn if the function to be added is not abstract */
+ if ((fn->common.fn_flags & ZEND_ACC_ABSTRACT) == 0) {
+ zend_hash_quick_del(&ce->function_table, hash_key->arKey, hash_key->nKeyLength,
hash_key->h);
+ }
}
if (add) {
Added: php/php-src/trunk/Zend/tests/traits/bug55424.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/traits/bug55424.phpt (rev 0)
+++ php/php-src/trunk/Zend/tests/traits/bug55424.phpt 2011-08-15 22:16:58 UTC (rev 314981)
@@ -0,0 +1,35 @@
+--TEST--
+Bug #55424 (Method got missing from class when a trait defined an abstract method to express a
requirement)
+--FILE--
+<?php
+
+ trait ATrait
+ {
+ function setRequired()
+ {
+ $this->setAttribute();
+ }
+
+ abstract function setAttribute();
+ }
+
+ class Base
+ {
+ function setAttribute() { }
+ }
+
+ class MyClass extends Base
+ {
+ use ATrait;
+ }
+
+ $i = new Base();
+ $i->setAttribute();
+
+ $t = new MyClass();
+ /* setAttribute used to disappear for no good reason. */
+ $t->setRequired();
+ echo 'DONE';
+?>
+--EXPECT--
+DONE
Modified: php/php-src/trunk/Zend/zend_compile.c
===================================================================
--- php/php-src/trunk/Zend/zend_compile.c 2011-08-15 20:41:33 UTC (rev 314980)
+++ php/php-src/trunk/Zend/zend_compile.c 2011-08-15 22:16:58 UTC (rev 314981)
@@ -3635,10 +3635,13 @@
} else if (existing_fn->common.scope != ce) {
add = 1; /* or inherited from other class or interface */
/* it is just a reference which was added to the subclass while doing the inheritance */
- /* prototype = existing_fn; */
- /* memory is scrambled anyway???? */
- /* function_add_ref(prototype); */
- zend_hash_quick_del(&ce->function_table, hash_key->arKey, hash_key->nKeyLength,
hash_key->h);
+ /* so we can deleted now, and will add the overriding method afterwards */
+
+ /* except, if we try to add an abstract function, then we should not delete the inherited one */
+ /* delete inherited fn if the function to be added is not abstract */
+ if ((fn->common.fn_flags & ZEND_ACC_ABSTRACT) == 0) {
+ zend_hash_quick_del(&ce->function_table, hash_key->arKey, hash_key->nKeyLength,
hash_key->h);
+ }
}
if (add) {