Skip to content

Language: encapsed {$obj} ignores __toString — dumps object / NULL concat (re-#13466, zend_operators.c) #26489

Closed

Description

@PurHur

Category

bug · php-src-strict · pillar 4 · regression of closed #13466

Problem

In double-quoted encapsed interpolations, Zend stringifies objects via __toString. On master@c295da392 (2026-08-01) "{$c}" var_exports an object __set_state dump, and "prefix{$c}suffix" yields NULL.

Repro Zend 8.2+ VM (2026-08-01)
class C { function __toString(): string { return 'obj'; } } var_export("{$c}"); 'obj' \C::__set_state(...)
var_export("prefix{$c}suffix"); 'prefixobjsuffix' NULL

Compliance case still red: language/encapsed_rvalue_object.

php-src reference

PHP implementation target

  • Encapsed / string-interp lowering in lib/Compiler.php must coerce object r-values through __toString (shared string cast path) — PHP-in-PHP; no new C
  • Exception message interpolation ("err: {$c}") must match Zend

Repro

./script/docker-exec.sh -- bash -lc 'php bin/vm.php -r "
class C {
  public string \$p = \"prop\";
  public function __toString(): string { return \"obj\"; }
}
\$c = new C();
var_export(\"{\$c}\");
echo PHP_EOL;
var_export(\"prefix{\$c}suffix\");
echo PHP_EOL;
"'

Done when

  • VM/JIT/AOT: "{$c}" / concat / exception message match Zend __toString results
  • language/encapsed_rvalue_object compliance green
  • 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 1, 2026
  2. PurHur commented on Aug 1, 2026

    @PurHur
    OwnerAuthor

    claim: Worker lane C (Composer) — starting this run

  3. PurHur commented on Aug 1, 2026

    @PurHur
    OwnerAuthor

    Merged in #26548 (546f721e9).

    Cause: rewireVarExportNestedInlineCallArgSendSlots overwrote correctly wired encapsed ConcatList ARG_SEND slots with a prior New_ EXEC_RETURN, so var_export("{$c}") dumped the object instead of __toString.

    Fix: early-return in that rewire when the immediate producer is ConcatList / BinaryOp\Concat (kept out of isImmediateVarExportExpressionPrelude because those callers compileExpr() the prelude).

    Verified:

    • VM + JIT: test/repro/encapsed_rvalue_object_26489.php matches language/encapsed_rvalue_object EXPECT ('obj', 'prop', 'one', 'prefixobjsuffix', …)
    • Issue repro: var_export("{$c}") → 'obj'; var_export("prefix{$c}suffix") → 'prefixobjsuffix'
    • AOT: build OK; run segfaults exit 139 on both this branch and origin/master (c:main_before_php) — pre-existing, not introduced here

    Gate snapshot: user_release_ready: yes from release-readiness --json before claim.

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