diff options
author | Stefan Marr <gron@php.net> | 2010-11-18 17:59:04 +0000 |
---|---|---|
committer | Stefan Marr <gron@php.net> | 2010-11-18 17:59:04 +0000 |
commit | 4cc45507da8164847708c26bfdf0840419a166fc (patch) | |
tree | d2b04153a3f0dc0fb664da413370bf81f91614da | |
parent | 15c9da1149b01f7700df5b3dc8ab346dc6d85ec2 (diff) | |
download | php-git-4cc45507da8164847708c26bfdf0840419a166fc.tar.gz |
Fixed problem reported by Patrick ALLAERT. Trait method was not applied properly when fully qualified.
-rw-r--r-- | Zend/tests/traits/bugs/alias-semantics02.phpt | 25 | ||||
-rw-r--r-- | Zend/tests/traits/error_015.phpt | 7 | ||||
-rw-r--r-- | Zend/tests/traits/language010.phpt | 4 | ||||
-rw-r--r-- | Zend/zend_compile.c | 42 |
4 files changed, 40 insertions, 38 deletions
diff --git a/Zend/tests/traits/bugs/alias-semantics02.phpt b/Zend/tests/traits/bugs/alias-semantics02.phpt new file mode 100644 index 0000000000..e0b5286e4f --- /dev/null +++ b/Zend/tests/traits/bugs/alias-semantics02.phpt @@ -0,0 +1,25 @@ +--TEST-- +Semantic of alias operation is to provide an additional identifier for the +method body of the original method. +It should also work incase the method is fully qualified. +--FILE-- +<?php +error_reporting(E_ALL); + +trait THello { + public function a() { + echo 'A'; + } +} + +class TraitsTest { + use THello { THello::a as b; } +} + +$test = new TraitsTest(); +$test->a(); +$test->b(); + +?> +--EXPECTF-- +AA
\ No newline at end of file diff --git a/Zend/tests/traits/error_015.phpt b/Zend/tests/traits/error_015.phpt index 571e6f4db5..ec47c0d8e2 100644 --- a/Zend/tests/traits/error_015.phpt +++ b/Zend/tests/traits/error_015.phpt @@ -1,5 +1,6 @@ --TEST-- -Trying to add an alias to a trait method where there is another with same name +Trying to add an alias to a trait method where there is another with same name. +Should warn about the conflict. --FILE-- <?php @@ -22,4 +23,6 @@ var_dump($x->test()); ?> --EXPECTF-- -Fatal error: Failed to add aliased trait method (zzz) to the trait table. There is probably already a trait method with the same name in %s on line %d +Warning: Trait method test has not been applied, because there are collisions with other trait methods on bar in %s on line %d + +Fatal error: Call to undefined method bar::test() in %s on line %d diff --git a/Zend/tests/traits/language010.phpt b/Zend/tests/traits/language010.phpt index f184457bef..f7fea6f295 100644 --- a/Zend/tests/traits/language010.phpt +++ b/Zend/tests/traits/language010.phpt @@ -27,6 +27,4 @@ $o->world(); ?> --EXPECTF-- -Warning: Trait method world has not been applied, because there are collisions with other trait methods on MyClass in %s on line %d -Hello -Fatal error: Call to undefined method MyClass::world() in %s on line %d
\ No newline at end of file +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 diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index c49dce6fcb..ec741f9e10 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3674,13 +3674,13 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args, target = va_arg(args, HashTable*); aliases = va_arg(args, zend_trait_alias**); exclude_table = va_arg(args, HashTable*); - + fnname_len = strlen(fn->common.function_name); - /* apply aliases which are qualified with a class name, there should not be any ambiguatty */ + /* apply aliases which are qualified with a class name, there should not be any ambiguity */ if (aliases) { while (aliases[i]) { - if (fn->common.scope == aliases[i]->trait_method->ce && + 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)) { @@ -3716,9 +3716,8 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args, fn_copy = *fn; zend_traits_duplicate_function(&fn_copy, estrndup(fn->common.function_name, fnname_len) TSRMLS_CC); - /* apply aliases which are not qualified by a class name, or which have not alias name, just setting visibility */ - /* TODO: i am still not sure, that there will be no ambigousities... */ - + /* apply aliases which are not qualified by a class name, or which have not + alias name, just setting visibility */ if (aliases) { i = 0; while (aliases[i]) { @@ -3726,33 +3725,10 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args, (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) { - zend_uint lcname2_len; - char* lcname2; - zend_function fn_copy2 = *fn; - - zend_traits_duplicate_function(&fn_copy2, estrndup(aliases[i]->alias, aliases[i]->alias_len) TSRMLS_CC); - - if (aliases[i]->modifiers) { /* if it is 0, no modifieres has been changed */ - fn_copy2.common.fn_flags = aliases[i]->modifiers; - if (!(aliases[i]->modifiers & ZEND_ACC_PPP_MASK)) { - fn_copy2.common.fn_flags |= ZEND_ACC_PUBLIC; - } - } - - lcname2_len = aliases[i]->alias_len; - lcname2 = zend_str_tolower_dup(aliases[i]->alias, lcname2_len); - - if (zend_hash_add(target, lcname2, lcname2_len+1, &fn_copy2, sizeof(zend_function), NULL)==FAILURE) { - zend_error(E_ERROR, "Failed to add aliased trait method (%s) to the trait table. There is probably already a trait method with the same name", fn_copy2.common.function_name); - } - efree(lcname2); - } else { - if (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)) { - fn_copy.common.fn_flags |= ZEND_ACC_PUBLIC; - } + 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)) { + fn_copy.common.fn_flags |= ZEND_ACC_PUBLIC; } } } |