]> granicus.if.org Git - php/commitdiff
Fixed a inconsitent condition for aliasing traits.
authorStefan Marr <gron@php.net>
Fri, 13 May 2011 20:28:34 +0000 (20:28 +0000)
committerStefan Marr <gron@php.net>
Fri, 13 May 2011 20:28:34 +0000 (20:28 +0000)
- missed a failing Traits test, but is now fixed, and the bug covered by a dedicated test
# Should always comment conditions that go over more than two lines :-/

Zend/tests/traits/bugs/alias01.phpt [new file with mode: 0644]
Zend/tests/traits/language010.phpt
Zend/zend_compile.c

diff --git a/Zend/tests/traits/bugs/alias01.phpt b/Zend/tests/traits/bugs/alias01.phpt
new file mode 100644 (file)
index 0000000..b60261e
--- /dev/null
@@ -0,0 +1,26 @@
+--TEST--
+Aliases are applied to the correct methods, and only to them.
+--FILE--
+<?php
+trait T1 {
+  function m1() { echo "T:m1\n"; }
+  function m2() { echo "T:m2\n"; }
+}
+
+class C1 { 
+  use T1 { m1 as a1; }
+}
+
+$o = new C1;
+$o->m1();
+$o->a1();
+$o->m2();
+$o->a2();
+
+?>
+--EXPECTF--
+T:m1
+T:m1
+T:m2
+
+Fatal error: Call to undefined method C1::a2() in %s on line %d
index f7fea6f295046ef639398371877536f7aae22916..e550abb7bc6814669051c7847c74d157df965295 100644 (file)
@@ -27,4 +27,4 @@ $o->world();
 
 ?>
 --EXPECTF--    
-Fatal error: Failed to add trait method (world) to the trait table. There is probably already a trait method with the same name in %s on line %d
\ No newline at end of file
+Fatal error: Trait method world has not been applied, because there are collisions with other trait methods on MyClass in %s on line %d
\ No newline at end of file
index a16380f7b862feb555d72b6302aaf9ccaeaedf0f..7c992b9cf786161628114754eb7afdc4d7792f8d 100644 (file)
@@ -3662,10 +3662,13 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args,
        /* apply aliases which are qualified with a class name, there should not be any ambiguity */
        if (aliases) {
                while (aliases[i]) {
-                       if (!aliases[i]->trait_method->ce || (fn->common.scope == aliases[i]->trait_method->ce &&
-                               (zend_binary_strcasecmp(aliases[i]->trait_method->method_name,
+      
+                       if (/* Scope unset or equal to the function we compare to */
+          (!aliases[i]->trait_method->ce || fn->common.scope == aliases[i]->trait_method->ce)
+          && /* and, the alias applies to fn */
+          (zend_binary_strcasecmp(aliases[i]->trait_method->method_name,
                                                                                                                                 aliases[i]->trait_method->mname_len,
-                                                                                                                                fn->common.function_name, fnname_len) == 0))) {
+                                                                                                                                fn->common.function_name, fnname_len) == 0)) {
                                if (aliases[i]->alias) {
                                        fn_copy = *fn;
                                        zend_traits_duplicate_function(&fn_copy, estrndup(aliases[i]->alias, aliases[i]->alias_len) TSRMLS_CC);
@@ -3703,10 +3706,12 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args,
                if (aliases) {
                        i = 0;
                        while (aliases[i]) {
-                               if ((!aliases[i]->trait_method->ce || fn->common.scope == aliases[i]->trait_method->ce) &&
-                                       (zend_binary_strcasecmp(aliases[i]->trait_method->method_name,
-                                                                                                                                        aliases[i]->trait_method->mname_len,
-                                                                                                                                        fn->common.function_name, fnname_len) == 0)) {
+                               if (/* Scope unset or equal to the function we compare to */
+            (!aliases[i]->trait_method->ce || fn->common.scope == aliases[i]->trait_method->ce)
+            && /* and, the alias applies to fn */
+                                         (zend_binary_strcasecmp(aliases[i]->trait_method->method_name,
+                                    aliases[i]->trait_method->mname_len,
+                                                                                                                                         fn->common.function_name, fnname_len) == 0)) {
                                        if (!aliases[i]->alias && aliases[i]->modifiers) { /* if it is 0, no modifieres has been changed */
                                                fn_copy.common.fn_flags = aliases[i]->modifiers;
                                                if (!(aliases[i]->modifiers & ZEND_ACC_PPP_MASK)) {