summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-05-28 16:14:46 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-05-28 16:15:37 +0200
commitf19dd674e012639f8511ff2e531f24e74ef701ac (patch)
tree49157cd9688744206b041ec4e2258081fa279c6c
parent6738241aece97979bdb7531babcfdf12e3c4b45b (diff)
downloadphp-git-f19dd674e012639f8511ff2e531f24e74ef701ac.tar.gz
SCCP: Fix handling of ASSIGN_OBJ_REF
The generic BOT handling is not away of OP_DATA, so need to handle this opcode before we get to that.
-rw-r--r--ext/opcache/Optimizer/sccp.c21
-rw-r--r--ext/opcache/tests/opt/sccp_029.phpt27
2 files changed, 38 insertions, 10 deletions
diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c
index e81c99d61b..e09d5d6849 100644
--- a/ext/opcache/Optimizer/sccp.c
+++ b/ext/opcache/Optimizer/sccp.c
@@ -1440,6 +1440,17 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
SET_RESULT_BOT(result);
}
return;
+ case ZEND_ASSIGN_STATIC_PROP_REF:
+ case ZEND_ASSIGN_OBJ_REF:
+ /* Handled here because we also need to BOT the OP_DATA operand, while the generic
+ * code below will not do so. */
+ SET_RESULT_BOT(result);
+ SET_RESULT_BOT(op1);
+ SET_RESULT_BOT(op2);
+ opline++;
+ ssa_op++;
+ SET_RESULT_BOT(op1);
+ break;
}
if ((op1 && IS_BOT(op1)) || (op2 && IS_BOT(op2))) {
@@ -1915,16 +1926,6 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
SET_RESULT_BOT(result);
break;
}
- case ZEND_ASSIGN_STATIC_PROP_REF:
- case ZEND_ASSIGN_OBJ_REF:
- SET_RESULT_BOT(result);
- SET_RESULT_BOT(op1);
- SET_RESULT_BOT(op2);
- opline++;
- ssa_op++;
- op1 = get_op1_value(ctx, opline, ssa_op);
- SET_RESULT_BOT(op1);
- break;
default:
{
/* If we have no explicit implementation return BOT */
diff --git a/ext/opcache/tests/opt/sccp_029.phpt b/ext/opcache/tests/opt/sccp_029.phpt
new file mode 100644
index 0000000000..3a16477711
--- /dev/null
+++ b/ext/opcache/tests/opt/sccp_029.phpt
@@ -0,0 +1,27 @@
+--TEST--
+SCCP 029: Don't propagate assignments to references to typed properties
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+opcache.preload=
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+class Test {
+ public string $x = "x";
+}
+function test() {
+ $test = new Test();
+ $ref = "y";
+ $test->x =& $ref;
+ $ref = 42;
+ var_dump($ref);
+}
+test();
+
+?>
+--EXPECT--
+string(2) "42"