]> granicus.if.org Git - php/commitdiff
Fix bug #69871 (short-circuiting failure with smart_branch)
authorBob Weinand <bobwei9@hotmail.com>
Thu, 18 Jun 2015 13:58:46 +0000 (15:58 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Thu, 18 Jun 2015 13:59:00 +0000 (15:59 +0200)
Zend/tests/bug69871.phpt [new file with mode: 0644]
Zend/zend_execute.c

diff --git a/Zend/tests/bug69871.phpt b/Zend/tests/bug69871.phpt
new file mode 100644 (file)
index 0000000..7b87a75
--- /dev/null
@@ -0,0 +1,15 @@
+--TEST--
+Bug #69871 (Short-circuiting failure with smart_branch)
+--FILE--
+<?php
+
+$a = true;
+if (isset($a) && 0) {
+       var_dump(true);
+} else {
+       var_dump(false);
+}
+
+?>
+--EXPECT--
+bool(false)
index 9190eff2c346b4d606bba57504486ed82b4b6052..27274d334dd17686b031159cb338eb91e1e92e91 100644 (file)
@@ -2428,9 +2428,21 @@ static zend_always_inline zend_generator *zend_get_running_generator(zend_execut
 # define ZEND_VM_SMART_BRANCH(_result, _check) do { \
                int __result; \
                if (EXPECTED((opline+1)->opcode == ZEND_JMPZ)) { \
-                       __result = (_result); \
+                       if (UNEXPECTED((opline+1)->op1_type == IS_CONST)) { \
+                               zend_uchar __type = Z_TYPE_P(EX_CONSTANT((opline+1)->op1)); \
+                               ZEND_ASSERT(__type == IS_TRUE || __type == IS_FALSE); /* assume boolean */ \
+                               __result = __type == IS_TRUE; \
+                       } else { \
+                               __result = (_result); \
+                       } \
                } else if (EXPECTED((opline+1)->opcode == ZEND_JMPNZ)) { \
-                       __result = !(_result); \
+                       if (UNEXPECTED((opline+1)->op1_type == IS_CONST)) { \
+                               zend_uchar __type = Z_TYPE_P(EX_CONSTANT((opline+1)->op1)); \
+                               ZEND_ASSERT(__type == IS_TRUE || __type == IS_FALSE); /* assume boolean */ \
+                               __result = __type != IS_TRUE; \
+                       } else { \
+                               __result = !(_result); \
+                       } \
                } else { \
                        break; \
                } \