Skip to content

Commit 0d5d375

Browse files
committed
More debugging
1 parent 6b5c9c1 commit 0d5d375

File tree

5 files changed

+57
-17
lines changed

5 files changed

+57
-17
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Property types must be invariant
3+
--FILE--
4+
<?php
5+
6+
interface X {}
7+
interface Y {}
8+
9+
class A {
10+
public (X&Y&Z)|L $prop;
11+
}
12+
class B extends A {
13+
public (X&Y)|L $prop;
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
Fatal error: Type of B::$prop must be (X&Y&Z)|L (as in class A) in %s on line %d

Zend/zend_API.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2757,18 +2757,32 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arg_info_toString, 0, 0, IS_STRING, 0)
27572757
ZEND_END_ARG_INFO()
27582758

27592759
#ifdef ZEND_DEBUG
2760-
static bool zend_verify_type_is_valid(zend_type type, int nesting_level, bool is_arena_alloc)
2760+
ZEND_API bool zend_verify_type_is_valid(zend_type type, int nesting_level, bool is_arena_alloc)
27612761
{
27622762
bool status = false;
27632763

2764-
if (ZEND_TYPE_HAS_LIST(type)) {
2764+
if (!ZEND_TYPE_IS_SET(type)) {
2765+
return nesting_level == 0;
2766+
} else if (ZEND_TYPE_IS_ONLY_MASK(type)) {
2767+
return true;
2768+
} else if (ZEND_TYPE_HAS_NAME(type)) {
2769+
zend_string *name = ZEND_TYPE_NAME(type);
2770+
if (zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_ITERABLE))) {
2771+
printf("iterable type should not exist at level %d\n", nesting_level);
2772+
return false;
2773+
}
2774+
return true;
2775+
} else if (ZEND_TYPE_HAS_LIST(type)) {
27652776
if (!ZEND_TYPE_IS_INTERSECTION(type) && !ZEND_TYPE_IS_UNION(type)) {
2777+
printf("Missing type list variant at level %d\n", nesting_level);
27662778
return false;
27672779
}
27682780
if (ZEND_TYPE_USES_ARENA(type) != is_arena_alloc) {
2781+
printf("Unexpected allocation type at level %d\n", nesting_level);
27692782
return false;
27702783
}
27712784
if (nesting_level >= 2) {
2785+
printf("Nesting exceeded: %d\n", nesting_level);
27722786
return false;
27732787
}
27742788

@@ -2779,20 +2793,11 @@ static bool zend_verify_type_is_valid(zend_type type, int nesting_level, bool is
27792793
return false;
27802794
}
27812795
ZEND_TYPE_LIST_FOREACH_END();
2782-
// status must be true
2783-
} else if (ZEND_TYPE_HAS_NAME(type)) {
2784-
zend_string *name = ZEND_TYPE_NAME(type);
2785-
if (zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_ITERABLE))) {
2786-
return false;
2787-
}
2788-
status = true;
2789-
} else if (!ZEND_TYPE_IS_COMPLEX(type)) {
27902796
return true;
27912797
}
2798+
printf("Error at level %d\n", nesting_level);
27922799
return status;
27932800
}
2794-
#elif
2795-
#define zend_verify_type_is_valid(type, nesting_level, is_arena_alloc) true
27962801
#endif
27972802

27982803
/* registers all functions in *library_functions in the function hash */
@@ -4320,7 +4325,7 @@ ZEND_API zend_property_info *zend_declare_typed_property(zend_class_entry *ce, z
43204325

43214326
ZEND_ASSERT(
43224327
zend_verify_type_is_valid(type, /* nesting_level */ 0, /* is_arena_alloca */ ce->type == ZEND_USER_CLASS)
4323-
&& "zend_type is invalid" && ce->type
4328+
&& "zend_type is invalid"
43244329
);
43254330

43264331
if (access_type & ZEND_ACC_READONLY) {

Zend/zend_API.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,13 @@ ZEND_API void zend_check_magic_method_implementation(
384384
const zend_class_entry *ce, const zend_function *fptr, zend_string *lcname, int error_type);
385385
ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, zend_string *lcname);
386386

387+
/* Type debugging utility */
388+
#ifdef ZEND_DEBUG
389+
ZEND_API bool zend_verify_type_is_valid(zend_type type, int nesting_level, bool is_arena_alloc);
390+
#else
391+
#define zend_verify_type_is_valid(type, nesting_level, is_arena_alloc) true
392+
#endif
393+
387394
ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *class_entry);
388395
ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce);
389396
ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry);

Zend/zend_inheritance.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2522,9 +2522,8 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
25222522
/* Assumption: only userland classes can use traits, as such the type must be arena allocated */
25232523
zend_type_copy_ctor(&type, /* use arena */ true, /* persistent */ false);
25242524
ZEND_ASSERT(
2525-
!ZEND_TYPE_IS_COMPLEX(type)
2526-
|| ZEND_TYPE_HAS_NAME(type)
2527-
|| (ZEND_TYPE_HAS_LIST(type) && ZEND_TYPE_USES_ARENA(type) && "Type list must be arena alloc")
2525+
zend_verify_type_is_valid(type, /* nesting_level */ 0, /* is_arena_alloca */ true)
2526+
&& "zend_type is invalid"
25282527
);
25292528
new_prop = zend_declare_typed_property(ce, prop_name, prop_value, flags, doc_comment, type);
25302529

Zend/zend_opcode.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ ZEND_API void zend_type_release(zend_type type, bool persistent) {
120120
} ZEND_TYPE_LIST_FOREACH_END();
121121
// TODO Figure out why DNF invalid_invariance1 test has a type not marked as arena allocated
122122
if (!ZEND_TYPE_USES_ARENA(*list_type) && persistent) {
123-
/* if (!ZEND_TYPE_USES_ARENA(*list_type)) { */
123+
//if (!ZEND_TYPE_USES_ARENA(*list_type)) {
124124
pefree(ZEND_TYPE_LIST(*list_type), persistent);
125125
}
126126
} else if (ZEND_TYPE_HAS_NAME(*list_type)) {
@@ -403,6 +403,17 @@ ZEND_API void destroy_zend_class(zval *zv)
403403
if (prop_info->attributes) {
404404
zend_hash_release(prop_info->attributes);
405405
}
406+
ZEND_ASSERT(
407+
!ZEND_TYPE_IS_COMPLEX(prop_info->type)
408+
|| ZEND_TYPE_HAS_NAME(prop_info->type)
409+
|| (ZEND_TYPE_HAS_LIST(prop_info->type) && ZEND_TYPE_USES_ARENA(prop_info->type) && "Type list must be arena alloc")
410+
);
411+
412+
//ZEND_ASSERT(
413+
zend_verify_type_is_valid(prop_info->type, /* nesting_level */ 0, /* is_arena_alloca */ true)
414+
// && "zend_type is invalid"
415+
//);
416+
;
406417
zend_type_release(prop_info->type, /* persistent */ 0);
407418
}
408419
} ZEND_HASH_FOREACH_END();

0 commit comments

Comments
 (0)