From: Nikita Popov Date: Tue, 8 Oct 2019 15:34:25 +0000 (+0200) Subject: Merge branch 'PHP-7.4' X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a32f130f9420a876381b7f9042855dad9445bbef;p=php Merge branch 'PHP-7.4' --- a32f130f9420a876381b7f9042855dad9445bbef diff --cc Zend/zend_compile.c index b169093de5,ce37710dd0..57ec932310 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@@ -5482,18 -5413,80 +5478,24 @@@ void zend_compile_params(zend_ast *ast zend_error_noreturn(E_COMPILE_ERROR, "void cannot be used as a parameter type"); } - if (type_ast->kind == ZEND_AST_TYPE) { - if (ZEND_TYPE_CODE(arg_info->type) == IS_ARRAY) { - if (default_ast && !has_null_default - && Z_TYPE(default_node.u.constant) != IS_ARRAY - && Z_TYPE(default_node.u.constant) != IS_CONSTANT_AST - ) { - zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters " - "with array type can only be an array or NULL"); - } - } else if (ZEND_TYPE_CODE(arg_info->type) == IS_CALLABLE && default_ast) { - if (!has_null_default && Z_TYPE(default_node.u.constant) != IS_CONSTANT_AST) { - zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters " - "with callable type can only be NULL"); - } - } - } else { - if (default_ast && !has_null_default && Z_TYPE(default_node.u.constant) != IS_CONSTANT_AST) { - if (ZEND_TYPE_IS_CLASS(arg_info->type)) { - zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters " - "with a class type can only be NULL"); - } else switch (ZEND_TYPE_CODE(arg_info->type)) { - case IS_DOUBLE: - if (Z_TYPE(default_node.u.constant) != IS_DOUBLE && Z_TYPE(default_node.u.constant) != IS_LONG) { - zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters " - "with a float type can only be float, integer, or NULL"); - } - convert_to_double(&default_node.u.constant); - break; - - case IS_ITERABLE: - if (Z_TYPE(default_node.u.constant) != IS_ARRAY) { - zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters " - "with iterable type can only be an array or NULL"); - } - break; - - case IS_OBJECT: - zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters " - "with an object type can only be NULL"); - break; - - default: - if (!ZEND_SAME_FAKE_TYPE(ZEND_TYPE_CODE(arg_info->type), Z_TYPE(default_node.u.constant))) { - zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters " - "with a %s type can only be %s or NULL", - zend_get_type_by_const(ZEND_TYPE_CODE(arg_info->type)), zend_get_type_by_const(ZEND_TYPE_CODE(arg_info->type))); - } - break; - } - } + if (default_type > IS_NULL && default_type != IS_CONSTANT_AST + && !zend_is_valid_default_value(arg_info->type, &default_node.u.constant)) { + zend_string *type_str = zend_type_to_string(arg_info->type); + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot use %s as default value for parameter $%s of type %s", + zend_get_type_by_const(default_type), + ZSTR_VAL(name), ZSTR_VAL(type_str)); } + } + opline = zend_emit_op(NULL, opcode, NULL, &default_node); + SET_NODE(opline->result, &var_node); + opline->op1.num = i + 1; + + if (type_ast) { /* Allocate cache slot to speed-up run-time class resolution */ - if (is_class) { - if (opline->opcode == ZEND_RECV_INIT) { - if (ZEND_TYPE_IS_CLASS(arg_info->type)) { - opline->extended_value = zend_alloc_cache_slot(); - } - } else { - if (ZEND_TYPE_IS_CLASS(arg_info->type)) { - opline->op2.num = op_array->cache_size; - op_array->cache_size += sizeof(void*); - } else { - opline->op2.num = -1; - } - } - } else { - if (opline->opcode != ZEND_RECV_INIT) { - opline->op2.num = -1; ++ if (ZEND_TYPE_IS_CLASS(arg_info->type)) { + opline->extended_value = zend_alloc_cache_slot(); } } } diff --cc Zend/zend_vm_def.h index b1927d280c,0c1ab106b3..b2ea3fefd5 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@@ -5117,12 -5252,15 +5118,13 @@@ ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT } else { ZVAL_COPY(param, default_value); } - } - - if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { - SAVE_OPLINE(); - if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, CACHE_ADDR(opline->extended_value)))) { - HANDLE_EXCEPTION(); + } else { + ZEND_VM_C_LABEL(recv_init_check_type): + if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { - zval *default_value = RT_CONSTANT(opline, opline->op2); - + SAVE_OPLINE(); - if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(opline->extended_value)))) { ++ if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, CACHE_ADDR(opline->extended_value)))) { + HANDLE_EXCEPTION(); + } } } diff --cc Zend/zend_vm_execute.h index 3e01ae36b3,f1b46fbd97..ffd3ede581 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@@ -2973,12 -3055,15 +2974,13 @@@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_ } else { ZVAL_COPY(param, default_value); } - } - - if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { - SAVE_OPLINE(); - if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, CACHE_ADDR(opline->extended_value)))) { - HANDLE_EXCEPTION(); + } else { + recv_init_check_type: + if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { - zval *default_value = RT_CONSTANT(opline, opline->op2); - + SAVE_OPLINE(); - if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(opline->extended_value)))) { ++ if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, CACHE_ADDR(opline->extended_value)))) { + HANDLE_EXCEPTION(); + } } }