Summary
A typed array property declared with a literal default is empty whenever it is read under AOT.
Silent wrong output — exit 0, plausible values.
VM is unaffected (6/6).
Reproducers
<?php
class C { private array $c = [1,2]; public function m(): int { return count($this->c); } }
echo (new C)->m(), "\n";
<?php
class C { private array $c = [7,8]; public function m(): int { return $this->c[1]; } }
echo (new C)->m(), "\n";
It is the property, not count() and not visibility
| case |
AOT |
count($this->c) — private array prop |
0 |
count($this->c) — public array prop |
0 |
$x = $this->c; count($x) — via a local |
0 |
$this->c[1] — element read, no count() |
0 |
count($o->c) — read from outside the class |
0 |
count($a) — plain local array, no class |
ok, 2 |
So count() is fine on a local; visibility is irrelevant; copying to a local first does not help;
and element access fails the same way. The array property simply does not carry its declared
default into the object.
Deterministic — 0/3 runs matched under --repeat 3 on every failing case.
Why it matters
private array $items = []; with later population is one of the most common shapes in
object-oriented PHP. Anything reading such a property before reassignment sees an empty array and
computes wrong answers silently.
Context
Found while re-validating #23059 (task: "re-validate #23059 broadly"). A class with properties
followed by a method dense with locals produced pqx10 instead of pqx12 — the trailing
count($this->c) term was 0.
Environment: php-compiler:22.04-dev, PHP 8.2.32, LLVM 9, php bin/compile.php -o <bin> <file>,
master 11092acbb. Reproducers in build/micro/cnt/.
Summary
A typed array property declared with a literal default is empty whenever it is read under AOT.
Silent wrong output — exit 0, plausible values.
VM is unaffected (6/6).
Reproducers
It is the property, not
count()and not visibilitycount($this->c)— private array propcount($this->c)— public array prop$x = $this->c; count($x)— via a local$this->c[1]— element read, nocount()count($o->c)— read from outside the classcount($a)— plain local array, no classSo
count()is fine on a local; visibility is irrelevant; copying to a local first does not help;and element access fails the same way. The array property simply does not carry its declared
default into the object.
Deterministic — 0/3 runs matched under
--repeat 3on every failing case.Why it matters
private array $items = [];with later population is one of the most common shapes inobject-oriented PHP. Anything reading such a property before reassignment sees an empty array and
computes wrong answers silently.
Context
Found while re-validating #23059 (task: "re-validate #23059 broadly"). A class with properties
followed by a method dense with locals produced
pqx10instead ofpqx12— the trailingcount($this->c)term was0.Environment:
php-compiler:22.04-dev, PHP 8.2.32, LLVM 9,php bin/compile.php -o <bin> <file>,master
11092acbb. Reproducers inbuild/micro/cnt/.