]> granicus.if.org Git - php/commitdiff
Fix SSA NOP removal
authorNikita Popov <nikic@php.net>
Sun, 5 Jun 2016 21:00:32 +0000 (23:00 +0200)
committerNikita Popov <nikic@php.net>
Sun, 5 Jun 2016 21:00:32 +0000 (23:00 +0200)
NOPs need to be tracked in the shiftlist as well, as there may be
jumps to NOPs.

ext/opcache/Optimizer/dfa_pass.c
ext/opcache/tests/ssa_bug_002.phpt [new file with mode: 0644]

index 3be638eb927df626f9183525a360762ddd97a9b8..2ebbfbd14115491cc973935627ff24beca2f6917 100644 (file)
@@ -142,6 +142,7 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa)
                        i = b->start;
                        b->start = target;
                        while (i < end) {
+                               shiftlist[i] = i - target;
                                if (EXPECTED(op_array->opcodes[i].opcode != ZEND_NOP) ||
                                   /*keep NOP to support ZEND_VM_SMART_BRANCH */
                                   (i > 0 &&
@@ -165,7 +166,6 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa)
                                        if (i != target) {
                                                op_array->opcodes[target] = op_array->opcodes[i];
                                                ssa->ops[target] = ssa->ops[i];
-                                               shiftlist[i] = i - target;
                                        }
                                        target++;
                                }
diff --git a/ext/opcache/tests/ssa_bug_002.phpt b/ext/opcache/tests/ssa_bug_002.phpt
new file mode 100644 (file)
index 0000000..9ff6f79
--- /dev/null
@@ -0,0 +1,16 @@
+--TEST--
+Incorrect NOP removal on jump to NOP
+--FILE--
+<?php
+
+function test(int $i) : int {
+    if ($i == 1) {
+        $x = $i + 1;
+    }
+    return $i;
+}
+var_dump(test(42));
+
+?>
+--EXPECT--
+int(42)