From 6cc53981e5b69a8c9cba267a6dcbcd9569c928b6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 29 Aug 2019 14:33:31 +0200 Subject: [PATCH] Addref static vars when not copying private method While we don't need to give this method separate static vars, we do still need to perform an addref, as there will be a corresponding delref in the dtor. --- ...atic_variable_in_private_trait_method.phpt | 35 +++++++++++++++++++ Zend/zend_inheritance.c | 12 +++++-- 2 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 Zend/tests/static_variable_in_private_trait_method.phpt diff --git a/Zend/tests/static_variable_in_private_trait_method.phpt b/Zend/tests/static_variable_in_private_trait_method.phpt new file mode 100644 index 0000000000..0d842c857c --- /dev/null +++ b/Zend/tests/static_variable_in_private_trait_method.phpt @@ -0,0 +1,35 @@ +--TEST-- +Behavior of static variable in private trait method +--FILE-- + +--EXPECT-- +object(stdClass)#1 (0) { +} +object(stdClass)#2 (0) { +} diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index f79f295f81..9c8acca865 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -96,11 +96,19 @@ static zend_always_inline zend_function *zend_duplicate_function(zend_function * (*func->op_array.refcount)++; } if (is_interface - || EXPECTED(!func->op_array.static_variables) - || (func->op_array.fn_flags & ZEND_ACC_PRIVATE)) { + || EXPECTED(!func->op_array.static_variables)) { /* reuse the same op_array structure */ return func; } + if (func->op_array.fn_flags & ZEND_ACC_PRIVATE) { + /* For private methods we reuse the same op_array structure even if + * static variables are used, because it will not end up being used + * anyway. However we still need to addref as the dtor will delref. */ + if (!(GC_FLAGS(func->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(func->op_array.static_variables); + } + return func; + } return zend_duplicate_user_function(func); } } -- 2.40.0