Skip to content

AOT: script-scope ++/-- goes wrong once several statements or variables are involved (loop after statements, second variable) #23842

Description

@PurHur

Summary

At script scope (not inside a function), ++/-- produces wrong values once a program does
more than a couple of operations. Individually each shape is fine; combined they are not.

VM is unaffected (57/57). AOT only.

Reproducers

1 — a for loop after other script-scope inc/dec statements

<?php
$n = 5; $n--; echo $n, "\n";
$n--; $n--; echo $n, "\n";
--$n;   echo $n, "\n";
$n++;   echo $n, "\n";
$acc = 0;
for ($i = 0; $i < 5; ++$i) { ++$acc; }
echo $acc, "\n";
zend: 4 2 1 2 5
aot : 4 2 1 2 0      <- accumulator is 0

The identical loop on its own is correct:

<?php $acc = 0; for ($i = 0; $i < 5; ++$i) { ++$acc; } echo $acc, "\n";   // aot: 5, correct

2 — a second script-scope variable (intermittent heap corruption)

<?php $a = 5; $a--; $b = 9; $b--; echo "$a $b\n";
zend: 4 8
aot : free(): invalid pointer   (core dump)

Note this one is not deterministic in shape — the three-variable version
($a,$b,$c + interpolation) prints 4 8 1 correctly. Consistent with heap corruption whose
manifestation depends on allocation layout rather than a clean "second variable" rule. I could not
reduce it further.

Not caused by #23781, and not by the resource guard

Verified by probe rather than assumed, on the same tree:

first $n-- later ops
resource guard emitted (normal) 4 correct wrong
resource guard force-disabled 5 wrong wrong

Force-disabling the guard makes it worse — even the first statement breaks. So the guard is not
the cause, and neither is #23781's elision of it (#23840 was a separate, now-fixed regression that
made all script-scope inc/dec no-ops).

Whatever this is, it predates both and lives in the script-scope store path.

Coverage

test/differential/cases/g08_toplevel_incdec.php gates the plain-statement shapes on both
backends. It deliberately stops short of these two, with the exclusion documented in the file
pointing here — including them would leave it permanently red and useless as a gate.

Environment: php-compiler:22.04-dev, PHP 8.2.32, LLVM 9, php bin/compile.php -o <bin> <file>.

Activity

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