Commit cba864da359 for php

commit cba864da3594849b2211be94b7299a7cbcbe32a3
Author: ndossche <7771979+ndossche@users.noreply.github.com>
Date:   Sat Sep 26 14:26:57 2026 +0200

    Fix incorrect DCE due to unsound escape analysis

    Closes GH-23924.

diff --git a/NEWS b/NEWS
index c747dbcdcf5..d36d4b56bfc 100644
--- a/NEWS
+++ b/NEWS
@@ -75,6 +75,7 @@ PHP                                                                        NEWS
   . Fixed bug GH-23637 (PHP-FPM worker SIGSEGV: run_time_cache map_ptr offset
     beyond CG(map_ptr_last) when a class is reached through the CE cache).
     (David Carlier)
+  . Fix incorrect DCE due to unsound escape analysis. (ndossche)

 - PCNTL:
   . Fixed pcntl_signal_dispatch() dropping the queued signals when it runs while
diff --git a/Zend/Optimizer/escape_analysis.c b/Zend/Optimizer/escape_analysis.c
index 840a18341a0..352d647e925 100644
--- a/Zend/Optimizer/escape_analysis.c
+++ b/Zend/Optimizer/escape_analysis.c
@@ -300,8 +300,10 @@ static bool is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int v
 			case ZEND_ASSIGN_STATIC_PROP_OP:
 			case ZEND_ASSIGN_DIM:
 			case ZEND_ASSIGN_OBJ:
-			case ZEND_ASSIGN_OBJ_REF:
 				break;
+			case ZEND_ASSIGN_OBJ_REF:
+				/* The property may now alias a variable outside of the object. */
+				return true;
 			case ZEND_PRE_INC_OBJ:
 			case ZEND_PRE_DEC_OBJ:
 			case ZEND_POST_INC_OBJ:
diff --git a/ext/opcache/tests/opt/dce_015.phpt b/ext/opcache/tests/opt/dce_015.phpt
new file mode 100644
index 00000000000..a09284cab36
--- /dev/null
+++ b/ext/opcache/tests/opt/dce_015.phpt
@@ -0,0 +1,45 @@
+--TEST--
+DCE must not remove assignments to properties of an object holding a reference
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+opcache.file_update_protection=0
+--EXTENSIONS--
+opcache
+--FILE--
+<?php
+
+class Holder {
+    public $untyped = 0;
+    public int $typed = 0;
+}
+
+class Target {
+    public $untyped = 0;
+    public int $typed = 0;
+}
+
+function untyped() {
+    $h = new Holder;
+    $t = new Target;
+    $h->untyped = &$t->untyped;
+    $h->untyped = 5;
+    var_dump($t->untyped);
+}
+
+function typed() {
+    $h = new Holder;
+    $t = new Target;
+    $h->typed = &$t->typed;
+    $h->typed = 5;
+    var_dump($t->typed);
+}
+
+untyped();
+typed();
+
+?>
+--EXPECT--
+int(5)
+int(5)