mirror of
https://github.com/php/php-src.git
synced 2025-01-26 21:54:16 +08:00
Fixed bug #42802 (Namespace not supported in typehints)
This commit is contained in:
parent
3a3a7e7441
commit
41e9b6b61c
1
NEWS
1
NEWS
@ -32,6 +32,7 @@ PHP NEWS
|
||||
- Improved and cleaned CGI code. FastCGI is now always enabled and can not be
|
||||
disabled. See sapi/cgi/CHANGES for more details. (Dmitry)
|
||||
|
||||
- Fixed bug #42802 (Namespace not supported in typehints). (Dmitry)
|
||||
- Fixed bug #42798 (__autoload() not triggered for classes used in method
|
||||
signature). (Dmitry)
|
||||
- Fixed bug #42657 (ini_get() returns incorrect value when default is NULL).
|
||||
|
45
Zend/tests/bug42802.phpt
Executable file
45
Zend/tests/bug42802.phpt
Executable file
@ -0,0 +1,45 @@
|
||||
--TEST--
|
||||
Bug #42802 (Namespace not supported in typehints)
|
||||
--FILE--
|
||||
<?php
|
||||
namespace foo;
|
||||
|
||||
class bar {
|
||||
}
|
||||
|
||||
function test1(bar $bar) {
|
||||
echo "ok\n";
|
||||
}
|
||||
|
||||
function test2(foo::bar $bar) {
|
||||
echo "ok\n";
|
||||
}
|
||||
function test3(::foo::bar $bar) {
|
||||
echo "ok\n";
|
||||
}
|
||||
function test4(::Exception $e) {
|
||||
echo "ok\n";
|
||||
}
|
||||
function test5(Exception $e) {
|
||||
echo "ok\n";
|
||||
}
|
||||
function test6(::bar $bar) {
|
||||
echo "bug\n";
|
||||
}
|
||||
|
||||
$x = new bar();
|
||||
$y = new Exception();
|
||||
test1($x);
|
||||
test2($x);
|
||||
test3($x);
|
||||
test4($y);
|
||||
test5($y);
|
||||
test6($x);
|
||||
--EXPECTF--
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
|
||||
Catchable fatal error: Argument 1 passed to foo::test6() must be an instance of bar, instance of foo::bar given, called in %sbug42802.php on line 23
|
@ -34,6 +34,7 @@
|
||||
ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
|
||||
ZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, char *filename TSRMLS_DC);
|
||||
|
||||
void zend_resolve_class_name(znode *class_name, ulong *fetch_type, int check_ns_name TSRMLS_DC);
|
||||
|
||||
#ifndef ZTS
|
||||
ZEND_API zend_compiler_globals compiler_globals;
|
||||
@ -1318,6 +1319,7 @@ void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initia
|
||||
if (class_type->op_type != IS_UNUSED) {
|
||||
cur_arg_info->allow_null = 0;
|
||||
if (class_type->u.constant.type == IS_STRING) {
|
||||
zend_resolve_class_name(class_type, &opline->extended_value, 1 TSRMLS_CC);
|
||||
cur_arg_info->class_name = class_type->u.constant.value.str.val;
|
||||
cur_arg_info->class_name_len = class_type->u.constant.value.str.len;
|
||||
if (op == ZEND_RECV_INIT) {
|
||||
|
@ -456,9 +456,9 @@ static inline void make_real_object(zval **object_ptr TSRMLS_DC)
|
||||
}
|
||||
}
|
||||
|
||||
static inline char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, const char **class_name, zend_class_entry **pce TSRMLS_DC)
|
||||
static inline char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC)
|
||||
{
|
||||
*pce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
|
||||
*pce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
|
||||
|
||||
*class_name = (*pce) ? (*pce)->name: cur_arg_info->class_name;
|
||||
if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
|
||||
@ -491,7 +491,7 @@ static inline int zend_verify_arg_error(zend_function *zf, zend_uint arg_num, co
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg TSRMLS_DC)
|
||||
static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg, ulong fetch_type TSRMLS_DC)
|
||||
{
|
||||
zend_arg_info *cur_arg_info;
|
||||
char *need_msg;
|
||||
@ -508,16 +508,16 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva
|
||||
const char *class_name;
|
||||
|
||||
if (!arg) {
|
||||
need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC);
|
||||
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
|
||||
return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "none", "" TSRMLS_CC);
|
||||
}
|
||||
if (Z_TYPE_P(arg) == IS_OBJECT) {
|
||||
need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC);
|
||||
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
|
||||
if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
|
||||
return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC);
|
||||
}
|
||||
} else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {
|
||||
need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC);
|
||||
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
|
||||
return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC);
|
||||
}
|
||||
} else if (cur_arg_info->array_type_hint) {
|
||||
|
@ -450,9 +450,9 @@ non_empty_parameter_list:
|
||||
|
||||
|
||||
optional_class_type:
|
||||
/* empty */ { $$.op_type = IS_UNUSED; }
|
||||
| T_STRING { $$ = $1; }
|
||||
| T_ARRAY { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_NULL;}
|
||||
/* empty */ { $$.op_type = IS_UNUSED; }
|
||||
| fully_qualified_class_name { $$ = $1; }
|
||||
| T_ARRAY { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_NULL;}
|
||||
;
|
||||
|
||||
|
||||
|
@ -1950,7 +1950,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
|
||||
arg_count = (ulong)(zend_uintptr_t) *p;
|
||||
|
||||
while (arg_count>0) {
|
||||
zend_verify_arg_type(EX(function_state).function, ++i, *(p-arg_count) TSRMLS_CC);
|
||||
zend_verify_arg_type(EX(function_state).function, ++i, *(p-arg_count), 0 TSRMLS_CC);
|
||||
arg_count--;
|
||||
}
|
||||
}
|
||||
@ -2381,7 +2381,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
|
||||
char *class_name = get_active_class_name(&space TSRMLS_CC);
|
||||
zend_execute_data *ptr = EX(prev_execute_data);
|
||||
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, opline->extended_value TSRMLS_CC);
|
||||
if(ptr && ptr->op_array) {
|
||||
zend_error(E_WARNING, "Missing argument %ld for %s%s%s(), called in %s on line %d and defined", opline->op1.u.constant.value.lval, class_name, space, get_active_function_name(TSRMLS_C), ptr->op_array->filename, ptr->opline->lineno);
|
||||
} else {
|
||||
@ -2394,7 +2394,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
|
||||
zend_free_op free_res;
|
||||
zval **var_ptr;
|
||||
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
|
||||
var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
|
||||
if (PZVAL_IS_REF(*param)) {
|
||||
zend_assign_to_variable_reference(var_ptr, param TSRMLS_CC);
|
||||
@ -2432,13 +2432,13 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
|
||||
param = NULL;
|
||||
assignment_value = &opline->op2.u.constant;
|
||||
}
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
|
||||
zend_assign_to_variable(NULL, &opline->result, NULL, assignment_value, IS_VAR, EX(Ts) TSRMLS_CC);
|
||||
} else {
|
||||
zval **var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
|
||||
|
||||
assignment_value = *param;
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
|
||||
if (PZVAL_IS_REF(assignment_value)) {
|
||||
zend_assign_to_variable_reference(var_ptr, param TSRMLS_CC);
|
||||
} else {
|
||||
|
@ -184,7 +184,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
|
||||
arg_count = (ulong)(zend_uintptr_t) *p;
|
||||
|
||||
while (arg_count>0) {
|
||||
zend_verify_arg_type(EX(function_state).function, ++i, *(p-arg_count) TSRMLS_CC);
|
||||
zend_verify_arg_type(EX(function_state).function, ++i, *(p-arg_count), 0 TSRMLS_CC);
|
||||
arg_count--;
|
||||
}
|
||||
}
|
||||
@ -358,7 +358,7 @@ static int ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
char *class_name = get_active_class_name(&space TSRMLS_CC);
|
||||
zend_execute_data *ptr = EX(prev_execute_data);
|
||||
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, opline->extended_value TSRMLS_CC);
|
||||
if(ptr && ptr->op_array) {
|
||||
zend_error(E_WARNING, "Missing argument %ld for %s%s%s(), called in %s on line %d and defined", opline->op1.u.constant.value.lval, class_name, space, get_active_function_name(TSRMLS_C), ptr->op_array->filename, ptr->opline->lineno);
|
||||
} else {
|
||||
@ -371,7 +371,7 @@ static int ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
zend_free_op free_res;
|
||||
zval **var_ptr;
|
||||
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
|
||||
var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
|
||||
if (PZVAL_IS_REF(*param)) {
|
||||
zend_assign_to_variable_reference(var_ptr, param TSRMLS_CC);
|
||||
@ -742,13 +742,13 @@ static int ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
param = NULL;
|
||||
assignment_value = &opline->op2.u.constant;
|
||||
}
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
|
||||
zend_assign_to_variable(NULL, &opline->result, NULL, assignment_value, IS_VAR, EX(Ts) TSRMLS_CC);
|
||||
} else {
|
||||
zval **var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
|
||||
|
||||
assignment_value = *param;
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
|
||||
if (PZVAL_IS_REF(assignment_value)) {
|
||||
zend_assign_to_variable_reference(var_ptr, param TSRMLS_CC);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user