From a79994e15750de579fe476ceca02b9afde93437f Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 29 Sep 2026 00:00:25 +0200 Subject: [PATCH 1/2] Fix __isset escape analysis causing misoptimization Co-authored-by: Arnaud Le Blanc <365207+arnaud-lb@users.noreply.github.com> --- Zend/Optimizer/escape_analysis.c | 2 ++ ext/opcache/tests/opt/dce_016.phpt | 50 ++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 ext/opcache/tests/opt/dce_016.phpt diff --git a/Zend/Optimizer/escape_analysis.c b/Zend/Optimizer/escape_analysis.c index 840a18341a0f..ee27832c7008 100644 --- a/Zend/Optimizer/escape_analysis.c +++ b/Zend/Optimizer/escape_analysis.c @@ -173,6 +173,7 @@ static bool is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, i && !ce->destructor && !ce->__get && !ce->__set + && !ce->__isset && !(ce->ce_flags & forbidden_flags) && (ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { return 1; @@ -242,6 +243,7 @@ static bool is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int va && !ce->destructor && !ce->__get && !ce->__set + && !ce->__isset && !ce->parent) { return 1; } diff --git a/ext/opcache/tests/opt/dce_016.phpt b/ext/opcache/tests/opt/dce_016.phpt new file mode 100644 index 000000000000..2185a4abfee7 --- /dev/null +++ b/ext/opcache/tests/opt/dce_016.phpt @@ -0,0 +1,50 @@ +--TEST-- +DCE must not remove assignments to properties of an object escaping through __isset +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +opcache.file_update_protection=0 +--EXTENSIONS-- +opcache +--FILE-- +foo); + $o->x = 42; +} + +f(); +var_dump($g->x); + +#[AllowDynamicProperties] +class F { + function __isset($n) { + $this->x = 2; + return true; + } +} + +function i() { + $o = new F; + $o->x = 1; + isset($o->foo); + var_dump($o->x); +} +i(); + +?> +--EXPECT-- +int(42) +int(2) From 68edb69ebad07f8f2bed718d05d779236bce37a0 Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 29 Sep 2026 00:02:52 +0200 Subject: [PATCH 2/2] Fix property hook escape analysis causing misoptimization Co-authored-by: Arnaud Le Blanc <365207+arnaud-lb@users.noreply.github.com> --- Zend/Optimizer/escape_analysis.c | 2 ++ ext/opcache/tests/opt/dce_017.phpt | 55 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 ext/opcache/tests/opt/dce_017.phpt diff --git a/Zend/Optimizer/escape_analysis.c b/Zend/Optimizer/escape_analysis.c index ee27832c7008..d99781283e6b 100644 --- a/Zend/Optimizer/escape_analysis.c +++ b/Zend/Optimizer/escape_analysis.c @@ -174,6 +174,7 @@ static bool is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, i && !ce->__get && !ce->__set && !ce->__isset + && !ce->num_hooked_props && !(ce->ce_flags & forbidden_flags) && (ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { return 1; @@ -244,6 +245,7 @@ static bool is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int va && !ce->__get && !ce->__set && !ce->__isset + && !ce->num_hooked_props && !ce->parent) { return 1; } diff --git a/ext/opcache/tests/opt/dce_017.phpt b/ext/opcache/tests/opt/dce_017.phpt new file mode 100644 index 000000000000..0cf8ad9bf366 --- /dev/null +++ b/ext/opcache/tests/opt/dce_017.phpt @@ -0,0 +1,55 @@ +--TEST-- +DCE must not remove assignments to properties of an object escaping through a property hook +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +opcache.file_update_protection=0 +--EXTENSIONS-- +opcache +--FILE-- +h; + $o->x = 42; +} + +g(); +var_dump($g->x); + +class E { + public $x = 0; + public $h { + set { + global $g; + $g = $this; + } + } +} + +function h() { + $o = new E; + $o->h = 1; + $o->x = 42; +} + +h(); +var_dump($g->x); + +?> +--EXPECT-- +int(42) +int(42)