From 18fb424befc5c7e98b91a570752fe6e90a09b330 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 10 Aug 2015 16:38:43 +0300 Subject: [PATCH] Fixed bug #70207 (Finally is broken with opcache) --- NEWS | 1 + ext/opcache/Optimizer/optimize_temp_vars_5.c | 32 +++++++++++++++++++- ext/opcache/tests/bug70207.phpt | 23 ++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/bug70207.phpt diff --git a/NEWS b/NEWS index a43b2a4399..a29f54cbf0 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ PHP NEWS - Core: . Fixed bug #70223 (Incrementing value returned by magic getter). (Laruence) . Fixed bug #70215 (Segfault when __invoke is static). (Bob) + . Fixed bug #70207 (Finally is broken with opcache). (Laruence, Dmitry) - CLI server: . Fixed bug #66606 (Sets HTTP_CONTENT_TYPE but not CONTENT_TYPE). diff --git a/ext/opcache/Optimizer/optimize_temp_vars_5.c b/ext/opcache/Optimizer/optimize_temp_vars_5.c index 0e96ee8624..172f9a1a62 100644 --- a/ext/opcache/Optimizer/optimize_temp_vars_5.c +++ b/ext/opcache/Optimizer/optimize_temp_vars_5.c @@ -101,7 +101,37 @@ void optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *c } } else { if (!zend_bitset_in(valid_T, currT)) { - GET_AVAILABLE_T(); + int use_new_var = 0; + + /* Code in "finally" blocks may modify temorary variables. + * We allocate new temporaries for values that need to + * relive FAST_CALLs. + */ + if ((op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) && + (opline->opcode == ZEND_RETURN || + opline->opcode == ZEND_RETURN_BY_REF || + opline->opcode == ZEND_FREE || + opline->opcode == ZEND_FE_FREE)) { + zend_op *curr = opline; + + while (--curr >= end) { + if (curr->opcode == ZEND_FAST_CALL) { + use_new_var = 1; + break; + } else if (curr->opcode != ZEND_FREE && + curr->opcode != ZEND_FE_FREE && + curr->opcode != ZEND_VERIFY_RETURN_TYPE && + curr->opcode != ZEND_DISCARD_EXCEPTION) { + break; + } + } + } + if (use_new_var) { + i = ++max; + zend_bitset_incl(taken_T, i); + } else { + GET_AVAILABLE_T(); + } map_T[currT] = i; zend_bitset_incl(valid_T, currT); } diff --git a/ext/opcache/tests/bug70207.phpt b/ext/opcache/tests/bug70207.phpt new file mode 100644 index 0000000000..c684ee6d33 --- /dev/null +++ b/ext/opcache/tests/bug70207.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #70207 Finally is broken with opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +opcache.file_update_protection=0 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(3) "bar" -- 2.50.1