]> granicus.if.org Git - php/commitdiff
Fixed bug #70241 (Skipped assertions affect Generator returns)
authorBob Weinand <bobwei9@hotmail.com>
Tue, 11 Aug 2015 20:12:06 +0000 (22:12 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Tue, 11 Aug 2015 20:12:06 +0000 (22:12 +0200)
NEWS
Zend/tests/bug70241.phpt [new file with mode: 0644]
Zend/zend_compile.c

diff --git a/NEWS b/NEWS
index 147b47b9e641fab8817e740bf4b490e9f0da7080..3d02db773cb46e94738f20a10e8db4c927f2d32f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,7 @@ PHP                                                                        NEWS
   . Fixed bug #69487 (SAPI may truncate POST data). (cmb)
   . Fixed bug #70198 (Checking liveness does not work as expected).
     (Shafreeck Sea, Anatol Belski)
+  . Fixed bug #70241 (Skipped assertions affect Generator returns). (Bob)
 
 - CLI server:
   . Fixed bug #66606 (Sets HTTP_CONTENT_TYPE but not CONTENT_TYPE).
diff --git a/Zend/tests/bug70241.phpt b/Zend/tests/bug70241.phpt
new file mode 100644 (file)
index 0000000..74218e9
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+Bug #70241 (Skipped assertions affect Generator returns)
+--INI--
+zend.assertions=-1
+--FILE--
+<?php
+
+function foo () {
+       assert(yield 1);
+       return null;
+}
+
+var_dump(foo() instanceof Generator);
+
+?>
+--EXPECT--
+bool(true)
index 606775a11ac03c28f2f179dd65138dbcd95fb59b..9c54245c4174b3d90940afa5172c93a0532ce0f4 100644 (file)
@@ -1128,6 +1128,32 @@ void zend_do_early_binding(void) /* {{{ */
 }
 /* }}} */
 
+static void zend_mark_function_as_generator() /* {{{ */
+{
+       if (!CG(active_op_array)->function_name) {
+               zend_error_noreturn(E_COMPILE_ERROR,
+                       "The \"yield\" expression can only be used inside a function");
+       }
+       if (CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+               const char *msg = "Generators may only declare a return type of Generator, Iterator or Traversable, %s is not permitted";
+               if (!CG(active_op_array)->arg_info[-1].class_name) {
+                       zend_error_noreturn(E_COMPILE_ERROR, msg,
+                               zend_get_type_by_const(CG(active_op_array)->arg_info[-1].type_hint));
+               }
+               if (!(ZSTR_LEN(CG(active_op_array)->arg_info[-1].class_name) == sizeof("Traversable")-1
+                               && zend_binary_strcasecmp(ZSTR_VAL(CG(active_op_array)->arg_info[-1].class_name), sizeof("Traversable")-1, "Traversable", sizeof("Traversable")-1) == 0) &&
+                       !(ZSTR_LEN(CG(active_op_array)->arg_info[-1].class_name) == sizeof("Iterator")-1
+                               && zend_binary_strcasecmp(ZSTR_VAL(CG(active_op_array)->arg_info[-1].class_name), sizeof("Iterator")-1, "Iterator", sizeof("Iterator")-1) == 0) &&
+                       !(ZSTR_LEN(CG(active_op_array)->arg_info[-1].class_name) == sizeof("Generator")-1
+                               && zend_binary_strcasecmp(ZSTR_VAL(CG(active_op_array)->arg_info[-1].class_name), sizeof("Generator")-1, "Generator", sizeof("Generator")-1) == 0)) {
+                       zend_error_noreturn(E_COMPILE_ERROR, msg, ZSTR_VAL(CG(active_op_array)->arg_info[-1].class_name));
+               }
+       }
+
+       CG(active_op_array)->fn_flags |= ZEND_ACC_GENERATOR;
+}
+/* }}} */
+
 ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array) /* {{{ */
 {
        if (op_array->early_binding != (uint32_t)-1) {
@@ -3041,6 +3067,22 @@ int zend_compile_func_cuf(znode *result, zend_ast_list *args, zend_string *lcnam
 }
 /* }}} */
 
+static void zend_compile_assert_side_effects(zend_ast *ast) /* {{{ */
+{
+       int i;
+       int children = zend_ast_is_list(ast) ? zend_ast_get_list(ast)->children : zend_ast_get_num_children(ast);
+
+       for (i = 0; i < children; i++) {
+               zend_ast *child = (zend_ast_is_list(ast) ? zend_ast_get_list(ast)->child : ast->child)[i];
+               if (child->kind == ZEND_AST_YIELD) {
+                       zend_mark_function_as_generator();
+               } else if (ast->kind >= ZEND_AST_IS_LIST_SHIFT) {
+                       zend_compile_assert_side_effects(child);
+               }
+       }
+}
+/* }}} */
+
 static int zend_compile_assert(znode *result, zend_ast_list *args, zend_string *name, zend_function *fbc) /* {{{ */
 {
        if (EG(assertions) >= 0) {
@@ -3081,6 +3123,8 @@ static int zend_compile_assert(znode *result, zend_ast_list *args, zend_string *
                }
                result->op_type = IS_CONST;
                ZVAL_TRUE(&result->u.constant);
+
+               zend_compile_assert_side_effects((zend_ast *) args);
        }
 
        return SUCCESS;
@@ -6186,32 +6230,6 @@ void zend_compile_exit(znode *result, zend_ast *ast) /* {{{ */
 }
 /* }}} */
 
-static void zend_mark_function_as_generator() /* {{{ */
-{
-       if (!CG(active_op_array)->function_name) {
-               zend_error_noreturn(E_COMPILE_ERROR,
-                       "The \"yield\" expression can only be used inside a function");
-       }
-       if (CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
-               const char *msg = "Generators may only declare a return type of Generator, Iterator or Traversable, %s is not permitted";
-               if (!CG(active_op_array)->arg_info[-1].class_name) {
-                       zend_error_noreturn(E_COMPILE_ERROR, msg,
-                               zend_get_type_by_const(CG(active_op_array)->arg_info[-1].type_hint));
-               }
-               if (!(ZSTR_LEN(CG(active_op_array)->arg_info[-1].class_name) == sizeof("Traversable")-1
-                               && zend_binary_strcasecmp(ZSTR_VAL(CG(active_op_array)->arg_info[-1].class_name), sizeof("Traversable")-1, "Traversable", sizeof("Traversable")-1) == 0) &&
-                       !(ZSTR_LEN(CG(active_op_array)->arg_info[-1].class_name) == sizeof("Iterator")-1
-                               && zend_binary_strcasecmp(ZSTR_VAL(CG(active_op_array)->arg_info[-1].class_name), sizeof("Iterator")-1, "Iterator", sizeof("Iterator")-1) == 0) &&
-                       !(ZSTR_LEN(CG(active_op_array)->arg_info[-1].class_name) == sizeof("Generator")-1
-                               && zend_binary_strcasecmp(ZSTR_VAL(CG(active_op_array)->arg_info[-1].class_name), sizeof("Generator")-1, "Generator", sizeof("Generator")-1) == 0)) {
-                       zend_error_noreturn(E_COMPILE_ERROR, msg, ZSTR_VAL(CG(active_op_array)->arg_info[-1].class_name));
-               }
-       }
-
-       CG(active_op_array)->fn_flags |= ZEND_ACC_GENERATOR;
-}
-/* }}} */
-
 void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */
 {
        zend_ast *value_ast = ast->child[0];