Summary
In a chained subscript read, a miss on the first index (so the miss fallback becomes the receiver of the second read) segfaults: for a refcounted element type the null fallback materializes the scalar sentinel 0x7fff_ffff_ffff_fffe instead of a null container, and the consuming outer read then loads the array length header from that sentinel address and faults.
A miss on the second index alone behaves correctly (warns, yields empty string, exits 0, heap clean) — only a first-index miss whose fallback is consumed as a container crashes.
Environment
- elephc main
e63d5d337 (v0.26.0-158), macOS arm64 (Apple Silicon); PHP 8.4.23 as behavioral reference.
Repro
<?php
$a = [];
for ($i = 0; $i < 3; $i++) { $a[] = ['kw', 'word' . $i]; }
// Miss on the first index: the second read consumes the miss fallback.
$x = (string) $a[7][1];
echo 'x=' . $x . "\n";
echo 'done' . "\n";
elephc miss_inner.php && ./miss_inner # also reproduces with --heap-debug
Observed
Warning: Undefined array key 7
then SIGSEGV (exit 139). The two echo lines never run.
Expected (PHP 8.4.23)
Warning: Undefined array key 7 …
Warning: Trying to access array offset on null …
x=
done
exit 0.
Notes
Summary
In a chained subscript read, a miss on the first index (so the miss fallback becomes the receiver of the second read) segfaults: for a refcounted element type the null fallback materializes the scalar sentinel
0x7fff_ffff_ffff_fffeinstead of a null container, and the consuming outer read then loads the array length header from that sentinel address and faults.A miss on the second index alone behaves correctly (warns, yields empty string, exits 0, heap clean) — only a first-index miss whose fallback is consumed as a container crashes.
Environment
e63d5d337(v0.26.0-158), macOS arm64 (Apple Silicon); PHP 8.4.23 as behavioral reference.Repro
Observed
then SIGSEGV (exit 139). The two
echolines never run.Expected (PHP 8.4.23)
exit 0.
Notes
emit_array_get_null_fallback(src/codegen/lower_inst/arrays.rs, the_ =>arm) materializes the scalar sentinel for refcounted element types; the consumingarray_getthen executesemit_load_from_address(len, array_reg, 0)against the sentinel value as if it were an array pointer.$a[1][7](first read hits, second misses) warns and continues correctly.