Skip to content

Regression: nested string/scalar-return builtin in call argument evaluates to null (extends #9547, Zend/zend_execute.c) #10495

Description

@PurHur

Category

stdlib · VM call lowering · php-src-strict

Problem

When a builtin that returns a string or other scalar (not only arrays) is used inline as an argument to another call, the nested expression evaluates to null instead of the return value. Assigning the same call to a variable first works.

Distinct from #9547 (array-return builtins such as array_keys() / stream_get_filters()). Same root cause class — nested FUNCCALL return slot not forwarded — but string/scalar returns are still broken.

php-src reference

Repro

test/repro/nested_string_builtin_call_arg.php:

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php test/repro/nested_string_builtin_call_arg.php
php bin/vm.php test/repro/nested_string_builtin_call_arg.php'
Expression Zend VM (bug)
var_export(get_debug_type(null), true) 'null' NULL
var_export(gettype(null), true) 'NULL' NULL
var_export(json_encode(null), true) 'null' NULL
var_export(get_class(new stdClass()), true) 'stdClass' NULL
$x = get_debug_type(null); var_export($x, true) (control) 'null' 'null'

Scope (PHP-in-PHP)

Area Path
VM call lowering nested call-as-argument must preserve callee return slot
Compiler lib/Compiler.php opcode emission for nested FUNCCALL
Stdlib no C runtime workaround

Done when (php-src-strict)

  • Repro matches Zend for nested get_debug_type, gettype, json_encode, get_class
  • #9547 nested array-return cases stay green
  • Compliance guard under test/compliance/cases/stdlib/nested_string_builtin_arg.phpt

Links

Extends #9547 · North star #1492

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 21, 2026
  2. PurHur commented on Jun 22, 2026

    @PurHur
    OwnerAuthor

    claim: cursor-agent-lane-c — starting this run

  3. PurHur commented on Jun 22, 2026

    @PurHur
    OwnerAuthor

    Merged via #10582.

    Fix: When php-cfg hoists trailing literal ConstFetch between nested FuncCall nodes (var_export(get_debug_type(null), true)), wire inner FUNCCALL_EXEC_RETURN to outer TYPE_ARG_SEND via isNestedCallArgProducerSeparatedByConsumerLiteralPreludes() in lib/Compiler.php.

    Verification:
    ```bash
    ./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
    php bin/vm.php -r "echo var_export(get_debug_type(null), true), "\n";"
    ./vendor/bin/phpunit --filter nested_string_builtin_arg test/compliance/
    '
    ```
    VM prints 'null' (was NULL); compliance nested_string_builtin_arg.phpt green.

  4. PurHur commented on Jun 22, 2026

    @PurHur
    OwnerAuthor

    claim: cursor-agent-lane-c — starting this run (continuation on agent/issue-10495-nested-string-builtin-arg)

  5. PurHur commented on Jun 22, 2026

    @PurHur
    OwnerAuthor

    Merged via #10586.

    Fix: compileCallArgSends no longer skips findInlineExprCallArgProducerSlot when hasProducer is true for php-cfg dead nested-call arg temps (var_export(get_debug_type(null), true) pattern).

    Verification (Docker):

    ./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
    php bin/vm.php test/repro/nested_string_builtin_call_arg.php
    ./vendor/bin/phpunit test/unit/InlineCallArgProducerSlotTest.php --filter testVarExportNestedScalarBuiltin'

    VM prints 'null', 'NULL', 'null', 'stdClass'; unit test green.

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