From: Stefan Marr Date: Thu, 18 Nov 2010 17:59:04 +0000 (+0000) Subject: Fixed problem reported by Patrick ALLAERT. Trait method was not applied properly... X-Git-Tag: php-5.4.0alpha1~191^2~636 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4cc45507da8164847708c26bfdf0840419a166fc;p=php Fixed problem reported by Patrick ALLAERT. Trait method was not applied properly when fully qualified. --- 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-- +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-- 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; } } }