[php-src] PR #24451: JIT: Fix OP_DATA read from an unwritten slot in zend_jit_assign_dim_op()

From: Date: Tue, 20 Oct 2026 03:17:21 +0000
Subject: [php-src] PR #24451: JIT: Fix OP_DATA read from an unwritten slot in zend_jit_assign_dim_op()
Groups: php.git-pulls 
Request: Send a blank email to git-pulls+get-39621@lists.php.net to get a copy of this message
Pull Request: https://github.com/php/php-src/pull/24451 Author: waroad In zend_jit_assign_dim_op(), when the array element may be a reference, the cold branch for typed references spills the OP_DATA register to its stack slot and then sets op3_addr = real_addr;. That reassignment also applies to the code emitted after the branch, so the normal +=/%=/... path then reads the right-hand operand from a stack slot that is only written on the typed-reference path. With the tracing JIT, $a[0] += $i + 1 on an array parameter adds a stale value (prints int(3) instead of int(6)), and the %= variant from the issue can divide by a stale zero and dies with SIGFPE. A CV on the right ($a[0] += $i) is affected too, also with the default JIT counters. The fix passes real_addr to the helper call only, the same way zend_jit_assign_op() already does for its typed reference branch, and leaves op3_addr alone for the rest of the function. The new test ext/opcache/tests/jit/gh24437.phpt covers the undefined-key case, an element that is a reference, an element that is a typed reference, and the %= case. Without the fix the first two cases print 3 and 13 instead of 6 and 16, and the %= case crashes with an FPE; with it, the test passes. The reproducers from the issue now match opcache.jit=off. Here's the PR, as suggested. It is close to #24387: there a register wasn't loaded on all paths around the typed reference check; here the stack slot is written only on the typed-reference path but read on the normal one. zend_jit_assign_dim_op() already force-loads OP_DATA before the reference check, so the change from #24387 isn't needed here. Targets PHP-8.4, where I built and tested it (debug + ASan/UBSan build); ext/opcache/tests/jit passes in tracing and function mode. Fixes #24437. Found with an LLM-based testing tool; I wrote this fix with help from Claude and reviewed it myself.

« previous php.git-pulls (#39621) next »