com php-src: Fixed bug #70207 (Finally is broken with opcache): NEWS ext/opcache/Optimizer/optimize_temp_vars_5.c ext/op cache/tests/bug70207.phpt
| From: | Anatol Belski | Date: | Mon, 10 Aug 2015 13:38:43 +0000 |
| Subject: | com php-src: Fixed bug #70207 (Finally is broken with opcache): NEWS ext/opcache/Optimizer/optimize_temp_vars_5.c ext/op cache/tests/bug70207.phpt | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-88616@lists.php.net to get a copy of this message | ||
Commit: 18fb424befc5c7e98b91a570752fe6e90a09b330
Author: Dmitry Stogov <dmitry@zend.com> Mon, 10 Aug 2015 16:38:43 +0300
Parents: aaf76387064e0ed16464bc843b9d31041bf831f0
Branches: PHP-7.0.0
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=18fb424befc5c7e98b91a570752fe6e90a09b330
Log:
Fixed bug #70207 (Finally is broken with opcache)
Bugs:
https://bugs.php.net/70207
Changed paths:
M NEWS
M ext/opcache/Optimizer/optimize_temp_vars_5.c
A ext/opcache/tests/bug70207.phpt
Diff:
diff --git a/NEWS b/NEWS
index a43b2a4..a29f54c 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 0e96ee8..172f9a1 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 0000000..c684ee6
--- /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--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+function bar() {
+ return "bar";
+}
+function foo() {
+ try { return bar(); }
+ finally { @fclose(null); }
+}
+
+var_dump(foo());
+?>
+--EXPECT--
+string(3) "bar"