Skip to content

Stdlib: ArrayObject::getIteratorClass() returns null after void setIteratorClass() in expression (ext/spl/spl_array.c) #10778

Description

@PurHur

Category

stdlib — php-src-strict

Problem

After $ao->setIteratorClass('ArrayIterator'), the next var_export($ao->getIteratorClass(), true) must be 'ArrayIterator'. On this compiler the first getIteratorClass() used as an expression after the void setter returns NULL (though a later call or direct echo may show the correct string).

Reproduces with declare(strict_types=1); see test/repro/maintainer_gap_arrayobject_get_iterator_class.php for the broader var_export sequence.

Verified 2026-06-23 on VM (php bin/vm.php).

php-src reference

  • ext/spl/spl_array.c — spl_array_setIteratorClass / spl_array_getIteratorClass
  • Likely VM return-value slot not cleared between void method and subsequent method call (ext/spl/ArrayObjectBuiltin.php early returnVar guard on setIteratorClass)

Repro

test/repro/maintainer_gap_arrayobject_getiterator_after_set.php

php test/repro/maintainer_gap_arrayobject_getiterator_after_set.php           # PASS exit 0
php bin/vm.php test/repro/maintainer_gap_arrayobject_getiterator_after_set.php  # FAIL exit 255

Implementation hint

  • ext/spl/ArrayObjectBuiltin.php — do not bail out of setIteratorClass when returnVar is null before persisting class; void methods must not poison the next call's return slot
  • ext/spl/SplArrayStorage.php — iterator class bag already correct when setter runs
  • PHP-in-PHP; no new runtime/*.c

Done when

Links

Activity

  1. added
    enhancementNew feature or request
    phase-4:stdlibPhase 4 – stdlib for web apps
    area:vmVirtual machine
    implementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claim
    on Jun 23, 2026
  2. PurHur commented on Jun 23, 2026

    @PurHur
    OwnerAuthor

    claim: cursor-agent-lane-c — starting this run (ArrayObject getIteratorClass after void setIteratorClass; ext/spl/spl_array.c)

  3. PurHur commented on Jun 23, 2026

    @PurHur
    OwnerAuthor

    Merged via #10800

    Fix: filterDeadVoidStatementMethodCallProducers drops dead void MethodCall preludes before sibling method inline call-args; setIteratorClass no longer returns early when returnVar is null.

    Verification:

    ./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
    php bin/vm.php test/repro/maintainer_gap_arrayobject_getiterator_after_set.php
    php bin/vm.php test/repro/maintainer_gap_arrayobject_get_iterator_class.php
    ./vendor/bin/phpunit --filter arrayobject_getiterator_after_set
    '
  4. PurHur commented on Jul 5, 2026

    @PurHur
    OwnerAuthor

    claim: cursor-agent-lane-a — regression fix: var_export after void setIteratorClass still misbinds getIteratorClass to true on master

  5. PurHur commented on Jul 5, 2026

    @PurHur
    OwnerAuthor

    Merged via #16310 — regression fix for var_export(\$ao->getIteratorClass(), true) after void setIteratorClass().

    Verification:

    • vendor/bin/phpunit --filter "ArrayObjectGetIterator|arrayobject_getiterator|arrayobject_iterator_class" — OK (5 tests)
    • php bin/vm.php test/repro/maintainer_gap_arrayobject_getiterator_after_set.php — prints 'ArrayIterator'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:vmVirtual machineenhancementNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-4:stdlibPhase 4 – stdlib for web appsstdlib

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions