Category
bug · AOT wrong output · DateTime fluent mutate
Problem
Chained mutable DateTime::modify() applies only the first relative change for later format() / reads. Separate statements on the same local match Zend; fluent chains do not.
| Repro |
Zend 8.2 |
AOT (master @ 048672b) |
$d=new DateTime('2024-06-01'); $d->modify('+1 day')->modify('+2 hours'); echo $d->format('Y-m-d H:i:s'); |
2024-06-02 02:00:00 |
2024-06-02 00:00:00 |
$d->modify('+2 hours')->modify('+1 day'); |
2024-06-02 02:00:00 |
2024-06-01 02:00:00 |
$d->modify('+1 day'); $d->modify('+2 hours'); (separate) |
2024-06-02 02:00:00 |
match |
Root cause: first modify publishes compileTimeDateTimeTimestamp on $d; the chain continuation mutates via the return value-box (runtime path) and updates object props but does not invalidate $d's stamp. format() prefers the stale stamp (#33911).
php-src reference
PHP implementation target
ext/standard/JitDateMutation.php — on mutable runtime modify, invalidate all DateTime compile-time stamps / dateTimeLocalInstants so reads use __dt_timestamp (peer #33911 invalidate after runtime add/sub)
Repro
./script/aot-smoke.sh # must stay 8/8
./script/docker-exec.sh -- bash -lc 'php bin/compile.php -o /tmp/m.bin test/repro/issue_XXXX_datetime_modify_chain_aot.php && /tmp/m.bin'
Done when
lane overflow: #32122 / #31968 children closed; no open AOT crash IR; discovered via differential probe.
Category
bug· AOT wrong output · DateTime fluent mutateProblem
Chained mutable
DateTime::modify()applies only the first relative change for laterformat()/ reads. Separate statements on the same local match Zend; fluent chains do not.$d=new DateTime('2024-06-01'); $d->modify('+1 day')->modify('+2 hours'); echo $d->format('Y-m-d H:i:s');2024-06-02 02:00:002024-06-02 00:00:00$d->modify('+2 hours')->modify('+1 day');2024-06-02 02:00:002024-06-01 02:00:00$d->modify('+1 day'); $d->modify('+2 hours');(separate)2024-06-02 02:00:00Root cause: first
modifypublishescompileTimeDateTimeTimestampon$d; the chain continuation mutates via the return value-box (runtime path) and updates object props but does not invalidate$d's stamp.format()prefers the stale stamp (#33911).php-src reference
ext/date/php_date.c—zim_DateTime_modifyreturns$this; fluent chains share one objectPHP implementation target
ext/standard/JitDateMutation.php— on mutable runtimemodify, invalidate all DateTime compile-time stamps /dateTimeLocalInstantsso reads use__dt_timestamp(peer#33911invalidate after runtime add/sub)Repro
Done when
./script/aot-smoke.sh8/8lane overflow: #32122 / #31968 children closed; no open AOT crash IR; discovered via differential probe.