Category
Language: · php-src-strict · nested ?? BP_VAR_IS
Problem
?? / ??= on an uninitialized typed property must use Zend BP_VAR_IS (quiet undefined → default), not a typed-property Error. Statement form $o->x ?? "d" already matches Zend (#31146). Nested forms — concat and function-arg — still compile/run as a normal read: VM prints the statement result then silently stops (exit 0, no Error, remaining echoes omitted). Same hole for static typed properties.
Probed 2026-08-17 — host Zend PHP 8.2 vs php bin/vm.php.
| Repro |
Zend 8.2+ |
VM (2026-08-17) |
var_export($o->x ?? "d"); (statement) |
'd' then continues |
'd' then continues |
"concat=" . var_export($o->x ?? "d", true) |
concat='d' then after |
no further output (rc 0) |
take($o->x ?? "d") |
arg=d then after |
empty (rc 0) |
S::$y ?? "d" statement |
'd' |
'd' |
concat of S::$y ?? "d" |
static_concat='d' then after |
no further output (rc 0) |
class C { public int $x; }
$o = new C;
echo "stmt="; var_export($o->x ?? "d"); echo "\n";
echo "concat=" . var_export($o->x ?? "d", true) . "\n"; // Zend 'd' / VM aborts
echo "after\n";
php-src reference
PHP implementation target
Repro
./script/docker-exec.sh -- bash -lc 'php test/repro/maintainer_gap_uninit_typed_coalesce.php'
./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_uninit_typed_coalesce.php'
./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_uninit_static_coalesce.php'
./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_uninit_coalesce_arg.php'
Done when
Category
Language:· php-src-strict · nested??BP_VAR_ISProblem
??/??=on an uninitialized typed property must use ZendBP_VAR_IS(quiet undefined → default), not a typed-property Error. Statement form$o->x ?? "d"already matches Zend (#31146). Nested forms — concat and function-arg — still compile/run as a normal read: VM prints the statement result then silently stops (exit 0, no Error, remaining echoes omitted). Same hole for static typed properties.Probed 2026-08-17 — host Zend PHP 8.2 vs
php bin/vm.php.var_export($o->x ?? "d");(statement)'d'then continues'd'then continues"concat=" . var_export($o->x ?? "d", true)concat='d'thenaftertake($o->x ?? "d")arg=dthenafterS::$y ?? "d"statement'd''d'S::$y ?? "d"static_concat='d'thenafterphp-src reference
Zend/zend_vm_def.h—ZEND_COALESCE/FETCH_OBJ_IS/FETCH_STATIC_PROP_ISZend/zend_object_handlers.c—zend_std_has_property/zend_std_read_propertywithBP_VAR_IS(uninitialized typed slot is "unset", no Error)PHP implementation target
lib/Compiler.php— Language: ?? / ??= on uninitialized typed property throws Error — Zend BP_VAR_IS default (zend_object_handlers.c) #31146 only rewrites siblingPropertyFetch/StaticPropertyFetchimmediately beforeBinaryOp\Coalesce. Extend the same IS-mode fetch to coalesce nested in concat /FuncCallargs (resolvePropertyFetchCoalesceCallArgSlotexists but does not cover this CFG)lib/VM.php—copyPropertyValueForIsModealready implements BP_VAR_IS; do not add a C runtime branchruntime/*.clogicRepro
Done when
??on uninitialized instance and static typed properties yield the default on VM (and JIT/AOT if in scope); remaining statements still run??/??=from Language: ?? / ??= on uninitialized typed property throws Error — Zend BP_VAR_IS default (zend_object_handlers.c) #31146 stay green (typed_prop_coalesce_uninit_31146.phpt)$o->xstill Errors;isset/emptyunchanged.phptundertest/compliance/cases/language/