]> granicus.if.org Git - php/commitdiff
Fixed bug #77743
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 18 Mar 2019 09:49:53 +0000 (10:49 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 18 Mar 2019 09:49:53 +0000 (10:49 +0100)
NEWS
ext/opcache/Optimizer/zend_ssa.c
ext/opcache/tests/bug77743.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 88f91cfe730626ae31358db018792d93355f0107..abf5a572d39f125d50105447fd683a3f7145ba97 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -35,6 +35,8 @@ PHP                                                                        NEWS
 - Opcache:
   . Fixed bug #77691 (Opcache passes wrong value for inline array push
     assignments). (Nikita)
+  . Fixed bug #77743 (Incorrect pi node insertion for jmpznz with identical
+    successors). (Nikita)
 
 - sodium:
   . Fixed bug #77646 (sign_detached() strings not terminated). (Frank)
index 015c6bc0d5d2df9c225063bf09e0e53cac67c5ba..d4ad655895ab789cda6f4d0e5aec631af7474792 100644 (file)
@@ -54,6 +54,14 @@ static zend_bool needs_pi(const zend_op_array *op_array, zend_dfg *dfg, zend_ssa
                return 0;
        }
 
+       /* Make sure that both sucessors of the from block aren't the same. Pi nodes are associated
+        * with predecessor blocks, so we can't distinguish which edge the pi belongs to. */
+       from_block = &ssa->cfg.blocks[from];
+       ZEND_ASSERT(from_block->successors_count == 2);
+       if (from_block->successors[0] == from_block->successors[1]) {
+               return 0;
+       }
+
        to_block = &ssa->cfg.blocks[to];
        if (to_block->predecessors_count == 1) {
                /* Always place pi if one predecessor (an if branch) */
@@ -62,8 +70,6 @@ static zend_bool needs_pi(const zend_op_array *op_array, zend_dfg *dfg, zend_ssa
 
        /* Check that the other successor of the from block does not dominate all other predecessors.
         * If it does, we'd probably end up annihilating a positive+negative pi assertion. */
-       from_block = &ssa->cfg.blocks[from];
-       ZEND_ASSERT(from_block->successors_count == 2);
        other_successor = from_block->successors[0] == to
                ? from_block->successors[1] : from_block->successors[0];
        return !dominates_other_predecessors(&ssa->cfg, to_block, other_successor, from);
diff --git a/ext/opcache/tests/bug77743.phpt b/ext/opcache/tests/bug77743.phpt
new file mode 100644 (file)
index 0000000..61627b1
--- /dev/null
@@ -0,0 +1,34 @@
+--TEST--
+Bug #77743: Incorrect pi node insertion for jmpznz with identical successors
+--FILE--
+<?php
+class Toto
+{
+    public function process1()
+    {
+        $keep_products = [1, 2, 3, 4];
+        foreach ($keep_products as $k => $v)
+        {
+            $id_country = myRet(45);
+            if ($id_country === false && false)
+            {
+            }
+
+            var_dump($id_country === false);
+        }
+    }
+}
+
+function myRet($x){
+    return $x;
+}
+
+$toto = new Toto();
+$toto->process1();
+
+?>
+--EXPECT--
+bool(false)
+bool(false)
+bool(false)
+bool(false)