diff options
Diffstat (limited to 'Zend/zend_compile.c')
-rw-r--r-- | Zend/zend_compile.c | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 28f98249d2..c39d8eaa1e 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1685,7 +1685,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n zval key; if (CG(current_namespace)) { - /* Prefix function name with current namespcae name */ + /* Prefix function name with current namespace name */ znode tmp; tmp.u.constant = *CG(current_namespace); @@ -2935,6 +2935,11 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c return 1; } + /* If both methods are private do not enforce a signature */ + if ((fe->common.fn_flags & ZEND_ACC_PRIVATE) && (proto->common.fn_flags & ZEND_ACC_PRIVATE)) { + return 1; + } + /* check number of arguments */ if (proto->common.required_num_args < fe->common.required_num_args || proto->common.num_args > fe->common.num_args) { @@ -3712,7 +3717,7 @@ static int zend_traits_merge_functions(zend_function *fn TSRMLS_DC, int num_args } else { /* Add it to result function table */ if (zend_hash_quick_add(resulting_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, fn, sizeof(zend_function), NULL)==FAILURE) { - zend_error(E_COMPILE_ERROR, "Trait method %s has not been applied, because failure occured during updating resulting trait method table", fn->common.function_name); + zend_error(E_COMPILE_ERROR, "Trait method %s has not been applied, because failure occurred during updating resulting trait method table", fn->common.function_name); } } @@ -3801,9 +3806,12 @@ static int zend_traits_merge_functions_to_class(zend_function *fn TSRMLS_DC, int 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) { + prototype = fn->common.prototype; do_inheritance_check_on_method(fn, existing_fn TSRMLS_CC); + fn->common.prototype = prototype; } /* delete inherited fn if the function to be added is not abstract */ @@ -3829,11 +3837,11 @@ static int zend_traits_merge_functions_to_class(zend_function *fn TSRMLS_DC, int function_add_ref(&fn_copy); if (zend_hash_quick_update(&ce->function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, &fn_copy, sizeof(zend_function), (void**)&fn_copy_p)==FAILURE) { - zend_error(E_COMPILE_ERROR, "Trait method %s has not been applied, because failure occured during updating class method table", hash_key->arKey); + zend_error(E_COMPILE_ERROR, "Trait method %s has not been applied, because failure occurred during updating class method table", hash_key->arKey); } - + zend_add_magic_methods(ce, hash_key->arKey, hash_key->nKeyLength, fn_copy_p TSRMLS_CC); - + zend_function_dtor(fn); } else { zend_function_dtor(fn); @@ -3870,10 +3878,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)) { fn_copy = *fn; function_add_ref(&fn_copy); - /* this function_name is never destroyed, because its refcount - greater than 1 and classes are always destoyed before the - traits they use */ + /* this function_name is never destroyed, because ZEND_ACC_ALIAS + flag is set */ fn_copy.common.function_name = aliases[i]->alias; + fn_copy.common.fn_flags |= ZEND_ACC_ALIAS; /* if it is 0, no modifieres has been changed */ if (aliases[i]->modifiers) { @@ -3906,6 +3914,7 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args, /* is not in hashtable, thus, function is not to be excluded */ fn_copy = *fn; function_add_ref(&fn_copy); + fn_copy.common.fn_flags |= ZEND_ACC_ALIAS; /* apply aliases which are not qualified by a class name, or which have not * alias name, just setting visibility */ @@ -4025,9 +4034,9 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* /** And, ensure that the referenced method is resolvable, too. */ lcname = zend_str_tolower_dup(cur_method_ref->method_name, - cur_method_ref->mname_len); + cur_method_ref->mname_len); method_exists = zend_hash_exists(&cur_method_ref->ce->function_table, - lcname, cur_method_ref->mname_len + 1); + lcname, cur_method_ref->mname_len + 1); efree(lcname); if (!method_exists) { @@ -5009,11 +5018,11 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name opline->op2_type = IS_CONST; if (doing_inheritance) { - /* Make sure a trait does not try to extend a class */ - if ((new_class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { - zend_error(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error", new_class_entry->name); - } - + /* Make sure a trait does not try to extend a class */ + if ((new_class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { + zend_error(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error", new_class_entry->name); + } + opline->extended_value = parent_class_name->u.op.var; opline->opcode = ZEND_DECLARE_INHERITED_CLASS; } else { @@ -6958,9 +6967,9 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{ lcname = zend_str_tolower_dup(Z_STRVAL_P(name), Z_STRLEN_P(name)); if (((Z_STRLEN_P(name) == sizeof("self")-1) && - !memcmp(lcname, "self", sizeof("self")-1)) || - ((Z_STRLEN_P(name) == sizeof("parent")-1) && - !memcmp(lcname, "parent", sizeof("parent")-1))) { + !memcmp(lcname, "self", sizeof("self")-1)) || + ((Z_STRLEN_P(name) == sizeof("parent")-1) && + !memcmp(lcname, "parent", sizeof("parent")-1))) { zend_error(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' is a special class name", Z_STRVAL_P(ns), Z_STRVAL_P(name), Z_STRVAL_P(name)); } |