Skip to content

Language: __toString throw continues try after concat/encapsed — sibling of #29521 (zend_operators.c) #29533

Closed

Description

@PurHur

Category

language · php-src-strict · __toString / exception control flow · pillar 4

Problem

Sibling of #29521 (echo/print/(string)): when __toString throws during . concatenation or double-quoted encapsed \"{$o}\", Zend transfers to catch and does not run the rest of the try body. VM/JIT still execute trailing statements (AFTER) after the user catch — same control-flow hole on the concat/encapsed opcodes.

Probed 2026-08-09 @ 95c9b7659b vs Zend 8.2.32. JIT matches VM.

Repro Zend 8.2.32 VM / JIT
try { $r = \"x\" . (new T()) . \"y\"; echo \"AFTER\n\"; } catch … caught then done (no AFTER) caught then AFTER / done
try { echo \"x{$o}y\"; echo \"AFTER\n\"; } catch … no AFTER AFTER still prints
Control: echo path tracked in #29521 — —

php-src reference

PHP implementation target

Repro

./script/docker-exec.sh -- bash -lc 'cat > /tmp/tostring_concat.php <<'"'"'PHP'"'"'
<?php
error_reporting(E_ALL);
class T { public function __toString() { throw new Exception(\"t\"); } }
try {
  $r = \"x\" . (new T()) . \"y\";
  echo \"AFTER\n\";
} catch (Exception $e) { echo \"caught\n\"; }
echo \"done\n\";
PHP
php -d zend.exception_ignore_args=0 /tmp/tostring_concat.php
php -d zend.exception_ignore_args=0 bin/vm.php /tmp/tostring_concat.php
php -d zend.exception_ignore_args=0 bin/jit.php /tmp/tostring_concat.php'

Done when

  • VM + JIT: . concat and encapsed \"{$obj}\" with throwing __toString match Zend — catch runs, no trailing try body
  • No residual NULL assign + AFTER after catch
  • Compliance/.phpt or test/repro/ guard
  • php-src-strict; no php-compiler-strict shortcut

Activity

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

    @PurHur
    OwnerAuthor

    claim: lane-A language worker — starting this run (Pillar 1: release-readiness still running; inventory doc drift noted; continuing #29521 sibling for concat/encapsed __toString unwind)

  3. PurHur commented on Aug 9, 2026

    @PurHur
    OwnerAuthor

    Release claim — verified @ ae0bf85833 (#29521 / #29537): concat + encapsed __toString throw now match Zend (catch, no AFTER) on VM and JIT.

    zend/vm/jit concat:   caught|done|
    zend/vm/jit encapsed: caught|done|
    

    Shared BuiltinCallbackCatchRedirect deferral covers these opcodes. Done-when guards still missing (compliance/.phpt) — follow-up welcome; not starting that here.

    Switching to lane-A #29532 (object array key still wrong).

  4. PurHur commented on Aug 9, 2026

    @PurHur
    OwnerAuthor

    Maintainer verify (2026-08-09) @ 092e9d1ee8 vs Zend 8.2.32 — exact issue repro (concat + encapsed __toString throw, catch (Exception), no AFTER) is green on VM and JIT (matches Zend: caught / done only).

    Closing as fixed on master. Likely landed with the #29521 unwind fix family. Re-open with a failing snippet if you still see AFTER/continue.

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 / JITarea:vmVirtual machinebugSomething 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