mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Don't convert assign op operand types in opcache
This is the same change as 56b18d478e
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.
This commit is contained in:
parent
6f325104eb
commit
cf377eefa6
@ -104,33 +104,9 @@ constant_binary_op:
|
||||
break;
|
||||
|
||||
case ZEND_ASSIGN_OP:
|
||||
if (opline->op2_type == IS_CONST) {
|
||||
if (opline->extended_value == ZEND_ADD
|
||||
|| opline->extended_value == ZEND_SUB
|
||||
|| opline->extended_value == ZEND_MUL
|
||||
|| opline->extended_value == ZEND_DIV
|
||||
|| opline->extended_value == ZEND_POW) {
|
||||
if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) {
|
||||
/* don't optimize if it should produce a runtime numeric string error */
|
||||
if (is_numeric_string(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), NULL, NULL, 0)) {
|
||||
convert_scalar_to_number(&ZEND_OP2_LITERAL(opline));
|
||||
}
|
||||
}
|
||||
} else if (opline->extended_value == ZEND_MOD
|
||||
|| opline->extended_value == ZEND_SL
|
||||
|| opline->extended_value == ZEND_SR) {
|
||||
zval *op2 = &ZEND_OP2_LITERAL(opline);
|
||||
if (Z_TYPE_P(op2) != IS_LONG) {
|
||||
if (!zend_is_op_long_compatible(op2)) {
|
||||
break;
|
||||
}
|
||||
convert_to_long(op2);
|
||||
}
|
||||
} else if (opline->extended_value == ZEND_CONCAT) {
|
||||
if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) {
|
||||
convert_to_string(&ZEND_OP2_LITERAL(opline));
|
||||
}
|
||||
}
|
||||
if (opline->extended_value == ZEND_CONCAT && opline->op2_type == IS_CONST
|
||||
&& Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) {
|
||||
convert_to_string(&ZEND_OP2_LITERAL(opline));
|
||||
}
|
||||
break;
|
||||
|
||||
|
57
Zend/tests/assign_op_type_error.phpt
Normal file
57
Zend/tests/assign_op_type_error.phpt
Normal file
@ -0,0 +1,57 @@
|
||||
--TEST--
|
||||
TypeError for compound assignment operations
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$x = [];
|
||||
try {
|
||||
$x += "1";
|
||||
} catch (TypeError $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
try {
|
||||
$x -= "1";
|
||||
} catch (TypeError $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
try {
|
||||
$x *= "1";
|
||||
} catch (TypeError $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
try {
|
||||
$x /= "1";
|
||||
} catch (TypeError $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
try {
|
||||
$x **= "1";
|
||||
} catch (TypeError $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
try {
|
||||
$x %= "1";
|
||||
} catch (TypeError $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
try {
|
||||
$x <<= "1";
|
||||
} catch (TypeError $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
try {
|
||||
$x >>= "1";
|
||||
} catch (TypeError $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Unsupported operand types: array + string
|
||||
Unsupported operand types: array - string
|
||||
Unsupported operand types: array * string
|
||||
Unsupported operand types: array / string
|
||||
Unsupported operand types: array ** string
|
||||
Unsupported operand types: array % string
|
||||
Unsupported operand types: array << string
|
||||
Unsupported operand types: array >> string
|
Loading…
Reference in New Issue
Block a user