diff --git a/Zend/tests/generators/gc_with_root_parent_mismatch.phpt b/Zend/tests/generators/gc_with_root_parent_mismatch.phpt new file mode 100644 index 00000000000..ee388b1c76d --- /dev/null +++ b/Zend/tests/generators/gc_with_root_parent_mismatch.phpt @@ -0,0 +1,27 @@ +--TEST-- +Generator GC when the yield from parent chain does not reach the root +--FILE-- +current()); +var_dump($gen2->current()); +$gen1->next(); +$gen1->next(); +gc_collect_cycles(); + +?> +--EXPECT-- +int(1) +int(1) diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 233dfe5ac95..963ac08c829 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -278,9 +278,9 @@ static uint32_t calc_gc_buffer_size(zend_generator *generator) /* {{{ */ /* Yield from root references */ if (generator->node.children == 0) { - zend_generator *child = generator, *root = generator->node.ptr.root; - while (root != child) { - child = child->node.parent; + zend_generator *root = generator->node.ptr.root; + while (root != generator) { + root = zend_generator_get_child(&root->node, generator); size++; } } @@ -343,10 +343,10 @@ static HashTable *zend_generator_get_gc(zval *object, zval **table, int *n) /* { } if (generator->node.children == 0) { - zend_generator *child = generator, *root = generator->node.ptr.root; - while (root != child) { - child = child->node.parent; - ZVAL_OBJ(gc_buffer++, &child->std); + zend_generator *root = generator->node.ptr.root; + while (root != generator) { + ZVAL_OBJ(gc_buffer++, &root->std); + root = zend_generator_get_child(&root->node, generator); } }