Summary
In AOT binaries, the result of a string concatenation does not survive. Passing it to a function
yields an empty string; concatenating from the same variable a second time aborts with
free(): invalid pointer. Both look like a premature free / double free of the concat result.
VM is unaffected — script/differential-sweep.sh (VM) is 53/53. This is AOT-only.
Minimal reproducers
1 — concat result passed to a function arrives empty
<?php function f($a){ echo $a, "\n"; } $s='s'; f($s.'1');
2 — second concat from the same variable corrupts the heap
<?php $s='s'; echo $s.'1', "\n"; echo $s.'2', "\n";
zend: s1
s2
aot : s1
free(): invalid pointer
Note the first concat prints correctly and the second one dies — consistent with the backing
buffer being released after the first use and then freed again.
What it is not
Deliberately bounded with a control set. These all pass in AOT, so it is not about arguments,
arity, or interpolation:
| case |
result |
function f($a,$b){...} f('x','y') — literal args |
ok |
function f($a,$b){ echo "$a $b\n"; } f('x','y') — interpolation |
ok |
function f($a){...} $x=1; f($x+1) — arithmetic arg |
ok |
function f($a,$b){...} $x=1; f($x+1,$x+2) — two arithmetic args |
ok |
function f($a){...} $s='s'; f($s.'1') — concat arg |
empty |
function f($a,$b){...} $s='s'; f($s.'1',$s.'2') — two concat args |
empty |
$s='s'; echo $s.'1'; echo $s.'2'; — concat, no call at all |
free(): invalid pointer |
Arithmetic results as arguments are fine; only string concat is affected. And reproducer 2 has no
function call in it, so this is not argument passing — it is the lifetime of the concat result
itself.
It is also not the #579 external-stub class. Built with PHP_COMPILER_WARN_EXTERNAL_STUBS=1,
the only warning emitted is phpcompiler\ext\dom\builtinclasses::register, which is incidental and
also present in binaries that run correctly.
Likely blast radius
This probably accounts for most of the string cluster in #23779: c04_concat, c11_strcmp,
d04_concat_dim, e15_str_fns (which dies with the same free(): invalid pointer), and possibly
e23_implode.
Environment
php-compiler:22.04-dev, PHP 8.2.32, LLVM 9. Reproduced on clean master 544d1dca9 (no local
lib/ modifications — verified). Built with php bin/compile.php -o <bin> <file>.
Summary
In AOT binaries, the result of a string concatenation does not survive. Passing it to a function
yields an empty string; concatenating from the same variable a second time aborts with
free(): invalid pointer. Both look like a premature free / double free of the concat result.VM is unaffected —
script/differential-sweep.sh(VM) is 53/53. This is AOT-only.Minimal reproducers
1 — concat result passed to a function arrives empty
2 — second concat from the same variable corrupts the heap
Note the first concat prints correctly and the second one dies — consistent with the backing
buffer being released after the first use and then freed again.
What it is not
Deliberately bounded with a control set. These all pass in AOT, so it is not about arguments,
arity, or interpolation:
function f($a,$b){...} f('x','y')— literal argsfunction f($a,$b){ echo "$a $b\n"; } f('x','y')— interpolationfunction f($a){...} $x=1; f($x+1)— arithmetic argfunction f($a,$b){...} $x=1; f($x+1,$x+2)— two arithmetic argsfunction f($a){...} $s='s'; f($s.'1')— concat argfunction f($a,$b){...} $s='s'; f($s.'1',$s.'2')— two concat args$s='s'; echo $s.'1'; echo $s.'2';— concat, no call at allArithmetic results as arguments are fine; only string concat is affected. And reproducer 2 has no
function call in it, so this is not argument passing — it is the lifetime of the concat result
itself.
It is also not the #579 external-stub class. Built with
PHP_COMPILER_WARN_EXTERNAL_STUBS=1,the only warning emitted is
phpcompiler\ext\dom\builtinclasses::register, which is incidental andalso present in binaries that run correctly.
Likely blast radius
This probably accounts for most of the string cluster in #23779:
c04_concat,c11_strcmp,d04_concat_dim,e15_str_fns(which dies with the samefree(): invalid pointer), and possiblye23_implode.Environment
php-compiler:22.04-dev, PHP 8.2.32, LLVM 9. Reproduced on clean master544d1dca9(no locallib/modifications — verified). Built withphp bin/compile.php -o <bin> <file>.