Category
bug · php-src-strict · AOT / JIT operand guards · silent wrong output
Problem
++$fh / --$fh where $fh is an open resource silently succeeds in an AOT binary. Zend raises TypeError: Cannot increment resource. This is the silent-wrong-output class from AGENTS.md §3.
The guard for this exists — JIT::guardIncDecResourceOperand(), added for #6396 — but it never fires for top-level script code.
| Repro |
Zend 8.2 |
AOT (master) |
++$fh on fopen('php://memory','r+') |
TypeError: Cannot increment resource (rc 255) |
prints no error (rc 0) |
Measured on master at 544d1dca9, php-compiler:22.04-dev, LLVM 9.
Cause
guardIncDecResourceOperand() only emits the check when the read operand is TYPE_NATIVE_LONG, or TYPE_VALUE with KIND_VARIABLE / functionStaticGlobal. A top-level $fh from fopen() lands in neither bucket, so the guard is skipped with no diagnostic. Worth checking whether the same hole applies to the other #6396-era operand guards.
php-src reference
PHP implementation target
lib/JIT.php — guardIncDecResourceOperand() (and sibling operand guards) must cover top-level resource locals, not only NATIVE_LONG / KIND_VARIABLE shapes
- Prefer PHP-side guard emission; no new C runtime logic
- Regression guard in
test/differential/cases/ (or AOT compliance) once fixed
Repro
./script/docker-exec.sh -- bash -lc '
cat > /tmp/repro_inc_res.php <<'"'"'PHP'"'"'
<?php
$fh = fopen("php://memory", "r+");
++$fh;
echo "no error\n";
PHP
./phpc build -o /tmp/repro_inc_res /tmp/repro_inc_res.php && /tmp/repro_inc_res; echo rc=$?
'
Done when
Note
Found while working #23483; pre-existing on master with lib/JIT.php stashed — filed separately so the perf change is not credited with fixing it.
Category
bug· php-src-strict · AOT / JIT operand guards · silent wrong outputProblem
++$fh/--$fhwhere$fhis an open resource silently succeeds in an AOT binary. Zend raisesTypeError: Cannot increment resource. This is the silent-wrong-output class from AGENTS.md §3.The guard for this exists —
JIT::guardIncDecResourceOperand(), added for #6396 — but it never fires for top-level script code.++$fhonfopen('php://memory','r+')TypeError: Cannot increment resource(rc 255)no error(rc 0)Measured on master at
544d1dca9,php-compiler:22.04-dev, LLVM 9.Cause
guardIncDecResourceOperand()only emits the check when the read operand isTYPE_NATIVE_LONG, orTYPE_VALUEwithKIND_VARIABLE/functionStaticGlobal. A top-level$fhfromfopen()lands in neither bucket, so the guard is skipped with no diagnostic. Worth checking whether the same hole applies to the other #6396-era operand guards.php-src reference
Zend/zend_operators.c— increment/decrement on non-numeric types → TypeErrorPHP implementation target
lib/JIT.php—guardIncDecResourceOperand()(and sibling operand guards) must cover top-level resource locals, not only NATIVE_LONG / KIND_VARIABLE shapestest/differential/cases/(or AOT compliance) once fixedRepro
Done when
TypeError: Cannot increment/decrement resourcematching ZendNote
Found while working #23483; pre-existing on master with
lib/JIT.phpstashed — filed separately so the perf change is not credited with fixing it.