php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | |
Patch bug55719.diff for Unknown/Other Function Bug #55719Patch version 2011-09-18 15:14 UTC Return to Bug #55719 | Download this patchThis patch renders other patches obsolete Obsolete patches: Patch Revisions:
Developer: laruence@php.netIndex: Zend/zend_compile.c =================================================================== --- Zend/zend_compile.c (revision 316933) +++ Zend/zend_compile.c (working copy) @@ -3010,6 +3010,145 @@ } /* }}} */ +static char * zend_get_function_declaration(zend_function *fptr TSRMLS_CC) /* {{{ */ { + char *offset, *buf = (char *)emalloc(1024 * sizeof(char)); + + offset = buf; + if (fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) { + *(offset++) = '&'; + *(offset++) = ' '; + } + + if (fptr->common.scope) { + memcpy(offset, fptr->common.scope->name, fptr->common.scope->name_length); + offset += fptr->common.scope->name_length; + *(offset++) = ':'; + *(offset++) = ':'; + } + + { + size_t name_len = strlen(fptr->common.function_name); + memcpy(offset, fptr->common.function_name, name_len); + offset += name_len; + } + + *(offset++) = '('; + if (fptr->common.arg_info) { + zend_uint i, required; + zend_arg_info *arg_info = fptr->common.arg_info; + + required = fptr->common.required_num_args; + for (i = 0; i < fptr->common.num_args;) { + if (arg_info->class_name) { + memcpy(offset, arg_info->class_name, arg_info->class_name_len); + offset += arg_info->class_name_len; + *(offset++) = ' '; + } else if (arg_info->type_hint) { + zend_uint type_name_len; + char *type_name = zend_get_type_by_const(arg_info->type_hint); + type_name_len = strlen(type_name); + memcpy(offset, type_name, type_name_len); + offset += type_name_len; + *(offset++) = ' '; + } + + if (arg_info->pass_by_reference) { + *(offset++) = '&'; + } + + *(offset++) = '$'; + if (arg_info->name) { + memcpy(offset, arg_info->name, arg_info->name_len); + offset += arg_info->name_len; + } else { + zend_uint idx = i; + memcpy(offset, "param", 5); + offset += 5; + do { + *(offset++) = (char) (idx % 10) + '0'; + idx /= 10; + } while (idx > 0); + } + if (i >= required) { + *(offset++) = ' '; + *(offset++) = '='; + *(offset++) = ' '; + if (fptr->type == ZEND_USER_FUNCTION) { + zend_op *precv = NULL; + { + zend_uint idx = i; + zend_op *op = ((zend_op_array *)fptr)->opcodes; + zend_op *end = op + ((zend_op_array *)fptr)->last; + + ++idx; + while (op < end) { + if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT) + && op->op1.num == (long)idx) + { + precv = op; + } + ++op; + } + } + if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) { + zval *zv, zv_copy; + int use_copy; + ALLOC_ZVAL(zv); + *zv = *precv->op2.zv; + zval_copy_ctor(zv); + INIT_PZVAL(zv); + zval_update_constant_ex(&zv, (void*)1, fptr->common.scope TSRMLS_CC); + if (Z_TYPE_P(zv) == IS_BOOL) { + if (Z_LVAL_P(zv)) { + memcpy(offset, "true", 4); + offset += 4; + } else { + memcpy(offset, "false", 5); + offset += 5; + } + } else if (Z_TYPE_P(zv) == IS_NULL) { + memcpy(offset, "NULL", 4); + offset += 4; + } else if (Z_TYPE_P(zv) == IS_STRING) { + *(offset++) = '\''; + memcpy(offset, Z_STRVAL_P(zv), MIN(Z_STRLEN_P(zv), 10)); + offset += MIN(Z_STRLEN_P(zv), 10); + if (Z_STRLEN_P(zv) > 10) { + *(offset++) = '.'; + *(offset++) = '.'; + *(offset++) = '.'; + } + *(offset++) = '\''; + } else { + zend_make_printable_zval(zv, &zv_copy, &use_copy); + memcpy(offset, Z_STRVAL_P(zv), Z_STRLEN_P(zv)); + offset += Z_STRLEN_P(zv); + if (use_copy) { + zval_dtor(&zv_copy); + } + } + zval_ptr_dtor(&zv); + } + } else { + memcpy(offset, "NULL", 4); + offset += 4; + } + } + + if (++i < fptr->common.num_args) { + *(offset++) = ','; + *(offset++) = ' '; + } + arg_info++; + } + *(offset++) = ')'; + } + *offset = '\0'; + + return buf; +} +/* }}} */ + static void do_inheritance_check_on_method(zend_function *child, zend_function *parent TSRMLS_DC) { zend_uint child_flags; @@ -3069,11 +3208,13 @@ if (child->common.prototype && (child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT)) { if (!zend_do_perform_implementation_check(child, child->common.prototype TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Declaration of %s::%s() must be compatible with that of %s::%s()", ZEND_FN_SCOPE_NAME(child), child->common.function_name, ZEND_FN_SCOPE_NAME(child->common.prototype), child->common.prototype->common.function_name); + zend_error(E_ERROR, "Declaration of %s::%s() should be compatible with %s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, zend_get_function_declaration(child->common.prototype TSRMLS_CC)); } } else if (EG(error_reporting) & E_STRICT || EG(user_error_handler)) { /* Check E_STRICT (or custom error handler) before the check so that we save some time */ if (!zend_do_perform_implementation_check(child, parent TSRMLS_CC)) { - zend_error(E_STRICT, "Declaration of %s::%s() should be compatible with that of %s::%s()", ZEND_FN_SCOPE_NAME(child), child->common.function_name, ZEND_FN_SCOPE_NAME(parent), parent->common.function_name); + char *method_prototype = zend_get_function_declaration(child->common.prototype TSRMLS_CC); + zend_error(E_STRICT, "Declaration of %s::%s() should be compatible with %s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, method_prototype); + efree(method_prototype); } } } |
Copyright © 2001-2024 The PHP Group All rights reserved. |
Last updated: Sun Dec 08 03:01:28 2024 UTC |