]> granicus.if.org Git - php/commitdiff
Fixed bug #80742 (Opcache JIT makes some boolean logic unexpectedly be true)
authorDmitry Stogov <dmitry@zend.com>
Tue, 16 Feb 2021 17:02:12 +0000 (20:02 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 16 Feb 2021 17:02:12 +0000 (20:02 +0300)
NEWS
ext/opcache/jit/zend_jit_x86.dasc
ext/opcache/tests/jit/bug80742.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index b39899c085deb799d5a62afba58c45a0a659ec21..d8a37b4323b47ce312b66c352c8731ad39c065c2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,8 @@ PHP                                                                        NEWS
   . Fixed bug #80634 (write_property handler of internal classes is skipped on
     preloaded JITted code). (Dmitry)
   . Fixed bug #80682 (opcache doesn't honour pcre.jit option). (Remi)
+  . Fixed bug #80742 (Opcache JIT makes some boolean logic unexpectedly be
+    true). (Dmitry)
 
 - OpenSSL:
   . Fixed bug #80747 (Providing RSA key size < 512 generates key that crash
index 93e95886aa095e6283fe402b52f1fa3be3b03bb7..ceaa2b9a5a9c89c89b218087ff820ce974ecc047 100644 (file)
@@ -7138,7 +7138,7 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z
                                        break;
                                case ZEND_IS_NOT_IDENTICAL:
                                        if (exit_addr) {
-                                               |1:
+                                               | jp >1
                                                | je &exit_addr
                                                |1:
                                        } else {
@@ -7231,10 +7231,10 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z
                                case ZEND_IS_NOT_EQUAL:
                                case ZEND_IS_NOT_IDENTICAL:
                                        |       jp >1
-                                       |       SET_ZVAL_TYPE_INFO res_addr, IS_TRUE
+                                       |       SET_ZVAL_TYPE_INFO res_addr, IS_FALSE
                                        |       je => target_label
                                        |1:
-                                       |       SET_ZVAL_TYPE_INFO res_addr, IS_FALSE
+                                       |       SET_ZVAL_TYPE_INFO res_addr, IS_TRUE
                                        break;
                                case ZEND_IS_SMALLER:
                                        if (swap) {
diff --git a/ext/opcache/tests/jit/bug80742.phpt b/ext/opcache/tests/jit/bug80742.phpt
new file mode 100644 (file)
index 0000000..a86fe10
--- /dev/null
@@ -0,0 +1,98 @@
+--TEST--
+Bug #80742 (Opcache JIT makes some boolean logic unexpectedly be true)
+--FILE--
+<?php
+
+function checkGroundState(float $movY, float $dy) : void{
+       var_dump($movY != $dy, $movY < 0, ($movY != $dy and $movY < 0));
+       var_dump("wow!");
+}
+
+checkGroundState(0, 0);
+
+function eq(float $a, float $b, $c, $d) {
+       if ($a == $b) {
+               echo 1;
+       }
+       if ($a == $b) {
+       } else {
+               echo 2;
+       }
+       if ($a != $b) {
+               echo 3;
+       }
+       if ($a != $b) {
+       } else {
+               echo 4;
+       }
+       if ($a === $b) {
+               echo 5;
+       }
+       if ($a === $b) {
+       } else {
+               echo 6;
+       }
+       if ($a !== $b) {
+               echo 7;
+       }
+       if ($a !== $b) {
+       } else {
+               echo 8;
+       }
+       echo "\n";
+       var_dump(
+               $a == $b && $c,
+               $a != $b && $c,
+               $a === $b && $c,
+               $a !== $b && $c,);
+       var_dump(
+               $a == $b || $d,
+               $a != $b || $d,
+               $a === $b || $d,
+               $a !== $b || $d);
+}
+eq(3.0, 3.0, true, false);
+eq(3.0,        2.0, true, false);
+eq(3.0, NAN, true, false);
+eq(NAN, NAN, true, false);
+--EXPECT--
+bool(false)
+bool(false)
+bool(false)
+string(4) "wow!"
+1458
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+2367
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+2367
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+2367
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)