1
0
mirror of https://github.com/php/php-src.git synced 2026-04-25 08:58:28 +02:00

Fix type inference and SCCP with typed references

We can't assume that the return value will be the same as the RHS
if typed references are involved.
This commit is contained in:
Nikita Popov
2021-09-28 12:58:14 +02:00
parent 0391c55b0c
commit d8c2ff6486
3 changed files with 28 additions and 4 deletions
+18
View File
@@ -0,0 +1,18 @@
--TEST--
Result of assigning to typed reference
--FILE--
<?php
class Test {
public ?string $prop;
}
function test() {
$obj = new Test;
$ref =& $obj->prop;
var_dump($ref = 0);
}
test();
?>
--EXPECT--
string(1) "0"
+4 -3
View File
@@ -1013,14 +1013,15 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
switch (opline->opcode) {
case ZEND_ASSIGN:
/* The value of op1 is irrelevant here, because we are overwriting it
* -- unless it can be a reference, in which case we propagate a BOT. */
* -- unless it can be a reference, in which case we propagate a BOT.
* The result is also BOT in this case, because it might be a typed reference. */
if (IS_BOT(op1) && (ctx->scdf.ssa->var_info[ssa_op->op1_use].type & MAY_BE_REF)) {
SET_RESULT_BOT(op1);
SET_RESULT_BOT(result);
} else {
SET_RESULT(op1, op2);
SET_RESULT(result, op2);
}
SET_RESULT(result, op2);
return;
case ZEND_TYPE_CHECK:
/* We may be able to evaluate TYPE_CHECK based on type inference info,
+6 -1
View File
@@ -2879,7 +2879,12 @@ static zend_always_inline int _zend_update_type_info(
COPY_SSA_OBJ_TYPE(ssa_op->op2_use, ssa_op->op1_def);
}
if (ssa_op->result_def >= 0) {
UPDATE_SSA_TYPE(tmp & ~MAY_BE_REF, ssa_op->result_def);
if (tmp & MAY_BE_REF) {
/* Assignment to typed reference may change type.
* Be conservative and don't assume anything. */
tmp = MAY_BE_RC1|MAY_BE_RCN|MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
}
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
COPY_SSA_OBJ_TYPE(ssa_op->op2_use, ssa_op->result_def);
}
break;