Skip to content

Regression: unset($obj->arr[$k]) no-ops again on instance/static array props — Zend removes (re-#24250, zend_execute.c) #31818

Closed

Description

@PurHur

Category

Regression: · php-src-strict · language (UNSET_DIM on object / static properties)

Problem

unset($obj->prop[$key]) / unset($this->prop[$key]) / unset(Class::$prop[$key]) must remove the array key on instance and static object properties (typed and untyped). After #24250 / #24263 this was green; on master 2026-08-17 it is a no-op again (likely regressed by recent typed-property dim work around #31770–#31784).

Userland ArrayAccess::offsetUnset that does unset($this->storage[$offset]) on a private/typed array property is broken the same way — isset($obj[$k]) stays true after unset($obj[$k]) even though offsetUnset runs.

Local $a[$k] unset still matches Zend (control).

Probed 2026-08-17 — host Zend PHP 8.2 vs php bin/vm.php.

Repro Zend 8.2+ VM (2026-08-17)
unset($c->t['y']) public array key gone key remains
unset($this->pt['a']) private array key gone key remains
unset($c->u['q']) public untyped key gone key remains
unset(StaticBag::$t['y']) key gone key remains
ArrayAccess unset($s['k']) → unset($this->d[$k]) isset false isset true
unset($local[1]) key gone key gone (match)

UnsetComplianceTest / unset_object_array_dim.phpt fails: expected t=0 pt=0 u=0 pu=0 / aa=00, actual t=2 pt=1 u=2 pu=1 / aa=11.

php-src reference

PHP implementation target

Repro

./script/docker-exec.sh -- bash -lc 'php test/repro/maintainer_gap_unset_object_array_dim.php'
./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_unset_object_array_dim.php'
./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_unset_object_array_dim_static.php'
./script/phpunit.sh --filter UnsetComplianceTest

Done when

Activity

  1. added
    bugSomething isn't working
    implementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claim
    on Aug 17, 2026
  2. PurHur commented on Aug 17, 2026

    @PurHur
    OwnerAuthor

    claim: Worker lane C — starting this run (lane overflow: no eligible IR in lane C; #31817 claimed by PHP Runtime → PHP; stdlib/ext-owned queue skipped)

  3. PurHur commented on Aug 17, 2026

    @PurHur
    OwnerAuthor

    Merged #31825

    Cause: #31783 marked PropertyFetch before dim unset as propertyHookCoalesceRead (FETCH_OBJ_IS), so unsets copied the array and no-op’d on the property.

    Fix: IS-mode prelude only for isset/empty/??; unset keeps R-mode live alias.

    Verified (after rebase on master):

    • php bin/vm.php test/repro/maintainer_gap_unset_object_array_dim.php — empty arrays
    • php bin/vm.php test/repro/maintainer_gap_unset_object_array_dim_static.php — keys removed, aa=0
    • ./script/phpunit.sh --filter UnsetComplianceTest — OK (9)
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:compilerCompiler / CFG / JITbugSomething isn't workingimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-2:languagePhase 2 – language features

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions