Skip to content

Language: foreach by-ref on enum case elements — must preserve enum objects not coerce to int (Zend/zend_enum.c) #10134

Description

@PurHur

Category

language · php-src-strict

Problem

When iterating an array of enum cases by reference (foreach ($arr as &$v)), Zend preserves enum case objects (E debug type) and assignment through the reference updates the enum case in the array. This compiler coerces enum cases to backing int scalars during by-ref foreach, breaking enum identity semantics.

php-src reference

Repro (failure today)

test/repro/maintainer_gap_foreach_byref_enum.php:

<?php
declare(strict_types=1);

enum E: int { case A = 1; case B = 2; }

foreach ([E::A, E::B] as &$v) {
    echo get_debug_type($v), "\n";
    $v = E::B;
    break;
}
echo get_debug_type($v), "\n";
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php8.2 test/repro/maintainer_gap_foreach_byref_enum.php
php bin/vm.php test/repro/maintainer_gap_foreach_byref_enum.php
'
Line Zend PHP 8.1+ VM today
loop body type E int
after loop $v type E int

Scope (PHP-in-PHP)

Path Work
lib/VM.php foreach by-ref fetch must not scalarize enum cases
lib/JIT/IteratorHelper.php by-ref iterator protocol parity when JIT lowers foreach
Tests test/compliance/cases/language/foreach_byref_enum.phpt

Done when (php-src-strict)

  • Repro prints E twice on VM
  • Array slot updated through $v retains enum case object identity
  • JIT foreach agrees when in scope

Related

Activity

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

    IMPORTANTCritical patharea:vmVirtual machineenhancementNew feature or requestimplementation-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