From 6ca94acb949607abd2ee024680ae49da33d49366 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 10 Feb 2025 13:54:00 +0000 Subject: [PATCH 1/4] Zend: Add some tests for redundant types --- Zend/tests/magic_methods/magic_methods_021.phpt | 2 +- .../duplicate_relative_class_parent_type.phpt | 15 +++++++++++++++ .../duplicate_relative_class_self_type.phpt | 12 ++++++++++++ .../duplicate_relative_class_static_type.phpt | 12 ++++++++++++ ..._resolved_relative_class_type_variation1.phpt | 13 +++++++++++++ ..._resolved_relative_class_type_variation2.phpt | 13 +++++++++++++ ..._resolved_relative_class_type_variation3.phpt | 16 ++++++++++++++++ ..._resolved_relative_class_type_variation4.phpt | 16 ++++++++++++++++ 8 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_parent_type.phpt create mode 100644 Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_self_type.phpt create mode 100644 Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_static_type.phpt create mode 100644 Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation1.phpt create mode 100644 Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation2.phpt create mode 100644 Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation3.phpt create mode 100644 Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation4.phpt diff --git a/Zend/tests/magic_methods/magic_methods_021.phpt b/Zend/tests/magic_methods/magic_methods_021.phpt index fd3e7fa9d0ee5..33a7220e5674e 100644 --- a/Zend/tests/magic_methods/magic_methods_021.phpt +++ b/Zend/tests/magic_methods/magic_methods_021.phpt @@ -12,7 +12,7 @@ class Foo2 { } class Foo3 { - public static function __set_state(array $data): Foo3|self {} + public static function __set_state(array $data): Foo3|Foo2 {} } ?> diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_parent_type.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_parent_type.phpt new file mode 100644 index 0000000000000..4596785263c70 --- /dev/null +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_parent_type.phpt @@ -0,0 +1,15 @@ +--TEST-- +Duplicate parent type +--FILE-- + +--EXPECTF-- +Fatal error: Duplicate type parent is redundant in %s on line %d diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_self_type.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_self_type.phpt new file mode 100644 index 0000000000000..4fcdb1f6109e3 --- /dev/null +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_self_type.phpt @@ -0,0 +1,12 @@ +--TEST-- +Duplicate self type +--FILE-- + +--EXPECTF-- +Fatal error: Duplicate type self is redundant in %s on line %d diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_static_type.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_static_type.phpt new file mode 100644 index 0000000000000..9c6e37ca6e093 --- /dev/null +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_static_type.phpt @@ -0,0 +1,12 @@ +--TEST-- +Duplicate static type +--FILE-- + +--EXPECTF-- +Fatal error: Duplicate type static is redundant in %s on line %d diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation1.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation1.phpt new file mode 100644 index 0000000000000..68b6fe78c8d65 --- /dev/null +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation1.phpt @@ -0,0 +1,13 @@ +--TEST-- +Relative class type self resolving to an existing entry (after variation) +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation2.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation2.phpt new file mode 100644 index 0000000000000..3dcd40ff1378d --- /dev/null +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation2.phpt @@ -0,0 +1,13 @@ +--TEST-- +Relative class type self resolving to an existing entry (before variation) +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation3.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation3.phpt new file mode 100644 index 0000000000000..4532025657423 --- /dev/null +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation3.phpt @@ -0,0 +1,16 @@ +--TEST-- +Relative class type parent resolving to an existing entry (after variation) +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation4.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation4.phpt new file mode 100644 index 0000000000000..8508b2eaeb28b --- /dev/null +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation4.phpt @@ -0,0 +1,16 @@ +--TEST-- +Relative class type parent resolving to an existing entry (before variation) +--FILE-- + +DONE +--EXPECT-- +DONE From e5840a9df3df459a845144457f70ed19b4908730 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 10 Feb 2025 13:54:25 +0000 Subject: [PATCH 2/4] Zend: Resolve self and parent types at compile time --- ...pe_is_allow_when_compile_time_resolve.phpt | 15 ++++++ ...ot_allow_if_not_compile_time_resolve.phpt} | 7 ++- ...pe_is_allow_when_compile_time_resolve.phpt | 13 +++++ ...ot_allow_if_not_compile_time_resolve.phpt} | 5 +- .../duplicate_relative_class_parent_type.phpt | 2 +- .../duplicate_relative_class_self_type.phpt | 2 +- ...solved_relative_class_type_variation1.phpt | 4 +- ...solved_relative_class_type_variation2.phpt | 4 +- ...solved_relative_class_type_variation3.phpt | 4 +- ...solved_relative_class_type_variation4.phpt | 4 +- Zend/zend_compile.c | 51 +++++++++++++------ Zend/zend_string.h | 2 + .../tests/types/ReflectionType_001.phpt | 8 +-- .../tests/{ => types}/bug80190.phpt | 6 +-- 14 files changed, 89 insertions(+), 38 deletions(-) create mode 100644 Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_allow_when_compile_time_resolve.phpt rename Zend/tests/type_declarations/intersection_types/{invalid_types/invalid_parent_type.phpt => relative_types/relative_parent_type_is_not_allow_if_not_compile_time_resolve.phpt} (62%) create mode 100644 Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_allow_when_compile_time_resolve.phpt rename Zend/tests/type_declarations/intersection_types/{invalid_types/invalid_self_type.phpt => relative_types/relative_self_type_is_not_allow_if_not_compile_time_resolve.phpt} (62%) rename ext/reflection/tests/{ => types}/bug80190.phpt (93%) diff --git a/Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_allow_when_compile_time_resolve.phpt b/Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_allow_when_compile_time_resolve.phpt new file mode 100644 index 0000000000000..09deba14dc15b --- /dev/null +++ b/Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_allow_when_compile_time_resolve.phpt @@ -0,0 +1,15 @@ +--TEST-- +parent type can take part in an intersection type is resolvable at compile time +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/Zend/tests/type_declarations/intersection_types/invalid_types/invalid_parent_type.phpt b/Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_not_allow_if_not_compile_time_resolve.phpt similarity index 62% rename from Zend/tests/type_declarations/intersection_types/invalid_types/invalid_parent_type.phpt rename to Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_not_allow_if_not_compile_time_resolve.phpt index e3a86771a2189..9ff858deb0da7 100644 --- a/Zend/tests/type_declarations/intersection_types/invalid_types/invalid_parent_type.phpt +++ b/Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_not_allow_if_not_compile_time_resolve.phpt @@ -1,14 +1,13 @@ --TEST-- -parent type cannot take part in an intersection type +parent type cannot take part in an intersection type if not resolvable at compile time --FILE-- +DONE --EXPECTF-- Fatal error: Type parent cannot be part of an intersection type in %s on line %d diff --git a/Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_allow_when_compile_time_resolve.phpt b/Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_allow_when_compile_time_resolve.phpt new file mode 100644 index 0000000000000..707acac144d2c --- /dev/null +++ b/Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_allow_when_compile_time_resolve.phpt @@ -0,0 +1,13 @@ +--TEST-- +self type can take part in an intersection type is resolvable at compile time +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/Zend/tests/type_declarations/intersection_types/invalid_types/invalid_self_type.phpt b/Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_not_allow_if_not_compile_time_resolve.phpt similarity index 62% rename from Zend/tests/type_declarations/intersection_types/invalid_types/invalid_self_type.phpt rename to Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_not_allow_if_not_compile_time_resolve.phpt index 66c7ec79325dc..69bd437a0743c 100644 --- a/Zend/tests/type_declarations/intersection_types/invalid_types/invalid_self_type.phpt +++ b/Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_not_allow_if_not_compile_time_resolve.phpt @@ -1,12 +1,13 @@ --TEST-- -self type cannot take part in an intersection type +self type cannot take part in an intersection type if not resolvable at compile time --FILE-- +DONE --EXPECTF-- Fatal error: Type self cannot be part of an intersection type in %s on line %d diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_parent_type.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_parent_type.phpt index 4596785263c70..2312fed21e9e6 100644 --- a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_parent_type.phpt +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_parent_type.phpt @@ -12,4 +12,4 @@ class Bar extends Foo { ?> --EXPECTF-- -Fatal error: Duplicate type parent is redundant in %s on line %d +Fatal error: Duplicate type Foo is redundant in %s on line %d diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_self_type.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_self_type.phpt index 4fcdb1f6109e3..fd3d073f97ba4 100644 --- a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_self_type.phpt +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_relative_class_self_type.phpt @@ -9,4 +9,4 @@ class Foo { ?> --EXPECTF-- -Fatal error: Duplicate type self is redundant in %s on line %d +Fatal error: Duplicate type Foo is redundant in %s on line %d diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation1.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation1.phpt index 68b6fe78c8d65..46bdd1c04556b 100644 --- a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation1.phpt +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation1.phpt @@ -9,5 +9,5 @@ class Foo { ?> DONE ---EXPECT-- -DONE +--EXPECTF-- +Fatal error: Duplicate type Foo is redundant in %s on line %d diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation2.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation2.phpt index 3dcd40ff1378d..512f7d6463d93 100644 --- a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation2.phpt +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation2.phpt @@ -9,5 +9,5 @@ class Foo { ?> DONE ---EXPECT-- -DONE +--EXPECTF-- +Fatal error: Duplicate type Foo is redundant in %s on line %d diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation3.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation3.phpt index 4532025657423..930b3116d756b 100644 --- a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation3.phpt +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation3.phpt @@ -12,5 +12,5 @@ class Bar extends Foo { ?> DONE ---EXPECT-- -DONE +--EXPECTF-- +Fatal error: Duplicate type Foo is redundant in %s on line %d diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation4.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation4.phpt index 8508b2eaeb28b..dcc3e428641d6 100644 --- a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation4.phpt +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_resolved_relative_class_type_variation4.phpt @@ -12,5 +12,5 @@ class Bar extends Foo { ?> DONE ---EXPECT-- -DONE +--EXPECTF-- +Fatal error: Duplicate type Foo is redundant in %s on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index cb64729806a23..95aa029526f18 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1409,10 +1409,8 @@ static zend_string *add_intersection_type(zend_string *str, ZEND_TYPE_LIST_FOREACH(intersection_type_list, single_type) { ZEND_ASSERT(!ZEND_TYPE_HAS_LIST(*single_type)); ZEND_ASSERT(ZEND_TYPE_HAS_NAME(*single_type)); - zend_string *name = ZEND_TYPE_NAME(*single_type); - zend_string *resolved = resolve_class_name(name, scope); - intersection_str = add_type_string(intersection_str, resolved, /* is_intersection */ true); - zend_string_release(resolved); + + intersection_str = add_type_string(intersection_str, ZEND_TYPE_NAME(*single_type), /* is_intersection */ true); } ZEND_TYPE_LIST_FOREACH_END(); ZEND_ASSERT(intersection_str); @@ -1444,6 +1442,7 @@ zend_string *zend_type_to_string_resolved(zend_type type, zend_class_entry *scop } ZEND_ASSERT(!ZEND_TYPE_HAS_LIST(*list_type)); ZEND_ASSERT(ZEND_TYPE_HAS_NAME(*list_type)); + zend_string *name = ZEND_TYPE_NAME(*list_type); zend_string *resolved = resolve_class_name(name, scope); str = add_type_string(str, resolved, /* is_intersection */ false); @@ -6957,14 +6956,14 @@ static zend_type zend_compile_single_typename(zend_ast *ast) return (zend_type) ZEND_TYPE_INIT_CODE(ast->attr, 0, 0); } else { - zend_string *class_name = zend_ast_get_str(ast); - uint8_t type_code = zend_lookup_builtin_type_by_name(class_name); + zend_string *type_name = zend_ast_get_str(ast); + uint8_t type_code = zend_lookup_builtin_type_by_name(type_name); if (type_code != 0) { if ((ast->attr & ZEND_NAME_NOT_FQ) != ZEND_NAME_NOT_FQ) { zend_error_noreturn(E_COMPILE_ERROR, "Type declaration '%s' must be unqualified", - ZSTR_VAL(zend_string_tolower(class_name))); + ZSTR_VAL(zend_string_tolower(type_name))); } /* Transform iterable into a type union alias */ @@ -6978,38 +6977,55 @@ static zend_type zend_compile_single_typename(zend_ast *ast) return (zend_type) ZEND_TYPE_INIT_CODE(type_code, 0, 0); } else { const char *correct_name; - zend_string *orig_name = zend_ast_get_str(ast); uint32_t fetch_type = zend_get_class_fetch_type_ast(ast); + zend_string *class_name = type_name; + if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) { class_name = zend_resolve_class_name_ast(ast); zend_assert_valid_class_name(class_name, "a type name"); } else { + ZEND_ASSERT(fetch_type == ZEND_FETCH_CLASS_SELF || fetch_type == ZEND_FETCH_CLASS_PARENT); + zend_ensure_valid_class_fetch_type(fetch_type); + if (fetch_type == ZEND_FETCH_CLASS_SELF) { + /* Scope might be unknown for unbound closures and traits */ + if (zend_is_scope_known()) { + class_name = CG(active_class_entry)->name; + ZEND_ASSERT(class_name && "must know class name when resolving self type at compile time"); + } + } else { + ZEND_ASSERT(fetch_type == ZEND_FETCH_CLASS_PARENT); + /* Scope might be unknown for unbound closures and traits */ + if (zend_is_scope_known()) { + class_name = CG(active_class_entry)->parent_name; + ZEND_ASSERT(class_name && "must know class name when resolving parent type at compile time"); + } + } zend_string_addref(class_name); } if (ast->attr == ZEND_NAME_NOT_FQ - && zend_is_confusable_type(orig_name, &correct_name) - && zend_is_not_imported(orig_name)) { + && zend_is_confusable_type(type_name, &correct_name) + && zend_is_not_imported(type_name)) { const char *extra = FC(current_namespace) ? " or import the class with \"use\"" : ""; if (correct_name) { zend_error(E_COMPILE_WARNING, "\"%s\" will be interpreted as a class name. Did you mean \"%s\"? " "Write \"\\%s\"%s to suppress this warning", - ZSTR_VAL(orig_name), correct_name, ZSTR_VAL(class_name), extra); + ZSTR_VAL(type_name), correct_name, ZSTR_VAL(class_name), extra); } else { zend_error(E_COMPILE_WARNING, "\"%s\" is not a supported builtin type " "and will be interpreted as a class name. " "Write \"\\%s\"%s to suppress this warning", - ZSTR_VAL(orig_name), ZSTR_VAL(class_name), extra); + ZSTR_VAL(type_name), ZSTR_VAL(class_name), extra); } } class_name = zend_new_interned_string(class_name); zend_alloc_ce_cache(class_name); - return (zend_type) ZEND_TYPE_INIT_CLASS(class_name, 0, 0); + return (zend_type) ZEND_TYPE_INIT_CLASS(class_name, /* allow null */ false, 0); } } } @@ -7132,6 +7148,7 @@ static zend_type zend_compile_typename_ex( /* Switch from single name to name list. */ type_list->num_types = 1; type_list->types[0] = type; + /* Clear MAY_BE_* type flags */ ZEND_TYPE_FULL_MASK(type_list->types[0]) &= ~_ZEND_TYPE_MAY_BE_MASK; } /* Mark type as list type */ @@ -7178,6 +7195,7 @@ static zend_type zend_compile_typename_ex( "Type contains both true and false, bool must be used instead"); } ZEND_TYPE_FULL_MASK(type) |= ZEND_TYPE_PURE_MASK(single_type); + /* Clear MAY_BE_* type flags */ ZEND_TYPE_FULL_MASK(single_type) &= ~_ZEND_TYPE_MAY_BE_MASK; if (ZEND_TYPE_IS_COMPLEX(single_type)) { @@ -7190,6 +7208,7 @@ static zend_type zend_compile_typename_ex( /* Switch from single name to name list. */ type_list->num_types = 1; type_list->types[0] = type; + /* Clear MAY_BE_* type flags */ ZEND_TYPE_FULL_MASK(type_list->types[0]) &= ~_ZEND_TYPE_MAY_BE_MASK; ZEND_TYPE_SET_LIST(type, type_list); } @@ -7253,8 +7272,10 @@ static zend_type zend_compile_typename_ex( zend_string_release_ex(standard_type_str, false); } /* Check for "self" and "parent" too */ - if (zend_string_equals_literal_ci(ZEND_TYPE_NAME(single_type), "self") - || zend_string_equals_literal_ci(ZEND_TYPE_NAME(single_type), "parent")) { + if ( + zend_string_equals(ZEND_TYPE_NAME(single_type), ZSTR_KNOWN(ZEND_STR_SELF)) + || zend_string_equals(ZEND_TYPE_NAME(single_type), ZSTR_KNOWN(ZEND_STR_PARENT)) + ) { zend_error_noreturn(E_COMPILE_ERROR, "Type %s cannot be part of an intersection type", ZSTR_VAL(ZEND_TYPE_NAME(single_type))); } diff --git a/Zend/zend_string.h b/Zend/zend_string.h index 88263d5d7a5d3..e9e2b947a6c91 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -624,6 +624,8 @@ EMPTY_SWITCH_DEFAULT_CASE() _(ZEND_STR_NULL_LOWERCASE, "null") \ _(ZEND_STR_MIXED, "mixed") \ _(ZEND_STR_TRAVERSABLE, "Traversable") \ + _(ZEND_STR_SELF, "self") \ + _(ZEND_STR_PARENT, "parent") \ _(ZEND_STR_SLEEP, "__sleep") \ _(ZEND_STR_WAKEUP, "__wakeup") \ _(ZEND_STR_CASES, "cases") \ diff --git a/ext/reflection/tests/types/ReflectionType_001.phpt b/ext/reflection/tests/types/ReflectionType_001.phpt index 3441878f155d7..33b3bbffac2a8 100644 --- a/ext/reflection/tests/types/ReflectionType_001.phpt +++ b/ext/reflection/tests/types/ReflectionType_001.phpt @@ -166,12 +166,12 @@ string(10) "SplSubject" bool(true) bool(false) bool(false) -string(4) "self" +string(1) "c" ** Method 2 - parameter 0 bool(true) bool(false) bool(false) -string(6) "parent" +string(8) "stdClass" ** Method 3 - parameter 0 bool(true) bool(false) @@ -195,12 +195,12 @@ string(3) "int" bool(true) bool(false) bool(false) -string(4) "self" +string(1) "c" ** Function/method return type 4 bool(true) bool(false) bool(false) -string(6) "parent" +string(8) "stdClass" ** Function/method return type 5 bool(true) bool(false) diff --git a/ext/reflection/tests/bug80190.phpt b/ext/reflection/tests/types/bug80190.phpt similarity index 93% rename from ext/reflection/tests/bug80190.phpt rename to ext/reflection/tests/types/bug80190.phpt index 16f2fbba42729..14fc8f7ddb21f 100644 --- a/ext/reflection/tests/bug80190.phpt +++ b/ext/reflection/tests/types/bug80190.phpt @@ -48,13 +48,13 @@ foreach ((new ReflectionClass(C::class))->getMethods() as $method) { --EXPECT-- C::a() $method->getReturnType() returns ReflectionNamedType - $method->getReturnType()->__toString() returns self + $method->getReturnType()->__toString() returns C C::b() $method->getReturnType() returns ReflectionUnionType - $method->getReturnType()->__toString() returns stdClass|self + $method->getReturnType()->__toString() returns stdClass|C $method->getReturnType()->getTypes() returns an array with 2 element(s) - type(s) in union: ReflectionNamedType(stdClass), ReflectionNamedType(self) + type(s) in union: ReflectionNamedType(stdClass), ReflectionNamedType(C) C::c() $method->getReturnType() returns ReflectionNamedType From 28b5b30627db4c15cc2f06376a997c8a9cbfb8f1 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Tue, 11 Feb 2025 13:21:10 +0000 Subject: [PATCH 3/4] Add some test and failing tests --- ...is_not_allow_if_not_compile_time_resolve2.phpt | 13 +++++++++++++ ...is_not_allow_if_not_compile_time_resolve2.phpt | 13 +++++++++++++ ...case_sensitive_relative_class_parent_type.phpt | 15 +++++++++++++++ ...e_case_sensitive_relative_class_self_type.phpt | 12 ++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_not_allow_if_not_compile_time_resolve2.phpt create mode 100644 Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_not_allow_if_not_compile_time_resolve2.phpt create mode 100644 Zend/tests/type_declarations/union_types/redundant_types/duplicate_case_sensitive_relative_class_parent_type.phpt create mode 100644 Zend/tests/type_declarations/union_types/redundant_types/duplicate_case_sensitive_relative_class_self_type.phpt diff --git a/Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_not_allow_if_not_compile_time_resolve2.phpt b/Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_not_allow_if_not_compile_time_resolve2.phpt new file mode 100644 index 0000000000000..9cc8fe55eb2f4 --- /dev/null +++ b/Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_not_allow_if_not_compile_time_resolve2.phpt @@ -0,0 +1,13 @@ +--TEST-- +parent type cannot take part in an intersection type if not resolvable at compile time +--FILE-- + +DONE +--EXPECTF-- +Fatal error: Type parent cannot be part of an intersection type in %s on line %d diff --git a/Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_not_allow_if_not_compile_time_resolve2.phpt b/Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_not_allow_if_not_compile_time_resolve2.phpt new file mode 100644 index 0000000000000..7faeba7c22622 --- /dev/null +++ b/Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_not_allow_if_not_compile_time_resolve2.phpt @@ -0,0 +1,13 @@ +--TEST-- +self type cannot take part in an intersection type if not resolvable at compile time +--FILE-- + +DONE +--EXPECTF-- +Fatal error: Type self cannot be part of an intersection type in %s on line %d diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_case_sensitive_relative_class_parent_type.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_case_sensitive_relative_class_parent_type.phpt new file mode 100644 index 0000000000000..3bcd9221f5e28 --- /dev/null +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_case_sensitive_relative_class_parent_type.phpt @@ -0,0 +1,15 @@ +--TEST-- +Duplicate parent type in different cases +--FILE-- + +--EXPECTF-- +Fatal error: Duplicate type Foo is redundant in %s on line %d diff --git a/Zend/tests/type_declarations/union_types/redundant_types/duplicate_case_sensitive_relative_class_self_type.phpt b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_case_sensitive_relative_class_self_type.phpt new file mode 100644 index 0000000000000..ce969e4dca9fc --- /dev/null +++ b/Zend/tests/type_declarations/union_types/redundant_types/duplicate_case_sensitive_relative_class_self_type.phpt @@ -0,0 +1,12 @@ +--TEST-- +Duplicate self type in different cases +--FILE-- + +--EXPECTF-- +Fatal error: Duplicate type Foo is redundant in %s on line %d From 06651eae067a83ab5224f3c3ec8a02602955a8e1 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Tue, 11 Feb 2025 13:22:54 +0000 Subject: [PATCH 4/4] Fix + adjust test --- ...parent_type_is_not_allow_if_not_compile_time_resolve2.phpt | 2 +- ...e_self_type_is_not_allow_if_not_compile_time_resolve2.phpt | 2 +- Zend/zend_compile.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_not_allow_if_not_compile_time_resolve2.phpt b/Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_not_allow_if_not_compile_time_resolve2.phpt index 9cc8fe55eb2f4..c511a1739ae1c 100644 --- a/Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_not_allow_if_not_compile_time_resolve2.phpt +++ b/Zend/tests/type_declarations/intersection_types/relative_types/relative_parent_type_is_not_allow_if_not_compile_time_resolve2.phpt @@ -10,4 +10,4 @@ trait T { ?> DONE --EXPECTF-- -Fatal error: Type parent cannot be part of an intersection type in %s on line %d +Fatal error: Type PARENT cannot be part of an intersection type in %s on line %d diff --git a/Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_not_allow_if_not_compile_time_resolve2.phpt b/Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_not_allow_if_not_compile_time_resolve2.phpt index 7faeba7c22622..00a2127273f2a 100644 --- a/Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_not_allow_if_not_compile_time_resolve2.phpt +++ b/Zend/tests/type_declarations/intersection_types/relative_types/relative_self_type_is_not_allow_if_not_compile_time_resolve2.phpt @@ -10,4 +10,4 @@ trait T { ?> DONE --EXPECTF-- -Fatal error: Type self cannot be part of an intersection type in %s on line %d +Fatal error: Type SELF cannot be part of an intersection type in %s on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 95aa029526f18..797ed8cdb08c4 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7273,8 +7273,8 @@ static zend_type zend_compile_typename_ex( } /* Check for "self" and "parent" too */ if ( - zend_string_equals(ZEND_TYPE_NAME(single_type), ZSTR_KNOWN(ZEND_STR_SELF)) - || zend_string_equals(ZEND_TYPE_NAME(single_type), ZSTR_KNOWN(ZEND_STR_PARENT)) + zend_string_equals_ci(ZEND_TYPE_NAME(single_type), ZSTR_KNOWN(ZEND_STR_SELF)) + || zend_string_equals_ci(ZEND_TYPE_NAME(single_type), ZSTR_KNOWN(ZEND_STR_PARENT)) ) { zend_error_noreturn(E_COMPILE_ERROR, "Type %s cannot be part of an intersection type", ZSTR_VAL(ZEND_TYPE_NAME(single_type)));