]> granicus.if.org Git - php/commitdiff
Fix null check in sccp add_array_elem chain handling
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 21 May 2019 15:15:07 +0000 (17:15 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 21 May 2019 15:15:07 +0000 (17:15 +0200)
We need to check result_use rather than result_def for a null zval.
Previously we were later assuming that the null zval is really a
partial array, which does not go well.

ext/opcache/Optimizer/sccp.c
ext/opcache/tests/bug78015.phpt

index 22f835527b9f5ce1738ed22ece14b677a9e58f1a..1791f6a941dc3947179df4e6d60610b4836dce6f 100644 (file)
@@ -1285,7 +1285,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
                        /* We want to avoid keeping around intermediate arrays for each SSA variable in the
                         * ADD_ARRAY_ELEMENT chain. We do this by only keeping the array on the last opcode
                         * and use a NULL value everywhere else. */
-                       if (Z_TYPE(ctx->values[ssa_op->result_def]) == IS_NULL) {
+                       if (result && Z_TYPE_P(result) == IS_NULL) {
                                SET_RESULT_BOT(result);
                                return;
                        }
index a9feb82fb4c17e42dd019e1881a562bda1e6ebc2..9bb416e7b396cf7de6b83f777a05e64810622d31 100644 (file)
@@ -58,6 +58,19 @@ function test7() {
     return $y;
 }
 
+function test8($array) {
+    $i = 0;
+    $ret = [[]];
+    foreach ($array as $_) {
+      $i++;
+      $ret = [[
+        'x' => 0,
+        'y' => $i,
+      ]];
+    }
+    return $ret[0];
+}
+
 var_dump(test1());
 var_dump(test2());
 var_dump(test3());
@@ -65,6 +78,7 @@ var_dump(test4());
 var_dump(test5());
 var_dump(test6());
 var_dump(test7());
+var_dump(test8([1]));
 
 ?>
 --EXPECTF--
@@ -83,3 +97,9 @@ bool(true)
 Notice: Array to string conversion in %s on line %d
 string(11) "Arrayfoobar"
 int(2)
+array(2) {
+  ["x"]=>
+  int(0)
+  ["y"]=>
+  int(1)
+}