From 99c623f00312fb9364e0e722bc9e25e15199d447 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sat, 14 Sep 2024 01:12:59 +0200 Subject: [PATCH 1/9] Implement erased types --- Zend/tests/erased_types/parameter_types.phpt | 16 ++++++++ Zend/tests/erased_types/property_types.phpt | 21 ++++++++++ Zend/tests/erased_types/return_types.phpt | 16 ++++++++ Zend/zend.c | 1 + Zend/zend_compile.c | 43 ++++++++++++++++++-- Zend/zend_globals.h | 6 +++ Zend/zend_object_handlers.c | 2 +- Zend/zend_types.h | 8 +++- 8 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 Zend/tests/erased_types/parameter_types.phpt create mode 100644 Zend/tests/erased_types/property_types.phpt create mode 100644 Zend/tests/erased_types/return_types.phpt diff --git a/Zend/tests/erased_types/parameter_types.phpt b/Zend/tests/erased_types/parameter_types.phpt new file mode 100644 index 0000000000000..07e5ae6a2b3cb --- /dev/null +++ b/Zend/tests/erased_types/parameter_types.phpt @@ -0,0 +1,16 @@ +--TEST-- +Erased types: Parameter types +--FILE-- + +--EXPECT-- +int(42) diff --git a/Zend/tests/erased_types/property_types.phpt b/Zend/tests/erased_types/property_types.phpt new file mode 100644 index 0000000000000..03707cd644f70 --- /dev/null +++ b/Zend/tests/erased_types/property_types.phpt @@ -0,0 +1,21 @@ +--TEST-- +Erased types: Property types +--FILE-- +prop = 42; +var_dump($c); + +?> +--EXPECTF-- +object(C)#%d (1) { + ["prop"]=> + int(42) +} diff --git a/Zend/tests/erased_types/return_types.phpt b/Zend/tests/erased_types/return_types.phpt new file mode 100644 index 0000000000000..6c30f0734d752 --- /dev/null +++ b/Zend/tests/erased_types/return_types.phpt @@ -0,0 +1,16 @@ +--TEST-- +Erased types: Return types +--FILE-- + +--EXPECT-- +int(42) diff --git a/Zend/zend.c b/Zend/zend.c index b4fd4fd269c8a..a7ae75791f514 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -731,6 +731,7 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{ compiler_globals->script_encoding_list = NULL; compiler_globals->current_linking_class = NULL; + compiler_globals->types_mode = ZEND_TYPES_MODE_CHECKED; /* Map region is going to be created and resized at run-time. */ compiler_globals->map_ptr_real_base = NULL; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 99938df0c8f09..7178ace904454 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2697,6 +2697,10 @@ static void zend_emit_return_type_check( return; } + if (CG(types_mode) == ZEND_TYPES_MODE_ERASED) { + return; + } + if (expr && expr->op_type == IS_CONST && ZEND_TYPE_CONTAINS_CODE(type, Z_TYPE(expr->u.constant))) { /* we don't need run-time check */ return; @@ -6900,7 +6904,34 @@ static void zend_compile_declare(zend_ast *ast) /* {{{ */ if (Z_LVAL(value_zv) == 1) { CG(active_op_array)->fn_flags |= ZEND_ACC_STRICT_TYPES; } + } else if (zend_string_equals_literal_ci(name, "types")) { + if (FAILURE == zend_is_first_statement(ast, /* allow_nop */ 0)) { + zend_error_noreturn(E_COMPILE_ERROR, + "types declaration pragma must be the very first statement in the script"); + } + + zval value_zv; + if (ast->child[1] != NULL) { + zend_error_noreturn(E_COMPILE_ERROR, + "types declaration must not use block mode"); + } + zend_const_expr_to_zval(&value_zv, value_ast_ptr, /* allow_dynamic */ false); + + if (Z_TYPE(value_zv) != IS_STRING) { +types_decl_value_error: + zend_error_noreturn(E_COMPILE_ERROR, "types declaration must be a string with the value \"checked\" or \"erased\""); + } + + if (zend_string_equals_literal_ci(Z_STR(value_zv), "checked")) { + CG(types_mode) = ZEND_TYPES_MODE_CHECKED; + } else if (zend_string_equals_literal_ci(Z_STR(value_zv), "erased")) { + CG(types_mode) = ZEND_TYPES_MODE_ERASED; + } else { + goto types_decl_value_error; + } + + zval_ptr_dtor(&value_zv); } else { zend_error(E_COMPILE_WARNING, "Unsupported declare '%s'", ZSTR_VAL(name)); } @@ -7323,6 +7354,11 @@ static zend_type zend_compile_typename_ex( } ast->attr = orig_ast_attr; + + if (CG(types_mode) == ZEND_TYPES_MODE_ERASED) { + ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_ERASED_BIT; + } + return type; } /* }}} */ @@ -7718,7 +7754,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 SET_NODE(opline->result, &var_node); opline->op1.num = i + 1; - if (type_ast) { + if (type_ast && CG(types_mode) == ZEND_TYPES_MODE_CHECKED) { /* Allocate cache slot to speed-up run-time class resolution */ opline->extended_value = zend_alloc_cache_slots(zend_type_get_num_classes(arg_info->type)); @@ -7728,8 +7764,9 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 | (is_promoted ? _ZEND_IS_PROMOTED_BIT : 0); ZEND_TYPE_FULL_MASK(arg_info->type) |= arg_info_flags; if (opcode == ZEND_RECV) { - opline->op2.num = type_ast ? - ZEND_TYPE_FULL_MASK(arg_info->type) : MAY_BE_ANY; + opline->op2.num = type_ast && CG(types_mode) == ZEND_TYPES_MODE_CHECKED + ? ZEND_TYPE_FULL_MASK(arg_info->type) + : MAY_BE_ANY; } if (is_promoted) { diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 62a97d753634a..0845a6201c015 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -81,6 +81,11 @@ typedef enum { ZEND_MEMOIZE_FETCH, } zend_memoize_mode; +typedef enum { + ZEND_TYPES_MODE_CHECKED = 0, + ZEND_TYPES_MODE_ERASED, +} zend_types_mode; + struct _zend_compiler_globals { zend_stack loop_var_stack; @@ -161,6 +166,7 @@ struct _zend_compiler_globals { #ifdef ZTS uint32_t copied_functions_count; #endif + zend_types_mode types_mode; }; diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 106ce27830283..ccc301912eade 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -434,7 +434,7 @@ static zend_always_inline uintptr_t zend_get_property_offset(zend_class_entry *c } offset = property_info->offset; - if (EXPECTED(!ZEND_TYPE_IS_SET(property_info->type))) { + if (!ZEND_TYPE_IS_SET(property_info->type) || ZEND_TYPE_IS_ERASED(property_info->type)) { property_info = NULL; } else { *info_ptr = property_info; diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 8f012868ddab4..fa29d072d0df6 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -142,8 +142,9 @@ typedef struct { zend_type types[1]; } zend_type_list; -#define _ZEND_TYPE_EXTRA_FLAGS_SHIFT 25 -#define _ZEND_TYPE_MASK ((1u << 25) - 1) +#define _ZEND_TYPE_EXTRA_FLAGS_SHIFT 26 +#define _ZEND_TYPE_MASK ((1u << 26) - 1) +#define _ZEND_TYPE_ERASED_BIT (1u << 25) /* Only one of these bits may be set. */ #define _ZEND_TYPE_NAME_BIT (1u << 24) // Used to signify that type.ptr is not a `zend_string*` but a `const char*`, @@ -166,6 +167,9 @@ typedef struct { #define ZEND_TYPE_IS_SET(t) \ (((t).type_mask & _ZEND_TYPE_MASK) != 0) +#define ZEND_TYPE_IS_ERASED(t) \ + ((((t).type_mask) & _ZEND_TYPE_ERASED_BIT) != 0) + /* If a type is complex it means it's either a list with a union or intersection, * or the void pointer is a class name */ #define ZEND_TYPE_IS_COMPLEX(t) \ From b2c56571c1723882477d35bdaec18c2e0293eded Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Fri, 20 Sep 2024 23:07:02 +0200 Subject: [PATCH 2/9] Treat erased as mixed in inherence --- Zend/Optimizer/zend_inference.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index e457c24b18aa2..3224aeb28894f 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -2370,7 +2370,7 @@ static uint32_t zend_convert_type(const zend_script *script, zend_type type, zen *pce = NULL; } - if (!ZEND_TYPE_IS_SET(type)) { + if (!ZEND_TYPE_IS_SET(type) || ZEND_TYPE_IS_ERASED(type)) { return MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF|MAY_BE_RC1|MAY_BE_RCN; } From d2942f0e93dfb10b8e846115b730aa4e3aa25671 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Fri, 20 Sep 2024 23:09:26 +0200 Subject: [PATCH 3/9] Fix erasure for RECV_INIT --- Zend/tests/erased_types/parameter_types.phpt | 7 ++++--- Zend/zend_execute.c | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Zend/tests/erased_types/parameter_types.phpt b/Zend/tests/erased_types/parameter_types.phpt index 07e5ae6a2b3cb..d920a26dcabea 100644 --- a/Zend/tests/erased_types/parameter_types.phpt +++ b/Zend/tests/erased_types/parameter_types.phpt @@ -5,12 +5,13 @@ Erased types: Parameter types declare(types='erased'); -function test(string $value) { - var_dump($value); +function test(string $p1, string $p2 = 'p2') { + var_dump($p1, $p2); } -test(42); +test(42, 43); ?> --EXPECT-- int(42) +int(43) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index a0eacb14dcf4c..ee063da191edc 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1260,6 +1260,8 @@ static zend_always_inline bool zend_verify_recv_arg_type(zend_function *zf, uint cur_arg_info = &zf->common.arg_info[arg_num-1]; if (ZEND_TYPE_IS_SET(cur_arg_info->type) + // FIXME: We could potentially avoid two checks by marking mixed as erased + && !ZEND_TYPE_IS_ERASED(cur_arg_info->type) && UNEXPECTED(!zend_check_type(&cur_arg_info->type, arg, cache_slot, zf->common.scope, 0, 0))) { zend_verify_arg_error(zf, cur_arg_info, arg_num, arg); return 0; From 93bd9e40749e18cb8cb3c0e9e172ae57230f21e7 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sat, 21 Sep 2024 03:11:30 +0200 Subject: [PATCH 4/9] Switch to positive type flag (erased to checked) This has a few upsides: * Zeroed types behave as expected, namely no type is never checked. The checked flag must only be set on types with some pure type mask. * We can simplify the type check test, i.e. if the checked flag is set, the type must be checked. --- Zend/Optimizer/zend_inference.c | 2 +- Zend/tests/erased_types/typed_references.phpt | 23 +++++++++++++++++++ Zend/zend_compile.c | 13 +++++++---- Zend/zend_execute.c | 4 +--- Zend/zend_object_handlers.c | 2 +- Zend/zend_objects.c | 2 +- Zend/zend_types.h | 18 +++++++-------- 7 files changed, 44 insertions(+), 20 deletions(-) create mode 100644 Zend/tests/erased_types/typed_references.phpt diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 3224aeb28894f..04cb753cb96f1 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -2370,7 +2370,7 @@ static uint32_t zend_convert_type(const zend_script *script, zend_type type, zen *pce = NULL; } - if (!ZEND_TYPE_IS_SET(type) || ZEND_TYPE_IS_ERASED(type)) { + if (!ZEND_TYPE_IS_CHECKED(type)) { return MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF|MAY_BE_RC1|MAY_BE_RCN; } diff --git a/Zend/tests/erased_types/typed_references.phpt b/Zend/tests/erased_types/typed_references.phpt new file mode 100644 index 0000000000000..101f865211486 --- /dev/null +++ b/Zend/tests/erased_types/typed_references.phpt @@ -0,0 +1,23 @@ +--TEST-- +Erased types: Typed references +--FILE-- +prop = 'foo'; +$ref = &$c->prop; +$ref = 42; +var_dump($c); + +?> +--EXPECTF-- +object(C)#%d (1) { + ["prop"]=> + &int(42) +} diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 7178ace904454..481eae365d873 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7355,8 +7355,11 @@ static zend_type zend_compile_typename_ex( ast->attr = orig_ast_attr; - if (CG(types_mode) == ZEND_TYPES_MODE_ERASED) { - ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_ERASED_BIT; + // FIXME: Also add the flag to list element types. + if (CG(types_mode) == ZEND_TYPES_MODE_CHECKED && ZEND_TYPE_PURE_MASK(type) != 0) { + ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_CHECKED_BIT; + } else { + ZEND_TYPE_FULL_MASK(type) &= ~_ZEND_TYPE_CHECKED_BIT; } return type; @@ -7754,7 +7757,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 SET_NODE(opline->result, &var_node); opline->op1.num = i + 1; - if (type_ast && CG(types_mode) == ZEND_TYPES_MODE_CHECKED) { + if (type_ast && ZEND_TYPE_IS_CHECKED(arg_info->type)) { /* Allocate cache slot to speed-up run-time class resolution */ opline->extended_value = zend_alloc_cache_slots(zend_type_get_num_classes(arg_info->type)); @@ -7764,8 +7767,8 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 | (is_promoted ? _ZEND_IS_PROMOTED_BIT : 0); ZEND_TYPE_FULL_MASK(arg_info->type) |= arg_info_flags; if (opcode == ZEND_RECV) { - opline->op2.num = type_ast && CG(types_mode) == ZEND_TYPES_MODE_CHECKED - ? ZEND_TYPE_FULL_MASK(arg_info->type) + opline->op2.num = type_ast && ZEND_TYPE_IS_CHECKED(arg_info->type) + ? ZEND_TYPE_PURE_MASK(arg_info->type) : MAY_BE_ANY; } diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index ee063da191edc..f6d471a93070c 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1259,9 +1259,7 @@ static zend_always_inline bool zend_verify_recv_arg_type(zend_function *zf, uint ZEND_ASSERT(arg_num <= zf->common.num_args); cur_arg_info = &zf->common.arg_info[arg_num-1]; - if (ZEND_TYPE_IS_SET(cur_arg_info->type) - // FIXME: We could potentially avoid two checks by marking mixed as erased - && !ZEND_TYPE_IS_ERASED(cur_arg_info->type) + if (ZEND_TYPE_IS_CHECKED(cur_arg_info->type) && UNEXPECTED(!zend_check_type(&cur_arg_info->type, arg, cache_slot, zf->common.scope, 0, 0))) { zend_verify_arg_error(zf, cur_arg_info, arg_num, arg); return 0; diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index ccc301912eade..9fc87237350ab 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -434,7 +434,7 @@ static zend_always_inline uintptr_t zend_get_property_offset(zend_class_entry *c } offset = property_info->offset; - if (!ZEND_TYPE_IS_SET(property_info->type) || ZEND_TYPE_IS_ERASED(property_info->type)) { + if (!ZEND_TYPE_IS_CHECKED(property_info->type)) { property_info = NULL; } else { *info_ptr = property_info; diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index fd0e97c5f4131..21a8905ac3358 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -66,7 +66,7 @@ void zend_object_dtor_property(zend_object *object, zval *p) if (UNEXPECTED(Z_ISREF_P(p)) && (ZEND_DEBUG || ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(p)))) { zend_property_info *prop_info = zend_get_property_info_for_slot_self(object, p); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZEND_REF_DEL_TYPE_SOURCE(Z_REF_P(p), prop_info); } } diff --git a/Zend/zend_types.h b/Zend/zend_types.h index fa29d072d0df6..21f5551a43be6 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -144,7 +144,7 @@ typedef struct { #define _ZEND_TYPE_EXTRA_FLAGS_SHIFT 26 #define _ZEND_TYPE_MASK ((1u << 26) - 1) -#define _ZEND_TYPE_ERASED_BIT (1u << 25) +#define _ZEND_TYPE_CHECKED_BIT (1u << 25) /* Only one of these bits may be set. */ #define _ZEND_TYPE_NAME_BIT (1u << 24) // Used to signify that type.ptr is not a `zend_string*` but a `const char*`, @@ -167,8 +167,8 @@ typedef struct { #define ZEND_TYPE_IS_SET(t) \ (((t).type_mask & _ZEND_TYPE_MASK) != 0) -#define ZEND_TYPE_IS_ERASED(t) \ - ((((t).type_mask) & _ZEND_TYPE_ERASED_BIT) != 0) +#define ZEND_TYPE_IS_CHECKED(t) \ + ((((t).type_mask) & _ZEND_TYPE_CHECKED_BIT) != 0) /* If a type is complex it means it's either a list with a union or intersection, * or the void pointer is a class name */ @@ -285,24 +285,24 @@ typedef struct { _ZEND_TYPE_PREFIX { NULL, (extra_flags) } #define ZEND_TYPE_INIT_MASK(_type_mask) \ - _ZEND_TYPE_PREFIX { NULL, (_type_mask) } + _ZEND_TYPE_PREFIX { NULL, (_type_mask) | _ZEND_TYPE_CHECKED_BIT } #define ZEND_TYPE_INIT_CODE(code, allow_null, extra_flags) \ ZEND_TYPE_INIT_MASK(((code) == _IS_BOOL ? MAY_BE_BOOL : ( (code) == IS_ITERABLE ? _ZEND_TYPE_ITERABLE_BIT : ((code) == IS_MIXED ? MAY_BE_ANY : (1 << (code))))) \ - | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : 0) | (extra_flags)) + | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : 0) | (extra_flags) | _ZEND_TYPE_CHECKED_BIT) #define ZEND_TYPE_INIT_PTR(ptr, type_kind, allow_null, extra_flags) \ _ZEND_TYPE_PREFIX { (void *) (ptr), \ - (type_kind) | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : 0) | (extra_flags) } + (type_kind) | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : 0) | (extra_flags) | _ZEND_TYPE_CHECKED_BIT } #define ZEND_TYPE_INIT_PTR_MASK(ptr, type_mask) \ - _ZEND_TYPE_PREFIX { (void *) (ptr), (type_mask) } + _ZEND_TYPE_PREFIX { (void *) (ptr), (type_mask) | _ZEND_TYPE_CHECKED_BIT } #define ZEND_TYPE_INIT_UNION(ptr, extra_flags) \ - _ZEND_TYPE_PREFIX { (void *) (ptr), (_ZEND_TYPE_LIST_BIT|_ZEND_TYPE_UNION_BIT) | (extra_flags) } + _ZEND_TYPE_PREFIX { (void *) (ptr), (_ZEND_TYPE_LIST_BIT|_ZEND_TYPE_UNION_BIT) | (extra_flags) | _ZEND_TYPE_CHECKED_BIT } #define ZEND_TYPE_INIT_INTERSECTION(ptr, extra_flags) \ - _ZEND_TYPE_PREFIX { (void *) (ptr), (_ZEND_TYPE_LIST_BIT|_ZEND_TYPE_INTERSECTION_BIT) | (extra_flags) } + _ZEND_TYPE_PREFIX { (void *) (ptr), (_ZEND_TYPE_LIST_BIT|_ZEND_TYPE_INTERSECTION_BIT) | (extra_flags) | _ZEND_TYPE_CHECKED_BIT } #define ZEND_TYPE_INIT_CLASS(class_name, allow_null, extra_flags) \ ZEND_TYPE_INIT_PTR(class_name, _ZEND_TYPE_NAME_BIT, allow_null, extra_flags) From 9c330e4cd89b4a83c743f2faf13866380f1ebf71 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sat, 21 Sep 2024 03:15:41 +0200 Subject: [PATCH 5/9] Implement static variable erasure Along with other changes in the VM. Those will all need tests. --- .../erased_types/static_parameter_types.phpt | 17 +++ Zend/zend_vm_def.h | 20 +-- Zend/zend_vm_execute.h | 118 +++++++++--------- 3 files changed, 86 insertions(+), 69 deletions(-) create mode 100644 Zend/tests/erased_types/static_parameter_types.phpt diff --git a/Zend/tests/erased_types/static_parameter_types.phpt b/Zend/tests/erased_types/static_parameter_types.phpt new file mode 100644 index 0000000000000..2ea72084dfaf9 --- /dev/null +++ b/Zend/tests/erased_types/static_parameter_types.phpt @@ -0,0 +1,17 @@ +--TEST-- +Erased types: Static property types +--FILE-- + +--EXPECT-- +int(42) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 55675e4a0b5c2..b04872c2d91ae 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1127,7 +1127,7 @@ ZEND_VM_HANDLER(29, ZEND_ASSIGN_STATIC_PROP_OP, ANY, ANY, OP) } } - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { /* special case for typed properties */ zend_binary_assign_op_typed_prop(prop_info, prop, value OPLINE_CC EXECUTE_DATA_CC); } else { @@ -1429,7 +1429,7 @@ ZEND_VM_HANDLER(38, ZEND_PRE_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT) } zend_pre_incdec_property_zval(prop, - ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC); + ZEND_TYPE_IS_CHECKED(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -1455,7 +1455,7 @@ ZEND_VM_HANDLER(40, ZEND_POST_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT) } zend_post_incdec_property_zval(prop, - ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC); + ZEND_TYPE_IS_CHECKED(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -2169,7 +2169,7 @@ ZEND_VM_C_LABEL(fetch_obj_r_fast_copy): retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); #if ZEND_DEBUG if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { + && ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_OPT_DEREF(retval); zend_verify_property_type(prop_info, retval, /* strict */ true); } @@ -2529,7 +2529,7 @@ ZEND_VM_C_LABEL(fast_assign_obj): if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); ZEND_VM_C_GOTO(free_and_exit_assign_obj); } else { @@ -2592,7 +2592,7 @@ ZEND_VM_HANDLER(25, ZEND_ASSIGN_STATIC_PROP, ANY, ANY, CACHE_SLOT, SPEC(OP_DATA= value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC); FREE_OP_DATA(); } else { @@ -2890,7 +2890,7 @@ ZEND_VM_HANDLER(33, ZEND_ASSIGN_STATIC_PROP_REF, ANY, ANY, CACHE_SLOT|SRC) if (UNEXPECTED(!zend_wrong_assign_to_variable_reference(prop, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC))) { prop = &EG(uninitialized_zval); } - } else if (ZEND_TYPE_IS_SET(prop_info->type)) { + } else if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { prop = zend_assign_to_typed_property_reference(prop_info, prop, value_ptr, &garbage EXECUTE_DATA_CC); } else { zend_assign_to_variable_reference(prop, value_ptr, &garbage); @@ -5705,7 +5705,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, UNUSED, CACHE_SLOT) zend_hash_real_init_packed(Z_ARRVAL_P(params)); ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) { zval *param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); - if (ZEND_TYPE_IS_SET(arg_info->type)) { + if (ZEND_TYPE_IS_CHECKED(arg_info->type)) { ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_FREE_EXTRA_ARGS); do { if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param, CACHE_ADDR(opline->extended_value)))) { @@ -5733,7 +5733,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, UNUSED, CACHE_SLOT) zend_string *name; zval *param; zend_arg_info *arg_info = &EX(func)->common.arg_info[EX(func)->common.num_args]; - if (ZEND_TYPE_IS_SET(arg_info->type)) { + if (ZEND_TYPE_IS_CHECKED(arg_info->type)) { SEPARATE_ARRAY(params); ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(EX(extra_named_params), name, param) { if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param, CACHE_ADDR(opline->extended_value)))) { @@ -7252,7 +7252,7 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_ADDR) UNDEF_RESULT(); HANDLE_EXCEPTION(); } - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_NEW_REF(value, value); ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(value), prop_info); value_type = IS_REFERENCE_EX; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 088c29cf408e8..79faa193ad139 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -794,7 +794,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_OP_SPEC_HAN } } - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { /* special case for typed properties */ zend_binary_assign_op_typed_prop(prop_info, prop, value OPLINE_CC EXECUTE_DATA_CC); } else { @@ -825,7 +825,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_STATIC_PROP_SPEC_HANDL } zend_pre_incdec_property_zval(prop, - ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC); + ZEND_TYPE_IS_CHECKED(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -845,7 +845,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_STATIC_PROP_SPEC_HAND } zend_post_incdec_property_zval(prop, - ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC); + ZEND_TYPE_IS_CHECKED(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -951,7 +951,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DAT value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC); } else { @@ -987,7 +987,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DAT value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } else { @@ -1023,7 +1023,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DAT value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } else { @@ -1059,7 +1059,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DAT value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC); } else { @@ -1099,7 +1099,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_REF_SPEC_HA if (UNEXPECTED(!zend_wrong_assign_to_variable_reference(prop, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC))) { prop = &EG(uninitialized_zval); } - } else if (ZEND_TYPE_IS_SET(prop_info->type)) { + } else if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { prop = zend_assign_to_typed_property_reference(prop_info, prop, value_ptr, &garbage EXECUTE_DATA_CC); } else { zend_assign_to_variable_reference(prop, value_ptr, &garbage); @@ -4198,7 +4198,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_UNUSED_HAND zend_hash_real_init_packed(Z_ARRVAL_P(params)); ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) { zval *param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); - if (ZEND_TYPE_IS_SET(arg_info->type)) { + if (ZEND_TYPE_IS_CHECKED(arg_info->type)) { ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_FREE_EXTRA_ARGS); do { if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param, CACHE_ADDR(opline->extended_value)))) { @@ -4226,7 +4226,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_UNUSED_HAND zend_string *name; zval *param; zend_arg_info *arg_info = &EX(func)->common.arg_info[EX(func)->common.num_args]; - if (ZEND_TYPE_IS_SET(arg_info->type)) { + if (ZEND_TYPE_IS_CHECKED(arg_info->type)) { SEPARATE_ARRAY(params); ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(EX(extra_named_params), name, param) { if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param, CACHE_ADDR(opline->extended_value)))) { @@ -6793,7 +6793,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_ retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); #if ZEND_DEBUG if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { + && ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_OPT_DEREF(retval); zend_verify_property_type(prop_info, retval, /* strict */ true); } @@ -9357,7 +9357,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_ retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); #if ZEND_DEBUG if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { + && ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_OPT_DEREF(retval); zend_verify_property_type(prop_info, retval, /* strict */ true); } @@ -11839,7 +11839,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_ retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); #if ZEND_DEBUG if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { + && ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_OPT_DEREF(retval); zend_verify_property_type(prop_info, retval, /* strict */ true); } @@ -16261,7 +16261,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_ retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); #if ZEND_DEBUG if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { + && ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_OPT_DEREF(retval); zend_verify_property_type(prop_info, retval, /* strict */ true); } @@ -17754,7 +17754,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); #if ZEND_DEBUG if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { + && ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_OPT_DEREF(retval); zend_verify_property_type(prop_info, retval, /* strict */ true); } @@ -19161,7 +19161,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HAN retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); #if ZEND_DEBUG if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { + && ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_OPT_DEREF(retval); zend_verify_property_type(prop_info, retval, /* strict */ true); } @@ -23082,7 +23082,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z UNDEF_RESULT(); HANDLE_EXCEPTION(); } - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_NEW_REF(value, value); ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(value), prop_info); value_type = IS_REFERENCE_EX; @@ -24035,7 +24035,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -24189,7 +24189,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -24343,7 +24343,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -24497,7 +24497,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -27026,7 +27026,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -27180,7 +27180,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -27334,7 +27334,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -27488,7 +27488,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -31379,7 +31379,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -31533,7 +31533,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -31687,7 +31687,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -31841,7 +31841,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -33796,7 +33796,7 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); #if ZEND_DEBUG if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { + && ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_OPT_DEREF(retval); zend_verify_property_type(prop_info, retval, /* strict */ true); } @@ -34126,7 +34126,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -34280,7 +34280,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -34434,7 +34434,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -34588,7 +34588,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -35969,7 +35969,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); #if ZEND_DEBUG if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { + && ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_OPT_DEREF(retval); zend_verify_property_type(prop_info, retval, /* strict */ true); } @@ -36294,7 +36294,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -36448,7 +36448,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -36602,7 +36602,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -36756,7 +36756,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -38615,7 +38615,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HAN retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); #if ZEND_DEBUG if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { + && ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_OPT_DEREF(retval); zend_verify_property_type(prop_info, retval, /* strict */ true); } @@ -38940,7 +38940,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -39094,7 +39094,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -39248,7 +39248,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -39402,7 +39402,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -42993,7 +42993,7 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); #if ZEND_DEBUG if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { + && ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_OPT_DEREF(retval); zend_verify_property_type(prop_info, retval, /* strict */ true); } @@ -43323,7 +43323,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -43477,7 +43477,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -43631,7 +43631,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -43785,7 +43785,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -46950,7 +46950,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); #if ZEND_DEBUG if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { + && ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_OPT_DEREF(retval); zend_verify_property_type(prop_info, retval, /* strict */ true); } @@ -47275,7 +47275,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -47429,7 +47429,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -47583,7 +47583,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -47737,7 +47737,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -52449,7 +52449,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); #if ZEND_DEBUG if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { + && ZEND_TYPE_IS_CHECKED(prop_info->type)) { ZVAL_OPT_DEREF(retval); zend_verify_property_type(prop_info, retval, /* strict */ true); } @@ -52774,7 +52774,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -52928,7 +52928,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -53082,7 +53082,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { @@ -53236,7 +53236,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { + if (ZEND_TYPE_IS_CHECKED(prop_info->type)) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; } else { From 70261e24b43b5c69eba6f10cb698ce64ff35ed2a Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sat, 28 Sep 2024 00:28:46 +0200 Subject: [PATCH 6/9] Move CG(types_mode) to FC --- .../include_erased_in_non_erased.inc | 19 +++++++++++++ .../include_erased_in_non_erased.phpt | 25 +++++++++++++++++ .../include_non_erased_in_erased.inc | 17 ++++++++++++ .../include_non_erased_in_erased.phpt | 27 +++++++++++++++++++ Zend/zend_compile.c | 9 ++++--- Zend/zend_compile.h | 6 +++++ Zend/zend_globals.h | 6 ----- 7 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 Zend/tests/erased_types/include_erased_in_non_erased.inc create mode 100644 Zend/tests/erased_types/include_erased_in_non_erased.phpt create mode 100644 Zend/tests/erased_types/include_non_erased_in_erased.inc create mode 100644 Zend/tests/erased_types/include_non_erased_in_erased.phpt diff --git a/Zend/tests/erased_types/include_erased_in_non_erased.inc b/Zend/tests/erased_types/include_erased_in_non_erased.inc new file mode 100644 index 0000000000000..f9e53c98fdf2a --- /dev/null +++ b/Zend/tests/erased_types/include_erased_in_non_erased.inc @@ -0,0 +1,19 @@ +test(42)); +var_dump($c->test2(42)); + +?> +--EXPECT-- +int(42) +string(2) "p2" +string(2) "42" +int(43) +int(42) +int(42) diff --git a/Zend/tests/erased_types/include_non_erased_in_erased.inc b/Zend/tests/erased_types/include_non_erased_in_erased.inc new file mode 100644 index 0000000000000..2d5cae97087c1 --- /dev/null +++ b/Zend/tests/erased_types/include_non_erased_in_erased.inc @@ -0,0 +1,17 @@ +test(42)); +var_dump($c->test2(42)); + +?> +--EXPECT-- +string(2) "42" +string(2) "p2" +string(2) "42" +string(2) "43" +string(2) "42" +string(2) "42" diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 481eae365d873..27859949f82c8 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -402,6 +402,7 @@ void zend_file_context_begin(zend_file_context *prev_context) /* {{{ */ FC(in_namespace) = 0; FC(has_bracketed_namespaces) = 0; FC(declarables).ticks = 0; + FC(types_mode) = ZEND_TYPES_MODE_CHECKED; zend_hash_init(&FC(seen_symbols), 8, NULL, NULL, 0); } /* }}} */ @@ -2697,7 +2698,7 @@ static void zend_emit_return_type_check( return; } - if (CG(types_mode) == ZEND_TYPES_MODE_ERASED) { + if (FC(types_mode) == ZEND_TYPES_MODE_ERASED) { return; } @@ -6924,9 +6925,9 @@ static void zend_compile_declare(zend_ast *ast) /* {{{ */ } if (zend_string_equals_literal_ci(Z_STR(value_zv), "checked")) { - CG(types_mode) = ZEND_TYPES_MODE_CHECKED; + FC(types_mode) = ZEND_TYPES_MODE_CHECKED; } else if (zend_string_equals_literal_ci(Z_STR(value_zv), "erased")) { - CG(types_mode) = ZEND_TYPES_MODE_ERASED; + FC(types_mode) = ZEND_TYPES_MODE_ERASED; } else { goto types_decl_value_error; } @@ -7356,7 +7357,7 @@ static zend_type zend_compile_typename_ex( ast->attr = orig_ast_attr; // FIXME: Also add the flag to list element types. - if (CG(types_mode) == ZEND_TYPES_MODE_CHECKED && ZEND_TYPE_PURE_MASK(type) != 0) { + if (FC(types_mode) == ZEND_TYPES_MODE_CHECKED && ZEND_TYPE_PURE_MASK(type) != 0) { ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_CHECKED_BIT; } else { ZEND_TYPE_FULL_MASK(type) &= ~_ZEND_TYPE_CHECKED_BIT; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 1eaf3ef686e79..c0b0df6473dfa 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -106,6 +106,11 @@ typedef struct _zend_declarables { zend_long ticks; } zend_declarables; +typedef enum { + ZEND_TYPES_MODE_CHECKED = 0, + ZEND_TYPES_MODE_ERASED, +} zend_types_mode; + /* Compilation context that is different for each file, but shared between op arrays. */ typedef struct _zend_file_context { zend_declarables declarables; @@ -119,6 +124,7 @@ typedef struct _zend_file_context { HashTable *imports_const; HashTable seen_symbols; + zend_types_mode types_mode; } zend_file_context; typedef union _zend_parser_stack_elem { diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 0845a6201c015..62a97d753634a 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -81,11 +81,6 @@ typedef enum { ZEND_MEMOIZE_FETCH, } zend_memoize_mode; -typedef enum { - ZEND_TYPES_MODE_CHECKED = 0, - ZEND_TYPES_MODE_ERASED, -} zend_types_mode; - struct _zend_compiler_globals { zend_stack loop_var_stack; @@ -166,7 +161,6 @@ struct _zend_compiler_globals { #ifdef ZTS uint32_t copied_functions_count; #endif - zend_types_mode types_mode; }; From 68d16794c2b8eed492164a394676240a2e97e440 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sat, 28 Sep 2024 00:47:38 +0200 Subject: [PATCH 7/9] Fix uninitialized erased properties --- Zend/tests/erased_types/uninitialized.phpt | 34 ++++++++++++++++++++++ Zend/zend_object_handlers.c | 6 ++++ 2 files changed, 40 insertions(+) create mode 100644 Zend/tests/erased_types/uninitialized.phpt diff --git a/Zend/tests/erased_types/uninitialized.phpt b/Zend/tests/erased_types/uninitialized.phpt new file mode 100644 index 0000000000000..3a19676d2f279 --- /dev/null +++ b/Zend/tests/erased_types/uninitialized.phpt @@ -0,0 +1,34 @@ +--TEST-- +Erased types: Uninitialized properties +--FILE-- +prop; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +try { + $c->prop++; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECTF-- +object(C)#%d (0) { + ["prop"]=> + uninitialized(int) +} +Typed property C::$prop must not be accessed before initialization +Typed property C::$prop must not be accessed before initialization diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 9fc87237350ab..61d31dd6d099d 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -935,6 +935,9 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int } } if (type != BP_VAR_IS) { + if (!prop_info && retval != &EG(uninitialized_zval)) { + prop_info = zend_get_property_info_for_slot(zobj, retval); + } if (prop_info) { zend_typed_property_uninitialized_access(prop_info, name); } else { @@ -1329,6 +1332,9 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam return zend_std_get_property_ptr_ptr(zobj, name, type, cache_slot); } if (UNEXPECTED(type == BP_VAR_RW || type == BP_VAR_R)) { + if (!prop_info) { + prop_info = zend_get_property_info_for_slot(zobj, retval); + } if (prop_info) { zend_typed_property_uninitialized_access(prop_info, name); retval = &EG(error_zval); From 8d8d39d8403b635d60da2480502e015133e5835e Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sat, 28 Sep 2024 01:15:19 +0200 Subject: [PATCH 8/9] Fix compile error --- Zend/zend.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Zend/zend.c b/Zend/zend.c index a7ae75791f514..b4fd4fd269c8a 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -731,7 +731,6 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{ compiler_globals->script_encoding_list = NULL; compiler_globals->current_linking_class = NULL; - compiler_globals->types_mode = ZEND_TYPES_MODE_CHECKED; /* Map region is going to be created and resized at run-time. */ compiler_globals->map_ptr_real_base = NULL; From 94c48f4fe304ff4777ee8117258f31485cdf35d2 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sat, 28 Sep 2024 01:40:49 +0200 Subject: [PATCH 9/9] Fix bugs --- Zend/zend_compile.c | 2 +- Zend/zend_object_handlers.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 27859949f82c8..df380eb71778a 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7357,7 +7357,7 @@ static zend_type zend_compile_typename_ex( ast->attr = orig_ast_attr; // FIXME: Also add the flag to list element types. - if (FC(types_mode) == ZEND_TYPES_MODE_CHECKED && ZEND_TYPE_PURE_MASK(type) != 0) { + if (FC(types_mode) == ZEND_TYPES_MODE_CHECKED && (ZEND_TYPE_FULL_MASK(type) & ~_ZEND_TYPE_CHECKED_BIT)) { ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_CHECKED_BIT; } else { ZEND_TYPE_FULL_MASK(type) &= ~_ZEND_TYPE_CHECKED_BIT; diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 61d31dd6d099d..95e1d1d251b73 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -937,6 +937,9 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int if (type != BP_VAR_IS) { if (!prop_info && retval != &EG(uninitialized_zval)) { prop_info = zend_get_property_info_for_slot(zobj, retval); + if (prop_info && !ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } } if (prop_info) { zend_typed_property_uninitialized_access(prop_info, name); @@ -1334,6 +1337,9 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam if (UNEXPECTED(type == BP_VAR_RW || type == BP_VAR_R)) { if (!prop_info) { prop_info = zend_get_property_info_for_slot(zobj, retval); + if (prop_info && !ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } } if (prop_info) { zend_typed_property_uninitialized_access(prop_info, name);