Category
runtime
Problem
When a ternary (?:) uses a function call in the condition and again in the alternate arm, the VM prints the wrong branch value. A minimal getenv() repro shows the consequent string "unset" is replaced by the function name "getenv" even when the condition is true.
This breaks idiomatic env checks like getenv('VAR') === false ? 'unset' : getenv('VAR') used in bootstrap and CLI tooling.
php-src reference
Repro (failure today)
<?php
putenv('FOO=bar');
putenv('FOO'); // unset
echo getenv('FOO') === false ? 'unset' : getenv('FOO');
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && php bin/vm.php repro.php'
php repro.php
| Runtime |
Output |
| Zend PHP 8.x |
unset |
bin/vm.php |
getenv |
Note: assigning to a temp works — $r = getenv('FOO'); echo $r === false ? 'unset' : 'val'; prints unset. Bug is specific to inline ternary with repeated call.
Scope (this repo)
| Layer |
Path |
Notes |
| Compiler |
lib/Compiler.php |
Ternary/?? branch merge may reuse wrong operand slot for call results |
| VM |
lib/VM.php |
Verify TYPE_JUMP/assign phi for ternary arms |
| Tests |
test/compliance/cases/language/ternary_func_call.phpt |
getenv repro + generic foo() stub |
Done when
Verification
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter ternary_func_call'
Links
Category
runtimeProblem
When a ternary (
?:) uses a function call in the condition and again in the alternate arm, the VM prints the wrong branch value. A minimalgetenv()repro shows the consequent string"unset"is replaced by the function name"getenv"even when the condition is true.This breaks idiomatic env checks like
getenv('VAR') === false ? 'unset' : getenv('VAR')used in bootstrap and CLI tooling.php-src reference
Zend/zend_compile.c—zend_compile_short_circuit/ ternaryzend_astloweringZend/zend_execute.c—ZEND_JMP_SET/ZEND_JMP_SET_VAR, short-circuit evaluation orderRepro (failure today)
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && php bin/vm.php repro.php' php repro.phpunsetbin/vm.phpgetenvNote: assigning to a temp works —
$r = getenv('FOO'); echo $r === false ? 'unset' : 'val';printsunset. Bug is specific to inline ternary with repeated call.Scope (this repo)
lib/Compiler.php??branch merge may reuse wrong operand slot for call resultslib/VM.phpTYPE_JUMP/assign phi for ternary armstest/compliance/cases/language/ternary_func_call.phptfoo()stubDone when
unseton VM./script/ci-fast.sh --filter ternary_func_callgreen??/?:with literals (Language: Null coalescing operator (??) in compiler pipeline #99, Language: ??= null coalescing assignment #1235)Verification
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter ternary_func_call'Links
local_onlyarg)