Skip to content

Commit 94d3e40

Browse files
committed
Delay array to string conversion notice until runtime
1 parent a72c741 commit 94d3e40

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

Zend/tests/runtime_compile_time_binary_operands.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ if($c === 0) {
148148
===DONE===
149149
--CLEAN--
150150
<?php
151-
$fl = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'compare_equality_temp.php';
151+
$fl = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'compare_binary_operands_temp.php';
152152
@unlink($fl);
153153
?>
154154
--EXPECTF--

Zend/zend_compile.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6814,6 +6814,16 @@ ZEND_API zend_bool zend_binary_op_produces_numeric_string_error(uint32_t opcode,
68146814
}
68156815
/* }}} */
68166816

6817+
ZEND_API zend_bool zend_binary_op_produces_array_conversion_error(uint32_t opcode, zval *op1, zval *op2) /* {{{ */
6818+
{
6819+
if (opcode == ZEND_CONCAT && (Z_TYPE_P(op1) == IS_ARRAY || Z_TYPE_P(op2) == IS_ARRAY)) {
6820+
return 1;
6821+
}
6822+
6823+
return 0;
6824+
}
6825+
/* }}} */
6826+
68176827
static inline zend_bool zend_try_ct_eval_binary_op(zval *result, uint32_t opcode, zval *op1, zval *op2) /* {{{ */
68186828
{
68196829
binary_op_type fn = get_binary_op(opcode);
@@ -6831,6 +6841,10 @@ static inline zend_bool zend_try_ct_eval_binary_op(zval *result, uint32_t opcode
68316841
if (zend_binary_op_produces_numeric_string_error(opcode, op1, op2)) {
68326842
return 0;
68336843
}
6844+
/* don't evaluate array to string conversions at compile-time */
6845+
if (zend_binary_op_produces_array_conversion_error(opcode, op1, op2)) {
6846+
return 0;
6847+
}
68346848

68356849
fn(result, op1, op2);
68366850
return 1;
@@ -7000,10 +7014,18 @@ void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */
70007014
if (opcode == ZEND_CONCAT) {
70017015
/* convert constant operands to strings at compile-time */
70027016
if (left_node.op_type == IS_CONST) {
7003-
convert_to_string(&left_node.u.constant);
7017+
if (Z_TYPE(left_node.u.constant) == IS_ARRAY) {
7018+
zend_emit_op_tmp(&left_node, ZEND_CAST, &left_node, NULL)->extended_value = IS_STRING;
7019+
} else {
7020+
convert_to_string(&left_node.u.constant);
7021+
}
70047022
}
70057023
if (right_node.op_type == IS_CONST) {
7006-
convert_to_string(&right_node.u.constant);
7024+
if (Z_TYPE(right_node.u.constant) == IS_ARRAY) {
7025+
zend_emit_op_tmp(&right_node, ZEND_CAST, &right_node, NULL)->extended_value = IS_STRING;
7026+
} else {
7027+
convert_to_string(&right_node.u.constant);
7028+
}
70077029
}
70087030
if (left_node.op_type == IS_CONST && right_node.op_type == IS_CONST) {
70097031
opcode = ZEND_FAST_CONCAT;

0 commit comments

Comments
 (0)