]> granicus.if.org Git - php/commitdiff
SCCP: Fix leak when determining TYPE_CHECK from type info
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 29 May 2019 14:47:19 +0000 (16:47 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 29 May 2019 14:47:19 +0000 (16:47 +0200)
As TYPE_CHECK is the only opcode where we do something like this,
I'm adding this hack.

ext/opcache/Optimizer/sccp.c
ext/opcache/tests/opt/sccp_030.phpt [new file with mode: 0644]

index b25f3a08e7c0ed88de3c4131a1e193e64bd91b24..ac3247076eaade9f26c13191da5ba2afb4a115ee 100644 (file)
@@ -2203,6 +2203,14 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
                                zend_ssa_remove_result_def(ssa, ssa_op);
                                if (opline->opcode == ZEND_DO_ICALL) {
                                        removed_ops = remove_call(ctx, opline, ssa_op);
+                               } else if (opline->opcode == ZEND_TYPE_CHECK
+                                               && !value_known(&ctx->values[ssa_op->op1_use])) {
+                                       /* For TYPE_CHECK we may compute the result value without knowing the
+                                        * operand, based on type inference information. Make sure the operand is
+                                        * freed and leave further cleanup to DCE. */
+                                       opline->opcode = ZEND_FREE;
+                                       opline->result_type = IS_UNUSED;
+                                       removed_ops++;
                                } else {
                                        zend_ssa_remove_instr(ssa, opline, ssa_op);
                                        removed_ops++;
diff --git a/ext/opcache/tests/opt/sccp_030.phpt b/ext/opcache/tests/opt/sccp_030.phpt
new file mode 100644 (file)
index 0000000..fbaecc1
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+SCCP 030: TYPE_CHECK inferred from type inference info
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+opcache.opt_debug_level=0
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+var_dump(is_string(sys_get_temp_dir()));
+
+?>
+--EXPECT--
+bool(true)