}
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) {
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);
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);
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);
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;
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);
// 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);
--- /dev/null
+--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"