]> granicus.if.org Git - php/commitdiff
a: try { ... } ≠ try { a: ... }
authorBob Weinand <bobwei9@hotmail.com>
Fri, 10 Jul 2015 21:29:07 +0000 (23:29 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Fri, 10 Jul 2015 21:29:07 +0000 (23:29 +0200)
Zend/tests/try/finally_goto_005.phpt [new file with mode: 0644]
Zend/zend_compile.c

diff --git a/Zend/tests/try/finally_goto_005.phpt b/Zend/tests/try/finally_goto_005.phpt
new file mode 100644 (file)
index 0000000..36b4155
--- /dev/null
@@ -0,0 +1,15 @@
+--TEST--
+There must be a difference between label: try { ... } and try { label: ... }
+--FILE--
+<?php
+
+label: try {
+       goto label;
+} finally {
+       print "success";
+       return; // don't loop
+}
+
+?>
+--EXPECT--
+success
index ce5d7481182feca644617d4f5b1e5e3346080d9e..3f773502d0fff5fa6069e41f0cac324af4647da3 100644 (file)
@@ -4060,14 +4060,29 @@ void zend_compile_try(zend_ast *ast) /* {{{ */
 
        uint32_t i;
        zend_op *opline;
-       uint32_t try_catch_offset = zend_add_try_element(
-               get_next_op_number(CG(active_op_array)));
+       uint32_t try_catch_offset;
        uint32_t *jmp_opnums = safe_emalloc(sizeof(uint32_t), catches->children, 0);
+       HashPosition hpos;
 
        if (catches->children == 0 && !finally_ast) {
                zend_error_noreturn(E_COMPILE_ERROR, "Cannot use try without catch or finally");
        }
 
+       /* label: try { } must not be equal to try { label: } */
+       if (CG(context).labels) {
+               zval *labelzv;
+               zend_hash_internal_pointer_end_ex(CG(context).labels, &hpos);
+               if ((labelzv = zend_hash_get_current_data_ex(CG(context).labels, &hpos))) {
+                       zend_label *label = Z_PTR_P(labelzv);
+                       if (label->opline_num == get_next_op_number(CG(active_op_array))) {
+                               /* using a NOP doesn't work here, it would be removed by opcache */
+                               zend_emit_jump(get_next_op_number(CG(active_op_array)) + 1);
+                       }
+               }
+       }
+
+       try_catch_offset = zend_add_try_element(get_next_op_number(CG(active_op_array)));
+
        zend_compile_stmt(try_ast);
 
        if (catches->children != 0) {