Skip to content

Commit 185a1ad

Browse files
committed
adds test case for #11883
Note that this test only fails if valgrind is run with the `--leak-check=full` flag.
1 parent bb092ab commit 185a1ad

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
DNF typed properties in internal classes
3+
--EXTENSIONS--
4+
zend_test
5+
spl
6+
reflection
7+
--FILE--
8+
<?php
9+
10+
$prop = new \ReflectionProperty(_ZendTestClass::class, 'dnfProperty');
11+
$type = $prop->getType();
12+
var_dump((string)$type);
13+
14+
$obj = new _ZendTestClass();
15+
$obj->dnfProperty = new \ArrayIterator([1, 2, 3]);
16+
try {
17+
$obj->dnfProperty = [];
18+
} catch (TypeError $e) {
19+
echo $e->getMessage(), "\n";
20+
}
21+
?>
22+
--EXPECT--
23+
string(32) "Iterator|(Traversable&Countable)"
24+
Cannot assign array to property _ZendTestClass::$dnfProperty of type Iterator|(Traversable&Countable)
25+

Zend/tests/type_declarations/typed_properties_095.phpt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ object(_ZendTestClass)#1 (3) {
7575
uninitialized(Traversable&Countable)
7676
["readonlyProp"]=>
7777
uninitialized(int)
78+
["dnfProperty"]=>
79+
uninitialized(Iterator|(Traversable&Countable))
7880
}
7981
int(123)
8082
Cannot assign string to property _ZendTestClass::$intProp of type int
@@ -91,6 +93,8 @@ object(Test)#4 (3) {
9193
uninitialized(Traversable&Countable)
9294
["readonlyProp"]=>
9395
uninitialized(int)
96+
["dnfProperty"]=>
97+
uninitialized(Iterator|(Traversable&Countable))
9498
}
9599
int(123)
96100
Cannot assign string to property _ZendTestClass::$staticIntProp of type int

ext/zend_test/test.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,11 +884,42 @@ static void le_throwing_resource_dtor(zend_resource *rsrc)
884884
zend_throw_exception(NULL, "Throwing resource destructor called", 0);
885885
}
886886

887+
// We need to "manually" generate this property because gen_stubs.php
888+
// does not support codegen for DNF types.
889+
static void register_ZendTestClass_dnf_property(zend_class_entry *ce) {
890+
zend_string *class_Iterator = zend_string_init_interned("Iterator", sizeof("Iterator") - 1, true);
891+
zend_alloc_ce_cache(class_Iterator);
892+
zend_string *class_Traversable = zend_string_init_interned("Traversable", sizeof("Traversable") - 1, true);
893+
zend_alloc_ce_cache(class_Traversable);
894+
zend_string *class_Countable = zend_string_init_interned("Countable", sizeof("Countable") - 1, true);
895+
zend_alloc_ce_cache(class_Countable);
896+
//
897+
zend_type_list *intersection_type_list = malloc(ZEND_TYPE_LIST_SIZE(2));
898+
intersection_type_list->num_types = 2;
899+
intersection_type_list->types[0] = (zend_type) ZEND_TYPE_INIT_CLASS(class_Traversable, 0, 0);
900+
intersection_type_list->types[1] = (zend_type) ZEND_TYPE_INIT_CLASS(class_Countable, 0, 0);
901+
zend_type_list *union_type_list = malloc(ZEND_TYPE_LIST_SIZE(2));
902+
union_type_list->num_types = 2;
903+
union_type_list->types[0] = (zend_type) ZEND_TYPE_INIT_CLASS(class_Iterator, 0, 0);
904+
union_type_list->types[1] = (zend_type) ZEND_TYPE_INIT_INTERSECTION(intersection_type_list, 0);
905+
zend_type prop_type = (zend_type) ZEND_TYPE_INIT_UNION(union_type_list, 0);
906+
//
907+
zend_string *prop_name = zend_string_init_interned("dnfProperty", sizeof("dnfProperty") - 1, true);
908+
zval default_value;
909+
ZVAL_UNDEF(&default_value);
910+
// We need this hack because some debug assertions incorrectly reject valid DNF types.
911+
// see https://github.com/php/php-src/issues/10120#issuecomment-1360682804
912+
zend_type hack = {0};
913+
zend_property_info *prop = zend_declare_typed_property(ce, prop_name, &default_value, ZEND_ACC_PUBLIC, NULL, hack);
914+
prop->type = prop_type;
915+
}
916+
887917
PHP_MINIT_FUNCTION(zend_test)
888918
{
889919
zend_test_interface = register_class__ZendTestInterface();
890920

891921
zend_test_class = register_class__ZendTestClass(zend_test_interface);
922+
register_ZendTestClass_dnf_property(zend_test_class);
892923
zend_test_class->create_object = zend_test_class_new;
893924
zend_test_class->get_static_method = zend_test_class_static_method_get;
894925

0 commit comments

Comments
 (0)