gron                                     Tue, 01 Nov 2011 15:25:24 +0000

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

Log:
Fixed Bug #60153 (Interface method prototypes not enforced when implementd via 
traits.)
# Moved the freeing of overriden functions to a point after the check.
# The new check comes after the normal inheritance check to give the first check
# the opportunity to abort with a more detailed error.
# Also fixed a small type in an unrelated test.

Bug: https://bugs.php.net/60153 (Open) Interface method prototypes not enforced 
when implementd via traits.
      
Changed paths:
    A   php/php-src/branches/PHP_5_4/Zend/tests/traits/bug60153.phpt
    U   php/php-src/branches/PHP_5_4/Zend/tests/traits/inheritance003.phpt
    U   php/php-src/branches/PHP_5_4/Zend/zend_compile.c
    A   php/php-src/trunk/Zend/tests/traits/bug60153.phpt
    U   php/php-src/trunk/Zend/tests/traits/inheritance003.phpt
    U   php/php-src/trunk/Zend/zend_compile.c

Added: php/php-src/branches/PHP_5_4/Zend/tests/traits/bug60153.phpt
===================================================================
--- php/php-src/branches/PHP_5_4/Zend/tests/traits/bug60153.phpt                
                (rev 0)
+++ php/php-src/branches/PHP_5_4/Zend/tests/traits/bug60153.phpt        
2011-11-01 15:25:24 UTC (rev 318650)
@@ -0,0 +1,19 @@
+--TEST--
+Bug #60153 (Interface method prototypes not enforced when implementd via 
traits.)
+--FILE--
+<?php
+
+interface IFoo {
+    public function oneArgument($a);
+}
+
+trait TFoo {
+  public function oneArgument() {}
+}
+
+class C implements IFoo {
+  use TFoo;
+}
+
+--EXPECTF--
+Fatal error: Declaration of C::oneArgument() must be compatible with 
IFoo::oneArgument($a) in %s on line %d

Modified: php/php-src/branches/PHP_5_4/Zend/tests/traits/inheritance003.phpt
===================================================================
--- php/php-src/branches/PHP_5_4/Zend/tests/traits/inheritance003.phpt  
2011-11-01 15:15:51 UTC (rev 318649)
+++ php/php-src/branches/PHP_5_4/Zend/tests/traits/inheritance003.phpt  
2011-11-01 15:25:24 UTC (rev 318650)
@@ -1,5 +1,5 @@
 --TEST--
-Trait method overriddes base class method and satisfies prototype
+Trait method overrides base class method and satisfies prototype
 --FILE--
 <?php
 error_reporting(E_ALL);

Modified: php/php-src/branches/PHP_5_4/Zend/zend_compile.c
===================================================================
--- php/php-src/branches/PHP_5_4/Zend/zend_compile.c    2011-11-01 15:15:51 UTC 
(rev 318649)
+++ php/php-src/branches/PHP_5_4/Zend/zend_compile.c    2011-11-01 15:25:24 UTC 
(rev 318650)
@@ -3831,14 +3831,6 @@
                add = 1; /* not found */
        } 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 */
-               /* 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) {
@@ -3871,7 +3863,24 @@
                if (prototype) {
                        do_inheritance_check_on_method(fn, prototype TSRMLS_CC);
                }
+               /* one more thing: make sure we properly implement an abstract 
method */
+               if (existing_fn && existing_fn->common.fn_flags & 
ZEND_ACC_ABSTRACT) {
+                       do_inheritance_check_on_method(fn, existing_fn 
TSRMLS_CC);
+               }

+               /* delete inherited fn if the function to be added is not 
abstract */
+               if (existing_fn
+                       && existing_fn->common.scope != ce
+                       && (fn->common.fn_flags & ZEND_ACC_ABSTRACT) == 0) {
+                       /* it is just a reference which was added to the 
subclass while doing
+                          the inheritance, 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 */
+                       zend_hash_quick_del(&ce->function_table, 
hash_key->arKey, hash_key->nKeyLength, hash_key->h);
+               }
+
+
                if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
                        ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
                }

Added: php/php-src/trunk/Zend/tests/traits/bug60153.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/traits/bug60153.phpt                           
(rev 0)
+++ php/php-src/trunk/Zend/tests/traits/bug60153.phpt   2011-11-01 15:25:24 UTC 
(rev 318650)
@@ -0,0 +1,19 @@
+--TEST--
+Bug #60153 (Interface method prototypes not enforced when implementd via 
traits.)
+--FILE--
+<?php
+
+interface IFoo {
+    public function oneArgument($a);
+}
+
+trait TFoo {
+  public function oneArgument() {}
+}
+
+class C implements IFoo {
+  use TFoo;
+}
+
+--EXPECTF--
+Fatal error: Declaration of C::oneArgument() must be compatible with 
IFoo::oneArgument($a) in %s on line %d

Modified: php/php-src/trunk/Zend/tests/traits/inheritance003.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/traits/inheritance003.phpt     2011-11-01 
15:15:51 UTC (rev 318649)
+++ php/php-src/trunk/Zend/tests/traits/inheritance003.phpt     2011-11-01 
15:25:24 UTC (rev 318650)
@@ -1,5 +1,5 @@
 --TEST--
-Trait method overriddes base class method and satisfies prototype
+Trait method overrides base class method and satisfies prototype
 --FILE--
 <?php
 error_reporting(E_ALL);

Modified: php/php-src/trunk/Zend/zend_compile.c
===================================================================
--- php/php-src/trunk/Zend/zend_compile.c       2011-11-01 15:15:51 UTC (rev 
318649)
+++ php/php-src/trunk/Zend/zend_compile.c       2011-11-01 15:25:24 UTC (rev 
318650)
@@ -3831,14 +3831,6 @@
                add = 1; /* not found */
        } 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 */
-               /* 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) {
@@ -3871,7 +3863,24 @@
                if (prototype) {
                        do_inheritance_check_on_method(fn, prototype TSRMLS_CC);
                }
+               /* one more thing: make sure we properly implement an abstract 
method */
+               if (existing_fn && existing_fn->common.fn_flags & 
ZEND_ACC_ABSTRACT) {
+                       do_inheritance_check_on_method(fn, existing_fn 
TSRMLS_CC);
+               }

+               /* delete inherited fn if the function to be added is not 
abstract */
+               if (existing_fn
+                       && existing_fn->common.scope != ce
+                       && (fn->common.fn_flags & ZEND_ACC_ABSTRACT) == 0) {
+                       /* it is just a reference which was added to the 
subclass while doing
+                          the inheritance, 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 */
+                       zend_hash_quick_del(&ce->function_table, 
hash_key->arKey, hash_key->nKeyLength, hash_key->h);
+               }
+
+
                if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
                        ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
                }

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

Reply via email to