Skip to content

Commit cf377ee

Browse files
committed
Don't convert assign op operand types in opcache
This is the same change as 56b18d4 but for ASSIGN_OP. Changing the operand type may change the error message and can result in different behavior with operator overloading. As with the other patch, if there is strong interest this could be added to the DFA pass instead, with an appropriate type check.
1 parent 6f32510 commit cf377ee

File tree

2 files changed

+60
-27
lines changed

2 files changed

+60
-27
lines changed

Zend/Optimizer/pass1.c

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -104,33 +104,9 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
104104
break;
105105

106106
case ZEND_ASSIGN_OP:
107-
if (opline->op2_type == IS_CONST) {
108-
if (opline->extended_value == ZEND_ADD
109-
|| opline->extended_value == ZEND_SUB
110-
|| opline->extended_value == ZEND_MUL
111-
|| opline->extended_value == ZEND_DIV
112-
|| opline->extended_value == ZEND_POW) {
113-
if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) {
114-
/* don't optimize if it should produce a runtime numeric string error */
115-
if (is_numeric_string(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), NULL, NULL, 0)) {
116-
convert_scalar_to_number(&ZEND_OP2_LITERAL(opline));
117-
}
118-
}
119-
} else if (opline->extended_value == ZEND_MOD
120-
|| opline->extended_value == ZEND_SL
121-
|| opline->extended_value == ZEND_SR) {
122-
zval *op2 = &ZEND_OP2_LITERAL(opline);
123-
if (Z_TYPE_P(op2) != IS_LONG) {
124-
if (!zend_is_op_long_compatible(op2)) {
125-
break;
126-
}
127-
convert_to_long(op2);
128-
}
129-
} else if (opline->extended_value == ZEND_CONCAT) {
130-
if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) {
131-
convert_to_string(&ZEND_OP2_LITERAL(opline));
132-
}
133-
}
107+
if (opline->extended_value == ZEND_CONCAT && opline->op2_type == IS_CONST
108+
&& Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) {
109+
convert_to_string(&ZEND_OP2_LITERAL(opline));
134110
}
135111
break;
136112

Zend/tests/assign_op_type_error.phpt

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
--TEST--
2+
TypeError for compound assignment operations
3+
--FILE--
4+
<?php
5+
6+
$x = [];
7+
try {
8+
$x += "1";
9+
} catch (TypeError $e) {
10+
echo $e->getMessage(), "\n";
11+
}
12+
try {
13+
$x -= "1";
14+
} catch (TypeError $e) {
15+
echo $e->getMessage(), "\n";
16+
}
17+
try {
18+
$x *= "1";
19+
} catch (TypeError $e) {
20+
echo $e->getMessage(), "\n";
21+
}
22+
try {
23+
$x /= "1";
24+
} catch (TypeError $e) {
25+
echo $e->getMessage(), "\n";
26+
}
27+
try {
28+
$x **= "1";
29+
} catch (TypeError $e) {
30+
echo $e->getMessage(), "\n";
31+
}
32+
try {
33+
$x %= "1";
34+
} catch (TypeError $e) {
35+
echo $e->getMessage(), "\n";
36+
}
37+
try {
38+
$x <<= "1";
39+
} catch (TypeError $e) {
40+
echo $e->getMessage(), "\n";
41+
}
42+
try {
43+
$x >>= "1";
44+
} catch (TypeError $e) {
45+
echo $e->getMessage(), "\n";
46+
}
47+
48+
?>
49+
--EXPECT--
50+
Unsupported operand types: array + string
51+
Unsupported operand types: array - string
52+
Unsupported operand types: array * string
53+
Unsupported operand types: array / string
54+
Unsupported operand types: array ** string
55+
Unsupported operand types: array % string
56+
Unsupported operand types: array << string
57+
Unsupported operand types: array >> string

0 commit comments

Comments
 (0)