From 1bb7ee32079224ea99f8399bae0ac5661f278a0c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 28 Sep 2021 14:12:58 +0200 Subject: [PATCH] Fix ASSIGN_DIM result inference with typed refs Same issue as with ASSIGN. Also make the handling for ASSIGN more precise, we can only have conversions between scalar values. --- Zend/tests/assign_typed_ref_result.phpt | 8 ++++++++ ext/opcache/Optimizer/zend_inference.c | 10 +++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Zend/tests/assign_typed_ref_result.phpt b/Zend/tests/assign_typed_ref_result.phpt index 9075db50376..722b8932bed 100644 --- a/Zend/tests/assign_typed_ref_result.phpt +++ b/Zend/tests/assign_typed_ref_result.phpt @@ -11,8 +11,16 @@ function test() { $ref =& $obj->prop; var_dump($ref = 0); } +function test2() { + $obj = new Test; + $ary = []; + $ary[0] =& $obj->prop; + var_dump($ary[0] = 0); +} test(); +test2(); ?> --EXPECT-- string(1) "0" +string(1) "0" diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index d5ade4e0ff0..fab49f2bb3b 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -2757,6 +2757,10 @@ static zend_always_inline int _zend_update_type_info( if (OP1_DATA_INFO() & MAY_BE_UNDEF) { tmp |= MAY_BE_NULL; } + if (t1 & MAY_BE_ARRAY_OF_REF) { + /* A scalar type conversion may occur when assigning to a typed reference. */ + tmp |= MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING; + } } if (t1 & MAY_BE_OBJECT) { tmp |= MAY_BE_REF; @@ -2866,9 +2870,9 @@ static zend_always_inline int _zend_update_type_info( } if (ssa_op->result_def >= 0) { 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; + /* A scalar type conversion may occur when assigning to a typed reference. */ + tmp &= ~MAY_BE_REF; + tmp |= MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_RC1|MAY_BE_RCN; } UPDATE_SSA_TYPE(tmp, ssa_op->result_def); COPY_SSA_OBJ_TYPE(ssa_op->op2_use, ssa_op->result_def);