Merge branch 'PHP-7.3' into PHP-7.4

This commit is contained in:
Nikita Popov 2019-05-15 14:36:45 +02:00
commit 806db1a793
2 changed files with 103 additions and 1 deletions

View File

@ -680,7 +680,13 @@ static inline int ct_eval_isset_isempty(zval *result, uint32_t extended_value, z
}
static inline void ct_eval_type_check(zval *result, uint32_t type_mask, zval *op1) {
ZVAL_BOOL(result, (type_mask >> Z_TYPE_P(op1)) & 1);
uint32_t type = Z_TYPE_P(op1);
if (type == PARTIAL_ARRAY) {
type = IS_ARRAY;
} else if (type == PARTIAL_OBJECT) {
type = IS_OBJECT;
}
ZVAL_BOOL(result, (type_mask >> type) & 1);
}
static inline int ct_eval_in_array(zval *result, uint32_t extended_value, zval *op1, zval *op2) {
@ -1424,6 +1430,12 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
SKIP_IF_TOP(op1);
SKIP_IF_TOP(op2);
/* TODO: We could implement support for evaluation of + on partial arrays. */
if (IS_PARTIAL_ARRAY(op1) || IS_PARTIAL_ARRAY(op2)) {
SET_RESULT_BOT(result);
break;
}
if (zend_optimizer_eval_binary_op(&zv, opline->opcode, op1, op2) == SUCCESS) {
SET_RESULT(result, &zv);
zval_ptr_dtor_nogc(&zv);
@ -1610,6 +1622,10 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
case ZEND_BW_NOT:
case ZEND_BOOL_NOT:
SKIP_IF_TOP(op1);
if (IS_PARTIAL_ARRAY(op1)) {
SET_RESULT_BOT(result);
break;
}
if (zend_optimizer_eval_unary_op(&zv, opline->opcode, op1) == SUCCESS) {
SET_RESULT(result, &zv);
zval_ptr_dtor_nogc(&zv);
@ -1619,6 +1635,10 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
break;
case ZEND_CAST:
SKIP_IF_TOP(op1);
if (IS_PARTIAL_ARRAY(op1)) {
SET_RESULT_BOT(result);
break;
}
if (zend_optimizer_eval_cast(&zv, opline->extended_value, op1) == SUCCESS) {
SET_RESULT(result, &zv);
zval_ptr_dtor_nogc(&zv);
@ -1630,6 +1650,10 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
case ZEND_JMPZ_EX:
case ZEND_JMPNZ_EX:
SKIP_IF_TOP(op1);
if (IS_PARTIAL_ARRAY(op1)) {
SET_RESULT_BOT(result);
break;
}
ZVAL_BOOL(&zv, zend_is_true(op1));
SET_RESULT(result, &zv);
break;
@ -1760,6 +1784,10 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
break;
case ZEND_ROPE_INIT:
SKIP_IF_TOP(op2);
if (IS_PARTIAL_ARRAY(op2)) {
SET_RESULT_BOT(result);
break;
}
if (zend_optimizer_eval_cast(&zv, IS_STRING, op2) == SUCCESS) {
SET_RESULT(result, &zv);
zval_ptr_dtor_nogc(&zv);
@ -1774,6 +1802,10 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
// string for all SSA vars with some extra checks
SKIP_IF_TOP(op1);
SKIP_IF_TOP(op2);
if (IS_PARTIAL_ARRAY(op2)) {
SET_RESULT_BOT(result);
break;
}
if (zend_optimizer_eval_binary_op(&zv, ZEND_CONCAT, op1, op2) == SUCCESS) {
SET_RESULT(result, &zv);
zval_ptr_dtor_nogc(&zv);

View File

@ -0,0 +1,70 @@
--TEST--
Bug #78015: Incorrect evaluation of expressions involving partials array in SCCP
--FILE--
<?php
$x = 1;
function test1() {
global $x;
$a = ['b' => [$x], 'c' => [$x]];
$d = $a['b'] + $a['c'];
return $d;
}
function test2() {
global $x;
$a = ['b' => [$x]];
$d = !$a['b'];
return $d;
}
function test3() {
global $x;
$a = ['b' => [$x]];
$d = (int) $a['b'];
return $d;
}
function test4() {
global $x;
$a = ['b' => [$x]];
$d = $a['b'] ?: 42;
return $d;
}
function test5() {
global $x;
$a = ['b' => [$x]];
$d = is_array($a['b']);
return $d;
}
function test6() {
global $x;
$a = ['b' => [$x]];
$b = "foo";
$d = "$a[b]{$b}bar";
return $d;
}
var_dump(test1());
var_dump(test2());
var_dump(test3());
var_dump(test4());
var_dump(test5());
var_dump(test6());
?>
--EXPECTF--
array(1) {
[0]=>
int(1)
}
bool(false)
int(1)
int(42)
bool(true)
Notice: Array to string conversion in %s on line %d
string(11) "Arrayfoobar"