summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-04-01 10:25:22 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-05-05 16:11:13 +0200
commit5bc1e224dbd660cea99c222baf8bd3c215d25073 (patch)
tree00414aab9d3884198debc4497df632c74b6984a7
parent31fb6a08b3a02e665d0e24d2cbd56d13342423c8 (diff)
downloadphp-git-5bc1e224dbd660cea99c222baf8bd3c215d25073.tar.gz
Make numeric operations on resources, arrays and objects type errors
RFC: https://wiki.php.net/rfc/arithmetic_operator_type_checks Closes GH-5331.
-rw-r--r--UPGRADING9
-rw-r--r--Zend/tests/add_003.phpt4
-rw-r--r--Zend/tests/bug54305.phpt17
-rw-r--r--Zend/tests/bug73337.phpt5
-rw-r--r--Zend/tests/compound_assign_failure.phpt66
-rw-r--r--Zend/tests/decrement_001.phpt9
-rw-r--r--Zend/tests/decrement_001_64bit.phpt13
-rw-r--r--Zend/tests/gc_038.phpt68
-rw-r--r--Zend/tests/increment_001.phpt9
-rw-r--r--Zend/tests/mod_001.phpt6
-rw-r--r--Zend/tests/not_002.phpt4
-rw-r--r--Zend/tests/operator_unsupported_types.phpt1517
-rw-r--r--Zend/tests/throw/001.phpt6
-rw-r--r--Zend/tests/xor_001.phpt9
-rw-r--r--Zend/zend_compile.c8
-rw-r--r--Zend/zend_operators.c188
-rw-r--r--ext/opcache/Optimizer/zend_inference.c39
-rw-r--r--ext/opcache/jit/zend_jit.c3
-rw-r--r--ext/opcache/jit/zend_jit_trace.c3
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc5
-rw-r--r--ext/standard/tests/math/pow_variation1.phpt4
-rw-r--r--ext/standard/tests/math/pow_variation1_64bit.phpt4
-rw-r--r--ext/standard/tests/math/pow_variation2.phpt4
-rwxr-xr-xscripts/dev/bless_tests.php3
24 files changed, 1816 insertions, 187 deletions
diff --git a/UPGRADING b/UPGRADING
index 233f78fdae..1066d016ff 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -181,7 +181,14 @@ PHP 8.0 UPGRADE NOTES
. Disabled functions are now treated exactly like non-existent functions.
Calling a disabled function will report it as unknown, and redefining a
disabled function is now possible.
- . data: wrappers are no longer writable, what matches the documented behavior.
+ . data: stream wrappers are no longer writable, which matches the documented
+ behavior.
+ . The arithmetic and bitwise operators
+ +, -, *, /, **, %, <<, >>, &, |, ^, ~, ++, --
+ will now consistently throw a TypeError when one of the operands is an
+ array, resource or non-overloaded object. The only exception to this is the
+ array + array merge operation, which remains supported.
+ RFC: https://wiki.php.net/rfc/arithmetic_operator_type_checks
- COM:
. Removed the ability to import case-insensitive constants from type
diff --git a/Zend/tests/add_003.phpt b/Zend/tests/add_003.phpt
index 0f03f550e0..69edb7cb1e 100644
--- a/Zend/tests/add_003.phpt
+++ b/Zend/tests/add_003.phpt
@@ -20,12 +20,8 @@ var_dump($c);
echo "Done\n";
?>
--EXPECTF--
-Notice: Object of class stdClass could not be converted to number in %sadd_003.php on line %d
-
Exception: Unsupported operand types: object + array
-Notice: Object of class stdClass could not be converted to number in %s on line %d
-
Fatal error: Uncaught TypeError: Unsupported operand types: object + array in %s:%d
Stack trace:
#0 {main}
diff --git a/Zend/tests/bug54305.phpt b/Zend/tests/bug54305.phpt
index 8e85d2be58..a443d480ec 100644
--- a/Zend/tests/bug54305.phpt
+++ b/Zend/tests/bug54305.phpt
@@ -9,14 +9,11 @@ class TestClass {
abstract class AbstractClass {
}
$methodWithArgs = new ReflectionMethod('TestClass', 'methodWithArgs');
-echo $methodWithArgs++;
-?>
---EXPECTF--
-Method [ <user> public method methodWithArgs ] {
- @@ %sbug54305.php %d - %d
-
- - Parameters [2] {
- Parameter #0 [ <required> $a ]
- Parameter #1 [ <required> $b ]
- }
+try {
+ echo $methodWithArgs++;
+} catch (TypeError $e) {
+ echo $e->getMessage(), "\n";
}
+?>
+--EXPECT--
+Cannot increment object
diff --git a/Zend/tests/bug73337.phpt b/Zend/tests/bug73337.phpt
index 53ce963c52..a338aa605c 100644
--- a/Zend/tests/bug73337.phpt
+++ b/Zend/tests/bug73337.phpt
@@ -5,8 +5,5 @@ Bug #73337 (try/catch not working with two exceptions inside a same operation)
class d { function __destruct() { throw new Exception; } }
try { new d + new d; } catch (Exception $e) { print "Exception properly caught\n"; }
?>
---EXPECTF--
-Notice: Object of class d could not be converted to number in %sbug73337.php on line 3
-
-Notice: Object of class d could not be converted to number in %sbug73337.php on line 3
+--EXPECT--
Exception properly caught
diff --git a/Zend/tests/compound_assign_failure.phpt b/Zend/tests/compound_assign_failure.phpt
index 1780725d93..0dc9af85f2 100644
--- a/Zend/tests/compound_assign_failure.phpt
+++ b/Zend/tests/compound_assign_failure.phpt
@@ -34,167 +34,167 @@ try {
$x = new stdClass;
try { $x += 1; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = 1;
try { $x += new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = "foo";
try { $x += new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = new stdClass;
try { $x -= 1; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = 1;
try { $x -= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = "foo";
try { $x -= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = new stdClass;
try { $x *= 1; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = 1;
try { $x *= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = "foo";
try { $x *= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = new stdClass;
try { $x /= 1; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = 1;
try { $x /= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = "foo";
try { $x /= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = new stdClass;
try { $x %= 1; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = 1;
try { $x %= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = "foo";
try { $x %= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = new stdClass;
try { $x **= 1; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = 1;
try { $x **= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = "foo";
try { $x **= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = new stdClass;
try { $x ^= 1; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = 1;
try { $x ^= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = "foo";
try { $x ^= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = new stdClass;
try { $x &= 1; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = 1;
try { $x &= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = "foo";
try { $x &= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = new stdClass;
try { $x |= 1; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = 1;
try { $x |= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = "foo";
try { $x |= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = new stdClass;
try { $x <<= 1; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = 1;
try { $x <<= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = "foo";
try { $x <<= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = new stdClass;
try { $x >>= 1; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = 1;
try { $x >>= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
$x = "foo";
try { $x >>= new stdClass; }
-catch (Exception $e) {}
+catch (Throwable $e) {}
var_dump($x);
?>
diff --git a/Zend/tests/decrement_001.phpt b/Zend/tests/decrement_001.phpt
index 22d95b16ac..5983c4eaa1 100644
--- a/Zend/tests/decrement_001.phpt
+++ b/Zend/tests/decrement_001.phpt
@@ -26,13 +26,18 @@ $a = array(
);
foreach ($a as $var) {
- $var--;
+ try {
+ $var--;
+ } catch (TypeError $e) {
+ echo $e->getMessage(), "\n";
+ }
var_dump($var);
}
echo "Done\n";
?>
--EXPECTF--
+Cannot decrement array
array(3) {
[0]=>
int(1)
@@ -51,8 +56,10 @@ float(1.5)
NULL
bool(true)
bool(false)
+Cannot decrement object
object(stdClass)#%d (0) {
}
+Cannot decrement array
array(0) {
}
float(-2147483649)
diff --git a/Zend/tests/decrement_001_64bit.phpt b/Zend/tests/decrement_001_64bit.phpt
index 2b2100932a..a96d8cbd07 100644
--- a/Zend/tests/decrement_001_64bit.phpt
+++ b/Zend/tests/decrement_001_64bit.phpt
@@ -26,13 +26,18 @@ $a = array(
);
foreach ($a as $var) {
- $var--;
+ try {
+ $var--;
+ } catch (TypeError $e) {
+ echo $e->getMessage(), "\n";
+ }
var_dump($var);
}
echo "Done\n";
?>
---EXPECTF--
+--EXPECT--
+Cannot decrement array
array(3) {
[0]=>
int(1)
@@ -51,8 +56,10 @@ float(1.5)
NULL
bool(true)
bool(false)
-object(stdClass)#%d (0) {
+Cannot decrement object
+object(stdClass)#1 (0) {
}
+Cannot decrement array
array(0) {
}
float(-9.223372036854776E+18)
diff --git a/Zend/tests/gc_038.phpt b/Zend/tests/gc_038.phpt
index d3219531d6..91f22bf154 100644
--- a/Zend/tests/gc_038.phpt
+++ b/Zend/tests/gc_038.phpt
@@ -6,8 +6,10 @@ zend.enable_gc = 1
<?php
function test_add() {
$x = new stdClass;
- $x->x= $x;
- @$x += 5;
+ $x->x = $x;
+ try {
+ $x += 5;
+ } catch (TypeError $e) { unset($x); }
$n = gc_collect_cycles();
echo "+=\t$n\n";
}
@@ -15,8 +17,10 @@ test_add();
function test_sub() {
$x = new stdClass;
- $x->x= $x;
- @$x -= 5;
+ $x->x = $x;
+ try {
+ $x -= 5;
+ } catch (TypeError $e) { unset($x); }
$n = gc_collect_cycles();
echo "-=\t$n\n";
}
@@ -24,8 +28,10 @@ test_sub();
function test_mul() {
$x = new stdClass;
- $x->x= $x;
- @$x *= 5;
+ $x->x = $x;
+ try {
+ $x *= 5;
+ } catch (TypeError $e) { unset($x); }
$n = gc_collect_cycles();
echo "*=\t$n\n";
}
@@ -33,8 +39,10 @@ test_mul();
function test_div() {
$x = new stdClass;
- $x->x= $x;
- @$x /= 5;
+ $x->x = $x;
+ try {
+ $x /= 5;
+ } catch (TypeError $e) { unset($x); }
$n = gc_collect_cycles();
echo "/=\t$n\n";
}
@@ -42,8 +50,10 @@ test_div();
function test_mod() {
$x = new stdClass;
- $x->x= $x;
- @$x %= 5;
+ $x->x = $x;
+ try {
+ $x %= 5;
+ } catch (TypeError $e) { unset($x); }
$n = gc_collect_cycles();
echo "%=\t$n\n";
}
@@ -51,8 +61,10 @@ test_mod();
function test_sl() {
$x = new stdClass;
- $x->x= $x;
- @$x <<= 5;
+ $x->x = $x;
+ try {
+ $x <<= 5;
+ } catch (TypeError $e) { unset($x); }
$n = gc_collect_cycles();
echo "<<=\t$n\n";
}
@@ -60,8 +72,10 @@ test_sl();
function test_sr() {
$x = new stdClass;
- $x->x= $x;
- @$x >>= 5;
+ $x->x = $x;
+ try {
+ $x >>= 5;
+ } catch (TypeError $e) { unset($x); }
$n = gc_collect_cycles();
echo ">>=\t$n\n";
}
@@ -69,8 +83,10 @@ test_sr();
function test_or() {
$x = new stdClass;
- $x->x= $x;
- @$x |= 1;
+ $x->x = $x;
+ try {
+ $x |= 5;
+ } catch (TypeError $e) { unset($x); }
$n = gc_collect_cycles();
echo "|=\t$n\n";
}
@@ -78,8 +94,10 @@ test_or();
function test_and() {
$x = new stdClass;
- $x->x= $x;
- @$x &= 1;
+ $x->x = $x;
+ try {
+ $x &= 5;
+ } catch (TypeError $e) { unset($x); }
$n = gc_collect_cycles();
echo "&=\t$n\n";
}
@@ -87,8 +105,10 @@ test_and();
function test_xor() {
$x = new stdClass;
- $x->x= $x;
- @$x ^= 1;
+ $x->x = $x;
+ try {
+ $x ^= 5;
+ } catch (TypeError $e) { unset($x); }
$n = gc_collect_cycles();
echo "^=\t$n\n";
}
@@ -96,8 +116,10 @@ test_xor();
function test_pow() {
$x = new stdClass;
- $x->x= $x;
- @$x **= 1;
+ $x->x = $x;
+ try {
+ $x **= 5;
+ } catch (TypeError $e) { unset($x); }
$n = gc_collect_cycles();
echo "**=\t$n\n";
}
@@ -117,7 +139,7 @@ function test_concat() {
}
test_concat();
?>
---EXPECT--
+--EXPECTF--
+= 1
-= 1
*= 1
diff --git a/Zend/tests/increment_001.phpt b/Zend/tests/increment_001.phpt
index 92f32bb657..a834c5c51d 100644
--- a/Zend/tests/increment_001.phpt
+++ b/Zend/tests/increment_001.phpt
@@ -26,13 +26,18 @@ $a = array(
);
foreach ($a as $var) {
- $var++;
+ try {
+ $var++;
+ } catch (TypeError $e) {
+ echo $e->getMessage(), "\n";
+ }
var_dump($var);
}
echo "Done\n";
?>
--EXPECTF--
+Cannot increment array
array(3) {
[0]=>
int(1)
@@ -51,8 +56,10 @@ float(3.5)
int(1)
bool(true)
bool(false)
+Cannot increment object
object(stdClass)#%d (0) {
}
+Cannot increment array
array(0) {
}
float(2147483648)
diff --git a/Zend/tests/mod_001.phpt b/Zend/tests/mod_001.phpt
index a393a43644..5c543a2619 100644
--- a/Zend/tests/mod_001.phpt
+++ b/Zend/tests/mod_001.phpt
@@ -9,12 +9,12 @@ $b = array();
try {
$c = $a % $b;
var_dump($c);
-} catch (DivisionByZeroError $e) {
+} catch (TypeError $e) {
echo "Exception: " . $e->getMessage() . "\n";
}
echo "Done\n";
?>
---EXPECT--
-Exception: Modulo by zero
+--EXPECTF--
+Exception: Unsupported operand types: array % array
Done
diff --git a/Zend/tests/not_002.phpt b/Zend/tests/not_002.phpt
index 38691a1a51..3282053b6b 100644
--- a/Zend/tests/not_002.phpt
+++ b/Zend/tests/not_002.phpt
@@ -18,9 +18,9 @@ var_dump($a);
echo "Done\n";
?>
--EXPECTF--
-Exception: Unsupported operand types
+Exception: Cannot perform bitwise not on array
-Fatal error: Uncaught Error: Unsupported operand types in %s:%d
+Fatal error: Uncaught TypeError: Cannot perform bitwise not on array in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d
diff --git a/Zend/tests/operator_unsupported_types.phpt b/Zend/tests/operator_unsupported_types.phpt
new file mode 100644
index 0000000000..9004897d71
--- /dev/null
+++ b/Zend/tests/operator_unsupported_types.phpt
@@ -0,0 +1,1517 @@
+--TEST--
+Using unsupported types with operators
+--FILE--
+<?php
+
+$binops = [
+ '+',
+ '-',
+ '*',
+ '/',
+ '%',
+ '**',
+ '<<',
+ '>>',
+ '&',
+ '|',
+ '^',
+ // Works on booleans, never errors.
+ 'xor',
+ // Only generates errors that string conversion emits.
+ '.',
+];
+$illegalValues = [
+ '[]',
+ 'new stdClass',
+ 'STDOUT',
+];
+$legalValues = [
+ 'null',
+ 'true',
+ 'false',
+ '2',
+ '3.5',
+ '"123"',
+ '"foo"', // Semi-legal.
+];
+
+set_error_handler(function($errno, $errstr) {
+ assert($errno == E_WARNING);
+ echo "Warning: $errstr\n";
+});
+
+function evalBinOp(string $op, string $value1, string $value2) {
+ try {
+ eval("return $value1 $op $value2;");
+ echo "No error for $value1 $op $value2\n";
+ } catch (Throwable $e) {
+ echo $e->getMessage() . "\n";
+ }
+}
+
+function evalAssignOp(string $op, string $value1, string $value2) {
+ $x = $origX = eval("return $value1;");
+ try {
+ eval("\$x $op= $value2;");
+ echo "No error for $value1 $op= $value2\n";
+ } catch (Throwable $e) {
+ echo $e->getMessage() . "\n";
+ if ($x !== $origX) {
+ die("Value corrupted!");
+ }
+ }
+}
+
+echo "BINARY OP:\n";
+foreach ($binops as $op) {
+ foreach ($illegalValues as $illegalValue1) {
+ foreach ($illegalValues as $illegalValue2) {
+ evalBinOp($op, $illegalValue1, $illegalValue2);
+ }
+ }
+ foreach ($illegalValues as $illegalValue) {
+ foreach ($legalValues as $legalValue) {
+ evalBinOp($op, $illegalValue, $legalValue);
+ evalBinOp($op, $legalValue, $illegalValue);
+ }
+ }
+}
+
+echo "\n\nASSIGN OP:\n";
+foreach ($binops as $op) {
+ if ($op === 'xor') continue;
+
+ foreach ($illegalValues as $illegalValue1) {
+ foreach ($illegalValues as $illegalValue2) {
+ evalAssignOp($op, $illegalValue1, $illegalValue2);
+ }
+ }
+ foreach ($illegalValues as $illegalValue) {
+ foreach ($legalValues as $legalValue) {
+ evalAssignOp($op, $illegalValue, $legalValue);
+ evalAssignOp($op, $legalValue, $illegalValue);
+ }
+ }
+}
+
+echo "\n\nUNARY OP:\n";
+foreach ($illegalValues as $illegalValue) {
+ try {
+ eval("return ~$illegalValue;");
+ echo "No error for ~$copy\n";
+ } catch (TypeError $e) {
+ echo $e->getMessage() . "\n";
+ }
+}
+
+echo "\n\nINCDEC:\n";
+foreach ($illegalValues as $illegalValue) {
+ $copy = eval("return $illegalValue;");
+ try {
+ $copy++;
+ echo "No error for $copy++\n";
+ } catch (TypeError $e) {
+ echo $e->getMessage() . "\n";
+ }
+ $copy = eval("return $illegalValue;");
+ try {
+ $copy--;
+ echo "No error for $copy--\n";
+ } catch (TypeError $e) {
+ echo $e->getMessage() . "\n";
+ }
+}
+
+?>
+--EXPECT--
+BINARY OP:
+No error for [] + []
+Unsupported operand types: array + object
+Unsupported operand types: array + resource
+Unsupported operand types: object + array
+Unsupported operand types: object + object
+Unsupported operand types: object + resource
+Unsupported operand types: resource + array
+Unsupported operand types: resource + object
+Unsupported operand types: resource + resource
+Unsupported operand types: array + null
+Unsupported operand types: null + array
+Unsupported operand types: array + bool
+Unsupported operand types: bool + array
+Unsupported operand types: array + bool
+Unsupported operand types: bool + array
+Unsupported operand types: array + int
+Unsupported operand types: int + array
+Unsupported operand types: array + float
+Unsupported operand types: float + array
+Unsupported operand types: array + string
+Unsupported operand types: string + array
+Unsupported operand types: array + string
+Warning: A non-numeric value encountered
+Unsupported operand types: string + array
+Unsupported operand types: object + null
+Unsupported operand types: null + object
+Unsupported operand types: object + bool
+Unsupported operand types: bool + object
+Unsupported operand types: object + bool
+Unsupported operand types: bool + object
+Unsupported operand types: object + int
+Unsupported operand types: int + object
+Unsupported operand types: object + float
+Unsupported operand types: float + object
+Unsupported operand types: object + string
+Unsupported operand types: string + object
+Unsupported operand types: object + string
+Warning: A non-numeric value encountered
+Unsupported operand types: string + object
+Unsupported operand types: resource + null
+Unsupported operand types: null + resource
+Unsupported operand types: resource + bool
+Unsupported operand types: bool + resource
+Unsupported operand types: resource + bool
+Unsupported operand types: bool + resource
+Unsupported operand types: resource + int
+Unsupported operand types: int + resource
+Unsupported operand types: resource + float
+Unsupported operand types: float + resource
+Unsupported operand types: resource + string
+Unsupported operand types: string + resource
+Unsupported operand types: resource + string
+Warning: A non-numeric value encountered
+Unsupported operand types: string + resource
+Unsupported operand types: array - array
+Unsupported operand types: array - object
+Unsupported operand types: array - resource
+Unsupported operand types: object - array
+Unsupported operand types: object - object
+Unsupported operand types: object - resource
+Unsupported operand types: resource - array
+Unsupported operand types: resource - object
+Unsupported operand types: resource - resource
+Unsupported operand types: array - null
+Unsupported operand types: null - array
+Unsupported operand types: array - bool
+Unsupported operand types: bool - array
+Unsupported operand types: array - bool
+Unsupported operand types: bool - array
+Unsupported operand types: array - int
+Unsupported operand types: int - array
+Unsupported operand types: array - float
+Unsupported operand types: float - array
+Unsupported operand types: array - string
+Unsupported operand types: string - array
+Unsupported operand types: array - string
+Warning: A non-numeric value encountered
+Unsupported operand types: string - array
+Unsupported operand types: object - null
+Unsupported operand types: null - object
+Unsupported operand types: object - bool
+Unsupported operand types: bool - object
+Unsupported operand types: object - bool
+Unsupported operand types: bool - object
+Unsupported operand types: object - int
+Unsupported operand types: int - object
+Unsupported operand types: object - float
+Unsupported operand types: float - object
+Unsupported operand types: object - string
+Unsupported operand types: string - object
+Unsupported operand types: object - string
+Warning: A non-numeric value encountered
+Unsupported operand types: string - object
+Unsupported operand types: resource - null
+Unsupported operand types: null - resource
+Unsupported operand types: resource - bool
+Unsupported operand types: bool - resource
+Unsupported operand types: resource - bool
+Unsupported operand types: bool - resource
+Unsupported operand types: resource - int
+Unsupported operand types: int - resource
+Unsupported operand types: resource - float
+Unsupported operand types: float - resource
+Unsupported operand types: resource - string
+Unsupported operand types: string - resource
+Unsupported operand types: resource - string
+Warning: A non-numeric value encountered
+Unsupported operand types: string - resource
+Unsupported operand types: array * array
+Unsupported operand types: object * array
+Unsupported operand types: resource * array
+Unsupported operand types: object * array
+Unsupported operand types: object * object
+Unsupported operand types: object * resource
+Unsupported operand types: resource * array
+Unsupported operand types: object * resource
+Unsupported operand types: resource * resource
+Unsupported operand types: array * null
+Unsupported operand types: null * array
+Unsupported operand types: array * bool
+Unsupported operand types: bool * array
+Unsupported operand types: array * bool
+Unsupported operand types: bool * array
+Unsupported operand types: array * int
+Unsupported operand types: int * array
+Unsupported operand types: array * float
+Unsupported operand types: float * array
+Unsupported operand types: array * string
+Unsupported operand types: string * array
+Unsupported operand types: array * string
+Warning: A non-numeric value encountered
+Unsupported operand types: string * array
+Unsupported operand types: object * null
+Unsupported operand types: object * null
+Unsupported operand types: object * bool
+Unsupported operand types: object * bool
+Unsupported operand types: object * bool
+Unsupported operand types: object * bool
+Unsupported operand types: object * int
+Unsupported operand types: object * int
+Unsupported operand types: object * float
+Unsupported operand types: object * float
+Unsupported operand types: object * string
+Unsupported operand types: object * string
+Unsupported operand types: object * string
+Unsupported operand types: object * string
+Unsupported operand types: resource * null
+Unsupported operand types: resource * null
+Unsupported operand types: resource * bool
+Unsupported operand types: resource * bool
+Unsupported operand types: resource * bool
+Unsupported operand types: resource * bool
+Unsupported operand types: resource * int
+Unsupported operand types: resource * int
+Unsupported operand types: resource * float
+Unsupported operand types: resource * float
+Unsupported operand types: resource * string
+Unsupported operand types: resource * string
+Unsupported operand types: resource * string
+Unsupported operand types: resource * string
+Unsupported operand types: array / array
+Unsupported operand types: array / object
+Unsupported operand types: array / resource
+Unsupported operand types: object / array
+Unsupported operand types: object / object
+Unsupported operand types: object / resource
+Unsupported operand types: resource / array
+Unsupported operand types: resource / object
+Unsupported operand types: resource / resource
+Unsupported operand types: array / null
+Unsupported operand types: null / array
+Unsupported operand types: array / bool
+Unsupported operand types: bool / array
+Unsupported operand types: array / bool
+Unsupported operand types: bool / array
+Unsupported operand types: array / int
+Unsupported operand types: int / array
+Unsupported operand types: array / float
+Unsupported operand types: float / array
+Unsupported operand types: array / string
+Unsupported operand types: string / array
+Unsupported operand types: array / string
+Warning: A non-numeric value encountered
+Unsupported operand types: string / array
+Unsupported operand types: object / null
+Unsupported operand types: null / object
+Unsupported operand types: object / bool
+Unsupported operand types: bool / object
+Unsupported operand types: object / bool
+Unsupported operand types: bool / object
+Unsupported operand types: object / int
+Unsupported operand types: int / object
+Unsupported operand types: object / float
+Unsupported operand types: float / object
+Unsupported operand types: object / string
+Unsupported operand types: string / object
+Unsupported operand types: object / string
+Warning: A non-numeric value encountered
+Unsupported operand types: string / object
+Unsupported operand types: resource / null
+Unsupported operand types: null / resource
+Unsupported operand types: resource / bool
+Unsupported operand types: bool / resource
+Unsupported operand types: resource / bool
+Unsupported operand types: bool / resource
+Unsupported operand types: resource / int
+Unsupported operand types: int / resource
+Unsupported operand types: resource / float
+Unsupported operand types: float / resource
+Unsupported operand types: resource / string
+Unsupported operand types: string / resource
+Unsupported operand types: resource / string
+Warning: A non-numeric value encountered
+Unsupported operand types: string / resource
+Unsupported operand types: array % array
+Unsupported operand types: array % object
+Unsupported operand types: array % resource
+Unsupported operand types: object % array
+Unsupported operand types: object % object
+Unsupported operand types: object % resource
+Unsupported operand types: resource % array
+Unsupported operand types: resource % object
+Unsupported operand types: resource % resource
+Unsupported operand types: array % null
+Unsupported operand types: null % array
+Unsupported operand types: array % bool
+Unsupported operand types: bool % array
+Unsupported operand types: array % bool
+Unsupported operand types: bool % array
+Unsupported operand types: array % int
+Unsupported operand types: int % array
+Unsupported operand types: array % float
+Unsupported operand types: float % array
+Unsupported operand types: array % string
+Unsupported operand types: string % array
+Unsupported operand types: array % string
+Warning: A non-numeric value encountered
+Unsupported operand types: string % array
+Unsupported operand types: object % null
+Unsupported operand types: null % object
+Unsupported operand types: object % bool
+Unsupported operand types: bool % object
+Unsupported operand types: object % bool
+Unsupported operand types: bool % object
+Unsupported operand types: object % int
+Unsupported operand types: int % object
+Unsupported operand types: object % float
+Unsupported operand types: float % object
+Unsupported operand types: object % string
+Unsupported operand types: string % object
+Unsupported operand types: object % string
+Warning: A non-numeric value encountered
+Unsupported operand types: string % object
+Unsupported operand types: resource % null
+Unsupported operand types: null % resource
+Unsupported operand types: resource % bool
+Unsupported operand types: bool % resource
+Unsupported operand types: resource % bool
+Unsupported operand types: bool % resource
+Unsupported operand types: resource % int
+Unsupported operand types: int % resource
+Unsupported operand types: resource % float
+Unsupported operand types: float % resource
+Unsupported operand types: resource % string
+Unsupported operand types: string % resource
+Unsupported operand types: resource % string
+Warning: A non-numeric value encountered
+Unsupported operand types: string % resource
+Unsupported operand types: array ** array
+Unsupported operand types: array ** object
+Unsupported operand types: array ** resource
+Unsupported operand types: object ** array
+Unsupported operand types: object ** object
+Unsupported operand types: object ** resource
+Unsupported operand types: resource ** array
+Unsupported operand types: resource ** object
+Unsupported operand types: resource ** resource
+Unsupported operand types: array ** null
+Unsupported operand types: null ** array
+Unsupported operand types: array ** bool
+Unsupported operand types: bool ** array
+Unsupported operand types: array ** bool
+Unsupported operand types: bool ** array
+Unsupported operand types: array ** int
+Unsupported operand types: int ** array
+Unsupported operand types: array ** float
+Unsupported operand types: float ** array
+Unsupported operand types: array ** string
+Unsupported operand types: string ** array
+Unsupported operand types: array ** string
+Warning: A non-numeric value encountered
+Unsupported operand types: string ** array
+Unsupported operand types: object ** null
+Unsupported operand types: null ** object
+Unsupported operand types: object ** bool
+Unsupported operand types: bool ** object
+Unsupported operand types: object ** bool
+Unsupported operand types: bool ** object
+Unsupported operand types: object ** int
+Unsupported operand types: int ** object
+Unsupported operand types: object ** float
+Unsupported operand types: float ** object
+Unsupported operand types: object ** string
+Unsupported operand types: string ** object
+Unsupported operand types: object ** string
+Warning: A non-numeric value encountered
+Unsupported operand types: string ** object
+Unsupported operand types: resource ** null
+Unsupported operand types: null ** resource
+Unsupported operand types: resource ** bool
+Unsupported operand types: bool ** resource
+Unsupported operand types: resource ** bool
+Unsupported operand types: bool ** resource
+Unsupported operand types: resource ** int
+Unsupported operand types: int ** resource
+Unsupported operand types: resource ** float
+Unsupported operand types: float ** resource
+Unsupported operand types: resource ** string
+Unsupported operand types: string ** resource
+Unsupported operand types: resource ** string
+Warning: A non-numeric value encountered
+Unsupported operand types: string ** resource
+Unsupported operand types: array << array
+Unsupported operand types: array << object
+Unsupported operand types: array << resource
+Unsupported operand types: object << array
+Unsupported operand types: object << object
+Unsupported operand types: object << resource
+Unsupported operand types: resource << array
+Unsupported operand types: resource << object
+Unsupported operand types: resource << resource
+Unsupported operand types: array << null
+Unsupported operand types: null << array
+Unsupported operand types: array << bool
+Unsupported operand types: bool << array
+Unsupported operand types: array << bool
+Unsupported operand types: bool << array
+Unsupported operand types: array << int
+Unsupported operand types: int << array
+Unsupported operand types: array << float
+Unsupported operand types: float << array
+Unsupported operand types: array << string
+Unsupported operand types: string << array
+Unsupported operand types: array << string
+Warning: A non-numeric value encountered
+Unsupported operand types: string << array
+Unsupported operand types: object << null
+Unsupported operand types: null << object
+Unsupported operand types: object << bool
+Unsupported operand types: bool << object
+Unsupported operand types: object << bool
+Unsupported operand types: bool << object
+Unsupported operand types: object << int
+Unsupported operand types: int << object
+Unsupported operand types: object << float
+Unsupported operand types: float << object
+Unsupported operand types: object << string
+Unsupported operand types: string << object
+Unsupported operand types: object << string
+Warning: A non-numeric value encountered
+Unsupported operand types: string << object
+Unsupported operand types: resource << null
+Unsupported operand types: null << resource
+Unsupported operand types: resource << bool
+Unsupported operand types: bool << resource
+Unsupported operand types: resource << bool
+Unsupported operand types: bool << resource
+Unsupported operand types: resource << int
+Unsupported operand types: int << resource
+Unsupported operand types: resource << float
+Unsupported operand types: float << resource
+Unsupported operand types: resource << string
+Unsupported operand types: string << resource
+Unsupported operand types: resource << string
+Warning: A non-numeric value encountered
+Unsupported operand types: string << resource
+Unsupported operand types: array >> array
+Unsupported operand types: array >> object
+Unsupported operand types: array >> resource
+Unsupported operand types: object >> array
+Unsupported operand types: object >> object
+Unsupported operand types: object >> resource
+Unsupported operand types: resource >> array
+Unsupported operand types: resource >> object
+Unsupported operand types: resource >> resource
+Unsupported operand types: array >> null
+Unsupported operand types: null >> array
+Unsupported operand types: array >> bool
+Unsupported operand types: bool >> array
+Unsupported operand types: array >> bool
+Unsupported operand types: bool >> array
+Unsupported operand types: array >> int
+Unsupported operand types: int >> array
+Unsupported operand types: array >> float
+Unsupported operand types: float >> array
+Unsupported operand types: array >> string
+Unsupported operand types: string >> array
+Unsupported operand types: array >> string
+Warning: A non-numeric value encountered
+Unsupported operand types: string >> array
+Unsupported operand types: object >> null
+Unsupported operand types: null >> object
+Unsupported operand types: object >> bool
+Unsupported operand types: bool >> object
+Unsupported operand types: object >> bool
+Unsupported operand types: bool >> object
+Unsupported operand types: object >> int
+Unsupported operand types: int >> object
+Unsupported operand types: object >> float
+Unsupported operand types: float >> object
+Unsupported operand types: object >> string
+Unsupported operand types: string >> object
+Unsupported operand types: object >> string
+Warning: A non-numeric value encountered
+Unsupported operand types: string >> object
+Unsupported operand types: resource >> null
+Unsupported operand types: null >> resource
+Unsupported operand types: resource >> bool
+Unsupported operand types: bool >> resource
+Unsupported operand types: resource >> bool
+Unsupported operand types: bool >> resource
+Unsupported operand types: resource >> int
+Unsupported operand types: int >> resource
+Unsupported operand types: resource >> float
+Unsupported operand types: float >> resource
+Unsupported operand types: resource >> string
+Unsupported operand types: string >> resource
+Unsupported operand types: resource >> string
+Warning: A non-numeric value encountered
+Unsupported operand types: string >> resource
+Unsupported operand types: array & array
+Unsupported operand types: object & array
+Unsupported operand types: resource & array
+Unsupported operand types: object & array
+Unsupported operand types: object & object
+Unsupported operand types: object & resource
+Unsupported operand types: resource & array
+Unsupported operand types: object & resource
+Unsupported operand types: resource & resource
+Unsupported operand types: array & null
+Unsupported operand types: null & array
+Unsupported operand types: array & bool
+Unsupported operand types: bool & array
+Unsupported operand types: array & bool
+Unsupported operand types: bool & array
+Unsupported operand types: array & int
+Unsupported operand types: int & array
+Unsupported operand types: array & float
+Unsupported operand types: float & array
+Unsupported operand types: array & string
+Unsupported operand types: string & array
+Unsupported operand types: array & string
+Warning: A non-numeric value encountered
+Unsupported operand types: string & array
+Unsupported operand types: object & null
+Unsupported operand types: object & null
+Unsupported operand types: object & bool
+Unsupported operand types: object & bool
+Unsupported operand types: object & bool
+Unsupported operand types: object & bool
+Unsupported operand types: object & int
+Unsupported operand types: object & int
+Unsupported operand types: object & float
+Unsupported operand types: object & float
+Unsupported operand types: object & string
+Unsupported operand types: object & string
+Unsupported operand types: object & string
+Unsupported operand types: object & string
+Unsupported operand types: resource & null
+Unsupported operand types: resource & null
+Unsupported operand types: resource & bool
+Unsupported operand types: resource & bool
+Unsupported operand types: resource & bool
+Unsupported operand types: resource & bool
+Unsupported operand types: resource & int
+Unsupported operand types: resource & int
+Unsupported operand types: resource & float
+Unsupported operand types: resource & float
+Unsupported operand types: resource & string
+Unsupported operand types: resource & string
+Unsupported operand types: resource & string
+Unsupported operand types: resource & string
+Unsupported operand types: array | array
+Unsupported operand types: object | array
+Unsupported operand types: resource | array
+Unsupported operand types: object | array
+Unsupported operand types: object | object
+Unsupported operand types: object | resource
+Unsupported operand types: resource | array
+Unsupported operand types: object | resource
+Unsupported operand types: resource | resource
+Unsupported operand types: array | null
+Unsupported operand types: null | array
+Unsupported operand types: array | bool
+Unsupported operand types: bool | array
+Unsupported operand types: array | bool
+Unsupported operand types: bool | array
+Unsupported operand types: array | int
+Unsupported operand types: int | array
+Unsupported operand types: array | float
+Unsupported operand types: float | array
+Unsupported operand types: array | string
+Unsupported operand types: string | array
+Unsupported operand types: array | string
+Warning: A non-numeric value encountered
+Unsupported operand types: string | array
+Unsupported operand types: object | null
+Unsupported operand types: object | null
+Unsupported operand types: object | bool
+Unsupported operand types: object | bool
+Unsupported operand types: object | bool
+Unsupported operand types: object | bool
+Unsupported operand types: object | int
+Unsupported operand types: object | int
+Unsupported operand types: object | float
+Unsupported operand types: object | float
+Unsupported operand types: object | string
+Unsupported operand types: object | string
+Unsupported operand types: object | string
+Unsupported operand types: object | string
+Unsupported operand types: resource | null
+Unsupported operand types: resource | null
+Unsupported operand types: resource | bool
+Unsupported operand types: resource | bool
+Unsupported operand types: resource | bool
+Unsupported operand types: resource | bool
+Unsupported operand types: resource | int
+Unsupported operand types: resource | int
+Unsupported operand types: resource | float
+Unsupported operand types: resource | float
+Unsupported operand types: resource | string
+Unsupported operand types: resource | string
+Unsupported operand types: resource | string
+Unsupported operand types: resource | string
+Unsupported operand types: array ^ array
+Unsupported operand types: object ^ array
+Unsupported operand types: resource ^ array
+Unsupported operand types: object ^ array
+Unsupported operand types: object ^ object
+Unsupported operand types: object ^ resource
+Unsupported operand types: resource ^ array
+Unsupported operand types: object ^ resource
+Unsupported operand types: resource ^ resource
+Unsupported operand types: array ^ null
+Unsupported operand types: null ^ array
+Unsupported operand types: array ^ bool
+Unsupported operand types: bool ^ array
+Unsupported operand types: array ^ bool
+Unsupported operand types: bool ^ array
+Unsupported operand types: array ^ int
+Unsupported operand types: int ^ array
+Unsupported operand types: array ^ float
+Unsupported operand types: float ^ array
+Unsupported operand types: array ^ string
+Unsupported operand types: string ^ array
+Unsupported operand types: array ^ string
+Warning: A non-numeric value encountered
+Unsupported operand types: string ^ array
+Unsupported operand types: object ^ null
+Unsupported operand types: object ^ null
+Unsupported operand types: object ^ bool
+Unsupported operand types: object ^ bool
+Unsupported operand types: object ^ bool
+Unsupported operand types: object ^ bool
+Unsupported operand types: object ^ int
+Unsupported operand types: object ^ int
+Unsupported operand types: object ^ float
+Unsupported operand types: object ^ float
+Unsupported operand types: object ^ string
+Unsupported operand types: object ^ string
+Unsupported operand types: object ^ string
+Unsupported operand types: object ^ string
+Unsupported operand types: resource ^ null
+Unsupported operand types: resource ^ null
+Unsupported operand types: resource ^ bool
+Unsupported operand types: resource ^ bool
+Unsupported operand types: resource ^ bool
+Unsupported operand types: resource ^ bool
+Unsupported operand types: resource ^ int
+Unsupported operand types: resource ^ int
+Unsupported operand types: resource ^ float
+Unsupported operand types: resource ^ float
+Unsupported operand types: resource ^ string
+Unsupported operand types: resource ^ string
+Unsupported operand types: resource ^ string
+Unsupported operand types: resource ^ string
+No error for [] xor []
+No error for [] xor new stdClass
+No error for [] xor STDOUT
+No error for new stdClass xor []
+No error for new stdClass xor new stdClass
+No error for new stdClass xor STDOUT
+No error for STDOUT xor []
+No error for STDOUT xor new stdClass
+No error for STDOUT xor STDOUT
+No error for [] xor null
+No error for null xor []
+No error for [] xor true
+No error for true xor []
+No error for [] xor false
+No error for false xor []
+No error for [] xor 2
+No error for 2 xor []
+No error for [] xor 3.5
+No error for 3.5 xor []
+No error for [] xor "123"
+No error for "123" xor []
+No error for [] xor "foo"
+No error for "foo" xor []
+No error for new stdClass xor null
+No error for null xor new stdClass
+No error for new stdClass xor true
+No error for true xor new stdClass
+No error for new stdClass xor false
+No error for false xor new stdClass
+No error for new stdClass xor 2
+No error for 2 xor new stdClass
+No error for new stdClass xor 3.5
+No error for 3.5 xor new stdClass
+No error for new stdClass xor "123"
+No error for "123" xor new stdClass
+No error for new stdClass xor "foo"
+No error for "foo" xor new stdClass
+No error for STDOUT xor null
+No error for null xor STDOUT
+No error for STDOUT xor true
+No error for true xor STDOUT
+No error for STDOUT xor false
+No error for false xor STDOUT
+No error for STDOUT xor 2
+No error for 2 xor STDOUT
+No error for STDOUT xor 3.5
+No error for 3.5 xor STDOUT
+No error for STDOUT xor "123"
+No error for "123" xor STDOUT
+No error for STDOUT xor "foo"
+No error for "foo" xor STDOUT
+Warning: Array to string conversion
+Warning: Array to string conversion
+No error for [] . []
+Warning: Array to string conversion
+Object of class stdClass could not be converted to string
+Warning: Array to string conversion
+No error for [] . STDOUT
+Warning: Array to string conversion
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Warning: Array to string conversion
+No error for STDOUT . []
+Object of class stdClass could not be converted to string
+No error for STDOUT . STDOUT
+Warning: Array to string conversion
+No error for [] . null
+Warning: Array to string conversion
+No error for null . []
+Warning: Array to string conversion
+No error for [] . true
+Warning: Array to string conversion
+No error for true . []
+Warning: Array to string conversion
+No error for [] . false
+Warning: Array to string conversion
+No error for false . []
+Warning: Array to string conversion
+No error for [] . 2
+Warning: Array to string conversion
+No error for 2 . []
+Warning: Array to string conversion
+No error for [] . 3.5
+Warning: Array to string conversion
+No error for 3.5 . []
+Warning: Array to string conversion
+No error for [] . "123"
+Warning: Array to string conversion
+No error for "123" . []
+Warning: Array to string conversion
+No error for [] . "foo"
+Warning: Array to string conversion
+No error for "foo" . []
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+No error for STDOUT . null
+No error for null . STDOUT
+No error for STDOUT . true
+No error for true . STDOUT
+No error for STDOUT . false
+No error for false . STDOUT
+No error for STDOUT . 2
+No error for 2 . STDOUT
+No error for STDOUT . 3.5
+No error for 3.5 . STDOUT
+No error for STDOUT . "123"
+No error for "123" . STDOUT
+No error for STDOUT . "foo"
+No error for "foo" . STDOUT
+
+
+ASSIGN OP:
+No error for [] += []
+Unsupported operand types: array + object
+Unsupported operand types: array + resource
+Unsupported operand types: object + array
+Unsupported operand types: object + object
+Unsupported operand types: object + resource
+Unsupported operand types: resource + array
+Unsupported operand types: resource + object
+Unsupported operand types: resource + resource
+Unsupported operand types: array + null
+Unsupported operand types: null + array
+Unsupported operand types: array + bool
+Unsupported operand types: bool + array
+Unsupported operand types: array + bool
+Unsupported operand types: bool + array
+Unsupported operand types: array + int
+Unsupported operand types: int + array
+Unsupported operand types: array + float
+Unsupported operand types: float + array
+Unsupported operand types: array + string
+Unsupported operand types: string + array
+Unsupported operand types: array + string
+Warning: A non-numeric value encountered
+Unsupported operand types: string + array
+Unsupported operand types: object + null
+Unsupported operand types: null + object
+Unsupported operand types: object + bool
+Unsupported operand types: bool + object
+Unsupported operand types: object + bool
+Unsupported operand types: bool + object
+Unsupported operand types: object + int
+Unsupported operand types: int + object
+Unsupported operand types: object + float
+Unsupported operand types: float + object
+Unsupported operand types: object + string
+Unsupported operand types: string + object
+Unsupported operand types: object + string
+Warning: A non-numeric value encountered
+Unsupported operand types: string + object
+Unsupported operand types: resource + null
+Unsupported operand types: null + resource
+Unsupported operand types: resource + bool
+Unsupported operand types: bool + resource
+Unsupported operand types: resource + bool
+Unsupported operand types: bool + resource
+Unsupported operand types: resource + int
+Unsupported operand types: int + resource
+Unsupported operand types: resource + float
+Unsupported operand types: float + resource
+Unsupported operand types: resource + string
+Unsupported operand types: string + resource
+Unsupported operand types: resource + string
+Warning: A non-numeric value encountered
+Unsupported operand types: string + resource
+Unsupported operand types: array - array
+Unsupported operand types: array - object
+Unsupported operand types: array - resource
+Unsupported operand types: object - array
+Unsupported operand types: object - object
+Unsupported operand types: object - resource
+Unsupported operand types: resource - array
+Unsupported operand types: resource - object
+Unsupported operand types: resource - resource
+Unsupported operand types: array - null
+Unsupported operand types: null - array
+Unsupported operand types: array - bool
+Unsupported operand types: bool - array
+Unsupported operand types: array - bool
+Unsupported operand types: bool - array
+Unsupported operand types: array - int
+Unsupported operand types: int - array
+Unsupported operand types: array - float
+Unsupported operand types: float - array
+Unsupported operand types: array - string
+Unsupported operand types: string - array
+Unsupported operand types: array - string
+Warning: A non-numeric value encountered
+Unsupported operand types: string - array
+Unsupported operand types: object - null
+Unsupported operand types: null - object
+Unsupported operand types: object - bool
+Unsupported operand types: bool - object
+Unsupported operand types: object - bool
+Unsupported operand types: bool - object
+Unsupported operand types: object - int
+Unsupported operand types: int - object
+Unsupported operand types: object - float
+Unsupported operand types: float - object
+Unsupported operand types: object - string
+Unsupported operand types: string - object
+Unsupported operand types: object - string
+Warning: A non-numeric value encountered
+Unsupported operand types: string - object
+Unsupported operand types: resource - null
+Unsupported operand types: null - resource
+Unsupported operand types: resource - bool
+Unsupported operand types: bool - resource
+Unsupported operand types: resource - bool
+Unsupported operand types: bool - resource
+Unsupported operand types: resource - int
+Unsupported operand types: int - resource
+Unsupported operand types: resource - float
+Unsupported operand types: float - resource
+Unsupported operand types: resource - string
+Unsupported operand types: string - resource
+Unsupported operand types: resource - string
+Warning: A non-numeric value encountered
+Unsupported operand types: string - resource
+Unsupported operand types: array * array
+Unsupported operand types: array * object
+Unsupported operand types: array * resource
+Unsupported operand types: object * array
+Unsupported operand types: object * object
+Unsupported operand types: object * resource
+Unsupported operand types: resource * array
+Unsupported operand types: resource * object
+Unsupported operand types: resource * resource
+Unsupported operand types: array * null
+Unsupported operand types: null * array
+Unsupported operand types: array * bool
+Unsupported operand types: bool * array
+Unsupported operand types: array * bool
+Unsupported operand types: bool * array
+Unsupported operand types: array * int
+Unsupported operand types: int * array
+Unsupported operand types: array * float
+Unsupported operand types: float * array
+Unsupported operand types: array * string
+Unsupported operand types: string * array
+Unsupported operand types: array * string
+Warning: A non-numeric value encountered
+Unsupported operand types: string * array
+Unsupported operand types: object * null
+Unsupported operand types: null * object
+Unsupported operand types: object * bool
+Unsupported operand types: bool * object
+Unsupported operand types: object * bool
+Unsupported operand types: bool * object
+Unsupported operand types: object * int
+Unsupported operand types: int * object
+Unsupported operand types: object * float
+Unsupported operand types: float * object
+Unsupported operand types: object * string
+Unsupported operand types: string * object
+Unsupported operand types: object * string
+Warning: A non-numeric value encountered
+Unsupported operand types: string * object
+Unsupported operand types: resource * null
+Unsupported operand types: null * resource
+Unsupported operand types: resource * bool
+Unsupported operand types: bool * resource
+Unsupported operand types: resource * bool
+Unsupported operand types: bool * resource
+Unsupported operand types: resource * int
+Unsupported operand types: int * resource
+Unsupported operand types: resource * float
+Unsupported operand types: float * resource
+Unsupported operand types: resource * string
+Unsupported operand types: string * resource
+Unsupported operand types: resource * string
+Warning: A non-numeric value encountered
+Unsupported operand types: string * resource
+Unsupported operand types: array / array
+Unsupported operand types: array / object
+Unsupported operand types: array / resource
+Unsupported operand types: object / array
+Unsupported operand types: object / object
+Unsupported operand types: object / resource
+Unsupported operand types: resource / array
+Unsupported operand types: resource / object
+Unsupported operand types: resource / resource
+Unsupported operand types: array / null
+Unsupported operand types: null / array
+Unsupported operand types: array / bool
+Unsupported operand types: bool / array
+Unsupported operand types: array / bool
+Unsupported operand types: bool / array
+Unsupported operand types: array / int
+Unsupported operand types: int / array
+Unsupported operand types: array / float
+Unsupported operand types: float / array
+Unsupported operand types: array / string
+Unsupported operand types: string / array
+Unsupported operand types: array / string
+Warning: A non-numeric value encountered
+Unsupported operand types: string / array
+Unsupported operand types: object / null
+Unsupported operand types: null / object
+Unsupported operand types: object / bool
+Unsupported operand types: bool / object
+Unsupported operand types: object / bool
+Unsupported operand types: bool / object
+Unsupported operand types: object / int
+Unsupported operand types: int / object
+Unsupported operand types: object / float
+Unsupported operand types: float / object
+Unsupported operand types: object / string
+Unsupported operand types: string / object
+Unsupported operand types: object / string
+Warning: A non-numeric value encountered
+Unsupported operand types: string / object
+Unsupported operand types: resource / null
+Unsupported operand types: null / resource
+Unsupported operand types: resource / bool
+Unsupported operand types: bool / resource
+Unsupported operand types: resource / bool
+Unsupported operand types: bool / resource
+Unsupported operand types: resource / int
+Unsupported operand types: int / resource
+Unsupported operand types: resource / float
+Unsupported operand types: float / resource
+Unsupported operand types: resource / string
+Unsupported operand types: string / resource
+Unsupported operand types: resource / string
+Warning: A non-numeric value encountered
+Unsupported operand types: string / resource
+Unsupported operand types: array % array
+Unsupported operand types: array % object
+Unsupported operand types: array % resource
+Unsupported operand types: object % array
+Unsupported operand types: object % object
+Unsupported operand types: object % resource
+Unsupported operand types: resource % array
+Unsupported operand types: resource % object
+Unsupported operand types: resource % resource
+Unsupported operand types: array % null
+Unsupported operand types: null % array
+Unsupported operand types: array % bool
+Unsupported operand types: bool % array
+Unsupported operand types: array % bool
+Unsupported operand types: bool % array
+Unsupported operand types: array % int
+Unsupported operand types: int % array
+Unsupported operand types: array % float
+Unsupported operand types: float % array
+Unsupported operand types: array % string
+Unsupported operand types: string % array
+Unsupported operand types: array % string
+Warning: A non-numeric value encountered
+Unsupported operand types: string % array
+Unsupported operand types: object % null
+Unsupported operand types: null % object
+Unsupported operand types: object % bool
+Unsupported operand types: bool % object
+Unsupported operand types: object % bool
+Unsupported operand types: bool % object
+Unsupported operand types: object % int
+Unsupported operand types: int % object
+Unsupported operand types: object % float
+Unsupported operand types: float % object
+Unsupported operand types: object % string
+Unsupported operand types: string % object
+Unsupported operand types: object % string
+Warning: A non-numeric value encountered
+Unsupported operand types: string % object
+Unsupported operand types: resource % null
+Unsupported operand types: null % resource
+Unsupported operand types: resource % bool
+Unsupported operand types: bool % resource
+Unsupported operand types: resource % bool
+Unsupported operand types: bool % resource
+Unsupported operand types: resource % int
+Unsupported operand types: int % resource
+Unsupported operand types: resource % float
+Unsupported operand types: float % resource
+Unsupported operand types: resource % string
+Unsupported operand types: string % resource
+Unsupported operand types: resource % string
+Warning: A non-numeric value encountered
+Unsupported operand types: string % resource
+Unsupported operand types: array ** array
+Unsupported operand types: array ** object
+Unsupported operand types: array ** resource
+Unsupported operand types: object ** array
+Unsupported operand types: object ** object
+Unsupported operand types: object ** resource
+Unsupported operand types: resource ** array
+Unsupported operand types: resource ** object
+Unsupported operand types: resource ** resource
+Unsupported operand types: array ** null
+Unsupported operand types: null ** array
+Unsupported operand types: array ** bool
+Unsupported operand types: bool ** array
+Unsupported operand types: array ** bool
+Unsupported operand types: bool ** array
+Unsupported operand types: array ** int
+Unsupported operand types: int ** array
+Unsupported operand types: array ** float
+Unsupported operand types: float ** array
+Unsupported operand types: array ** string
+Unsupported operand types: string ** array
+Unsupported operand types: array ** string
+Warning: A non-numeric value encountered
+Unsupported operand types: string ** array
+Unsupported operand types: object ** null
+Unsupported operand types: null ** object
+Unsupported operand types: object ** bool
+Unsupported operand types: bool ** object
+Unsupported operand types: object ** bool
+Unsupported operand types: bool ** object
+Unsupported operand types: object ** int
+Unsupported operand types: int ** object
+Unsupported operand types: object ** float
+Unsupported operand types: float ** object
+Unsupported operand types: object ** string
+Unsupported operand types: string ** object
+Unsupported operand types: object ** string
+Warning: A non-numeric value encountered
+Unsupported operand types: string ** object
+Unsupported operand types: resource ** null
+Unsupported operand types: null ** resource
+Unsupported operand types: resource ** bool
+Unsupported operand types: bool ** resource
+Unsupported operand types: resource ** bool
+Unsupported operand types: bool ** resource
+Unsupported operand types: resource ** int
+Unsupported operand types: int ** resource
+Unsupported operand types: resource ** float
+Unsupported operand types: float ** resource
+Unsupported operand types: resource ** string
+Unsupported operand types: string ** resource
+Unsupported operand types: resource ** string
+Warning: A non-numeric value encountered
+Unsupported operand types: string ** resource
+Unsupported operand types: array << array
+Unsupported operand types: array << object
+Unsupported operand types: array << resource
+Unsupported operand types: object << array
+Unsupported operand types: object << object
+Unsupported operand types: object << resource
+Unsupported operand types: resource << array
+Unsupported operand types: resource << object
+Unsupported operand types: resource << resource
+Unsupported operand types: array << null
+Unsupported operand types: null << array
+Unsupported operand types: array << bool
+Unsupported operand types: bool << array
+Unsupported operand types: array << bool
+Unsupported operand types: bool << array
+Unsupported operand types: array << int
+Unsupported operand types: int << array
+Unsupported operand types: array << float
+Unsupported operand types: float << array
+Unsupported operand types: array << string
+Unsupported operand types: string << array
+Unsupported operand types: array << string
+Warning: A non-numeric value encountered
+Unsupported operand types: string << array
+Unsupported operand types: object << null
+Unsupported operand types: null << object
+Unsupported operand types: object << bool
+Unsupported operand types: bool << object
+Unsupported operand types: object << bool
+Unsupported operand types: bool << object
+Unsupported operand types: object << int
+Unsupported operand types: int << object
+Unsupported operand types: object << float
+Unsupported operand types: float << object
+Unsupported operand types: object << string
+Unsupported operand types: string << object
+Unsupported operand types: object << string
+Warning: A non-numeric value encountered
+Unsupported operand types: string << object
+Unsupported operand types: resource << null
+Unsupported operand types: null << resource
+Unsupported operand types: resource << bool
+Unsupported operand types: bool << resource
+Unsupported operand types: resource << bool
+Unsupported operand types: bool << resource
+Unsupported operand types: resource << int
+Unsupported operand types: int << resource
+Unsupported operand types: resource << float
+Unsupported operand types: float << resource
+Unsupported operand types: resource << string
+Unsupported operand types: string << resource
+Unsupported operand types: resource << string
+Warning: A non-numeric value encountered
+Unsupported operand types: string << resource
+Unsupported operand types: array >> array
+Unsupported operand types: array >> object
+Unsupported operand types: array >> resource
+Unsupported operand types: object >> array
+Unsupported operand types: object >> object
+Unsupported operand types: object >> resource
+Unsupported operand types: resource >> array
+Unsupported operand types: resource >> object
+Unsupported operand types: resource >> resource
+Unsupported operand types: array >> null
+Unsupported operand types: null >> array
+Unsupported operand types: array >> bool
+Unsupported operand types: bool >> array
+Unsupported operand types: array >> bool
+Unsupported operand types: bool >> array
+Unsupported operand types: array >> int
+Unsupported operand types: int >> array
+Unsupported operand types: array >> float
+Unsupported operand types: float >> array
+Unsupported operand types: array >> string
+Unsupported operand types: string >> array
+Unsupported operand types: array >> string
+Warning: A non-numeric value encountered
+Unsupported operand types: string >> array
+Unsupported operand types: object >> null
+Unsupported operand types: null >> object
+Unsupported operand types: object >> bool
+Unsupported operand types: bool >> object
+Unsupported operand types: object >> bool
+Unsupported operand types: bool >> object
+Unsupported operand types: object >> int
+Unsupported operand types: int >> object
+Unsupported operand types: object >> float
+Unsupported operand types: float >> object
+Unsupported operand types: object >> string
+Unsupported operand types: string >> object
+Unsupported operand types: object >> string
+Warning: A non-numeric value encountered
+Unsupported operand types: string >> object
+Unsupported operand types: resource >> null
+Unsupported operand types: null >> resource
+Unsupported operand types: resource >> bool
+Unsupported operand types: bool >> resource
+Unsupported operand types: resource >> bool
+Unsupported operand types: bool >> resource
+Unsupported operand types: resource >> int
+Unsupported operand types: int >> resource
+Unsupported operand types: resource >> float
+Unsupported operand types: float >> resource
+Unsupported operand types: resource >> string
+Unsupported operand types: string >> resource
+Unsupported operand types: resource >> string
+Warning: A non-numeric value encountered
+Unsupported operand types: string >> resource
+Unsupported operand types: array & array
+Unsupported operand types: array & object
+Unsupported operand types: array & resource
+Unsupported operand types: object & array
+Unsupported operand types: object & object
+Unsupported operand types: object & resource
+Unsupported operand types: resource & array
+Unsupported operand types: resource & object
+Unsupported operand types: resource & resource
+Unsupported operand types: array & null
+Unsupported operand types: null & array
+Unsupported operand types: array & bool
+Unsupported operand types: bool & array
+Unsupported operand types: array & bool
+Unsupported operand types: bool & array
+Unsupported operand types: array & int
+Unsupported operand types: int & array
+Unsupported operand types: array & float
+Unsupported operand types: float & array
+Unsupported operand types: array & string
+Unsupported operand types: string & array
+Unsupported operand types: array & string
+Warning: A non-numeric value encountered
+Unsupported operand types: string & array
+Unsupported operand types: object & null
+Unsupported operand types: null & object
+Unsupported operand types: object & bool
+Unsupported operand types: bool & object
+Unsupported operand types: object & bool
+Unsupported operand types: bool & object
+Unsupported operand types: object & int
+Unsupported operand types: int & object
+Unsupported operand types: object & float
+Unsupported operand types: float & object
+Unsupported operand types: object & string
+Unsupported operand types: string & object
+Unsupported operand types: object & string
+Warning: A non-numeric value encountered
+Unsupported operand types: string & object
+Unsupported operand types: resource & null
+Unsupported operand types: null & resource
+Unsupported operand types: resource & bool
+Unsupported operand types: bool & resource
+Unsupported operand types: resource & bool
+Unsupported operand types: bool & resource
+Unsupported operand types: resource & int
+Unsupported operand types: int & resource
+Unsupported operand types: resource & float
+Unsupported operand types: float & resource
+Unsupported operand types: resource & string
+Unsupported operand types: string & resource
+Unsupported operand types: resource & string
+Warning: A non-numeric value encountered
+Unsupported operand types: string & resource
+Unsupported operand types: array | array
+Unsupported operand types: array | object
+Unsupported operand types: array | resource
+Unsupported operand types: object | array
+Unsupported operand types: object | object
+Unsupported operand types: object | resource
+Unsupported operand types: resource | array
+Unsupported operand types: resource | object
+Unsupported operand types: resource | resource
+Unsupported operand types: array | null
+Unsupported operand types: null | array
+Unsupported operand types: array | bool
+Unsupported operand types: bool | array
+Unsupported operand types: array | bool
+Unsupported operand types: bool | array
+Unsupported operand types: array | int
+Unsupported operand types: int | array
+Unsupported operand types: array | float
+Unsupported operand types: float | array
+Unsupported operand types: array | string
+Unsupported operand types: string | array
+Unsupported operand types: array | string
+Warning: A non-numeric value encountered
+Unsupported operand types: string | array
+Unsupported operand types: object | null
+Unsupported operand types: null | object
+Unsupported operand types: object | bool
+Unsupported operand types: bool | object
+Unsupported operand types: object | bool
+Unsupported operand types: bool | object
+Unsupported operand types: object | int
+Unsupported operand types: int | object
+Unsupported operand types: object | float
+Unsupported operand types: float | object
+Unsupported operand types: object | string
+Unsupported operand types: string | object
+Unsupported operand types: object | string
+Warning: A non-numeric value encountered
+Unsupported operand types: string | object
+Unsupported operand types: resource | null
+Unsupported operand types: null | resource
+Unsupported operand types: resource | bool
+Unsupported operand types: bool | resource
+Unsupported operand types: resource | bool
+Unsupported operand types: bool | resource
+Unsupported operand types: resource | int
+Unsupported operand types: int | resource
+Unsupported operand types: resource | float
+Unsupported operand types: float | resource
+Unsupported operand types: resource | string
+Unsupported operand types: string | resource
+Unsupported operand types: resource | string
+Warning: A non-numeric value encountered
+Unsupported operand types: string | resource
+Unsupported operand types: array ^ array
+Unsupported operand types: array ^ object
+Unsupported operand types: array ^ resource
+Unsupported operand types: object ^ array
+Unsupported operand types: object ^ object
+Unsupported operand types: object ^ resource
+Unsupported operand types: resource ^ array
+Unsupported operand types: resource ^ object
+Unsupported operand types: resource ^ resource
+Unsupported operand types: array ^ null
+Unsupported operand types: null ^ array
+Unsupported operand types: array ^ bool
+Unsupported operand types: bool ^ array
+Unsupported operand types: array ^ bool
+Unsupported operand types: bool ^ array
+Unsupported operand types: array ^ int
+Unsupported operand types: int ^ array
+Unsupported operand types: array ^ float
+Unsupported operand types: float ^ array
+Unsupported operand types: array ^ string
+Unsupported operand types: string ^ array
+Unsupported operand types: array ^ string
+Warning: A non-numeric value encountered
+Unsupported operand types: string ^ array
+Unsupported operand types: object ^ null
+Unsupported operand types: null ^ object
+Unsupported operand types: object ^ bool
+Unsupported operand types: bool ^ object
+Unsupported operand types: object ^ bool
+Unsupported operand types: bool ^ object
+Unsupported operand types: object ^ int
+Unsupported operand types: int ^ object
+Unsupported operand types: object ^ float
+Unsupported operand types: float ^ object
+Unsupported operand types: object ^ string
+Unsupported operand types: string ^ object
+Unsupported operand types: object ^ string
+Warning: A non-numeric value encountered
+Unsupported operand types: string ^ object
+Unsupported operand types: resource ^ null
+Unsupported operand types: null ^ resource
+Unsupported operand types: resource ^ bool
+Unsupported operand types: bool ^ resource
+Unsupported operand types: resource ^ bool
+Unsupported operand types: bool ^ resource
+Unsupported operand types: resource ^ int
+Unsupported operand types: int ^ resource
+Unsupported operand types: resource ^ float
+Unsupported operand types: float ^ resource
+Unsupported operand types: resource ^ string
+Unsupported operand types: string ^ resource
+Unsupported operand types: resource ^ string
+Warning: A non-numeric value encountered
+Unsupported operand types: string ^ resource
+Warning: Array to string conversion
+Warning: Array to string conversion
+No error for [] .= []
+Warning: Array to string conversion
+Object of class stdClass could not be converted to string
+Warning: Array to string conversion
+No error for [] .= STDOUT
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Warning: Array to string conversion
+No error for STDOUT .= []
+Object of class stdClass could not be converted to string
+No error for STDOUT .= STDOUT
+Warning: Array to string conversion
+No error for [] .= null
+Warning: Array to string conversion
+No error for null .= []
+Warning: Array to string conversion
+No error for [] .= true
+Warning: Array to string conversion
+No error for true .= []
+Warning: Array to string conversion
+No error for [] .= false
+Warning: Array to string conversion
+No error for false .= []
+Warning: Array to string conversion
+No error for [] .= 2
+Warning: Array to string conversion
+No error for 2 .= []
+Warning: Array to string conversion
+No error for [] .= 3.5
+Warning: Array to string conversion
+No error for 3.5 .= []
+Warning: Array to string conversion
+No error for [] .= "123"
+Warning: Array to string conversion
+No error for "123" .= []
+Warning: Array to string conversion
+No error for [] .= "foo"
+Warning: Array to string conversion
+No error for "foo" .= []
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+Object of class stdClass could not be converted to string
+No error for STDOUT .= null
+No error for null .= STDOUT
+No error for STDOUT .= true
+No error for true .= STDOUT
+No error for STDOUT .= false
+No error for false .= STDOUT
+No error for STDOUT .= 2
+No error for 2 .= STDOUT
+No error for STDOUT .= 3.5
+No error for 3.5 .= STDOUT
+No error for STDOUT .= "123"
+No error for "123" .= STDOUT
+No error for STDOUT .= "foo"
+No error for "foo" .= STDOUT
+
+
+UNARY OP:
+Cannot perform bitwise not on array
+Cannot perform bitwise not on object
+Cannot perform bitwise not on resource
+
+
+INCDEC:
+Cannot increment array
+Cannot decrement array
+Cannot increment object
+Cannot decrement object
+Cannot increment resource
+Cannot decrement resource
diff --git a/Zend/tests/throw/001.phpt b/Zend/tests/throw/001.phpt
index 072d9f45b5..deb8743ab5 100644
--- a/Zend/tests/throw/001.phpt
+++ b/Zend/tests/throw/001.phpt
@@ -148,7 +148,7 @@ try {
}
?>
---EXPECTF--
+--EXPECT--
string(13) "true && throw"
bool(false)
string(14) "true and throw"
@@ -167,9 +167,7 @@ string(3) "bar"
string(11) "exception 1"
bool(true)
string(20) "false ? true : throw"
-
-Notice: Object of class Exception could not be converted to number in %s on line %d
-string(22) "Can only throw objects"
+string(39) "Unsupported operand types: object + int"
string(35) "throw $exception = new Exception();"
string(37) "throw $exception ??= new Exception();"
string(30) "throw null ?? new Exception();"
diff --git a/Zend/tests/xor_001.phpt b/Zend/tests/xor_001.phpt
index 1a6d0fb633..9678af16b5 100644
--- a/Zend/tests/xor_001.phpt
+++ b/Zend/tests/xor_001.phpt
@@ -6,11 +6,14 @@ XORing arrays
$a = array(1,2,3);
$b = array();
-$c = $a ^ $b;
-var_dump($c);
+try {
+ $c = $a ^ $b;
+} catch (TypeError $e) {
+ echo $e->getMessage(), "\n";
+}
echo "Done\n";
?>
--EXPECT--
-int(1)
+Unsupported operand types: array ^ array
Done
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index bc214fa39a..8e620b2779 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -7219,11 +7219,9 @@ ZEND_API zend_bool zend_binary_op_produces_error(uint32_t opcode, zval *op1, zva
/* Adding two arrays is allowed. */
return 0;
}
- if (opcode == ZEND_ADD || opcode == ZEND_SUB || opcode == ZEND_MUL || opcode == ZEND_POW
- || opcode == ZEND_DIV) {
- /* These operators throw when one of the operands is an array. */
- return 1;
- }
+
+ /* Numeric operators throw when one of the operands is an array. */
+ return 1;
}
/* While basic arithmetic operators always produce numeric string errors,
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 7737667940..012e95d3b2 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -251,20 +251,17 @@ static zend_never_inline int ZEND_FASTCALL _zendi_try_convert_scalar_to_number(z
}
}
return SUCCESS;
- case IS_RESOURCE:
- ZVAL_LONG(holder, Z_RES_HANDLE_P(op));
- return SUCCESS;
case IS_OBJECT:
- convert_object_to_type(op, holder, _IS_NUMBER);
- if (UNEXPECTED(EG(exception))) {
+ if (Z_OBJ_HT_P(op)->cast_object(Z_OBJ_P(op), holder, _IS_NUMBER) == FAILURE
+ || EG(exception)) {
return FAILURE;
}
- if (UNEXPECTED(Z_TYPE_P(holder) != IS_LONG && Z_TYPE_P(holder) != IS_DOUBLE)) {
- ZVAL_LONG(holder, 1);
- }
+ ZEND_ASSERT(Z_TYPE_P(holder) == IS_LONG || Z_TYPE_P(holder) == IS_DOUBLE);
return SUCCESS;
- default:
+ case IS_RESOURCE:
+ case IS_ARRAY:
return FAILURE;
+ EMPTY_SWITCH_DEFAULT_CASE()
}
}
/* }}} */
@@ -280,6 +277,59 @@ static zend_always_inline int zendi_try_convert_scalar_to_number(zval *op, zval
}
/* }}} */
+static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(zval *op, zend_bool *failed) /* {{{ */
+{
+ *failed = 0;
+ switch (Z_TYPE_P(op)) {
+ case IS_NULL:
+ case IS_FALSE:
+ return 0;
+ case IS_TRUE:
+ return 1;
+ case IS_DOUBLE:
+ return zend_dval_to_lval(Z_DVAL_P(op));
+ case IS_STRING:
+ {
+ zend_uchar type;
+ zend_long lval;
+ double dval;
+ if (0 == (type = is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &lval, &dval, -1))) {
+ zend_error(E_WARNING, "A non-numeric value encountered");
+ if (UNEXPECTED(EG(exception))) {
+ *failed = 1;
+ }
+ return 0;
+ } else if (EXPECTED(type == IS_LONG)) {
+ return lval;
+ } else {
+ /* Previously we used strtol here, not is_numeric_string,
+ * and strtol gives you LONG_MAX/_MIN on overflow.
+ * We use use saturating conversion to emulate strtol()'s
+ * behaviour.
+ */
+ return zend_dval_to_lval_cap(dval);
+ }
+ }
+ case IS_OBJECT:
+ {
+ zval dst;
+ if (Z_OBJ_HT_P(op)->cast_object(Z_OBJ_P(op), &dst, IS_LONG) == FAILURE
+ || EG(exception)) {
+ *failed = 1;
+ return 0;
+ }
+ ZEND_ASSERT(Z_TYPE(dst) == IS_LONG);
+ return Z_LVAL(dst);
+ }
+ case IS_RESOURCE:
+ case IS_ARRAY:
+ *failed = 1;
+ return 0;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+}
+/* }}} */
+
#define ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode) \
if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT) \
&& UNEXPECTED(Z_OBJ_HANDLER_P(op1, do_operation))) { \
@@ -307,9 +357,10 @@ static zend_always_inline int zendi_try_convert_scalar_to_number(zval *op, zval
return SUCCESS; \
}
-#define convert_op1_op2_long(op1, op1_lval, op2, op2_lval, result, op) \
+#define convert_op1_op2_long(op1, op1_lval, op2, op2_lval, result, opcode, sigil) \
do { \
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) { \
+ zend_bool failed; \
if (Z_ISREF_P(op1)) { \
op1 = Z_REFVAL_P(op1); \
if (Z_TYPE_P(op1) == IS_LONG) { \
@@ -317,9 +368,10 @@ static zend_always_inline int zendi_try_convert_scalar_to_number(zval *op, zval
break; \
} \
} \
- ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(op); \
- op1_lval = _zval_get_long_func_noisy(op1); \
- if (UNEXPECTED(EG(exception))) { \
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode); \
+ op1_lval = zendi_try_get_long(op1, &failed); \
+ if (UNEXPECTED(failed)) { \
+ zend_binop_error(sigil, op1, op2); \
if (result != op1) { \
ZVAL_UNDEF(result); \
} \
@@ -331,6 +383,7 @@ static zend_always_inline int zendi_try_convert_scalar_to_number(zval *op, zval
} while (0); \
do { \
if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) { \
+ zend_bool failed; \
if (Z_ISREF_P(op2)) { \
op2 = Z_REFVAL_P(op2); \
if (Z_TYPE_P(op2) == IS_LONG) { \
@@ -338,9 +391,10 @@ static zend_always_inline int zendi_try_convert_scalar_to_number(zval *op, zval
break; \
} \
} \
- ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(op); \
- op2_lval = _zval_get_long_func_noisy(op2); \
- if (UNEXPECTED(EG(exception))) { \
+ ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(opcode); \
+ op2_lval = zendi_try_get_long(op2, &failed); \
+ if (UNEXPECTED(failed)) { \
+ zend_binop_error(sigil, op1, op2); \
if (result != op1) { \
ZVAL_UNDEF(result); \
} \
@@ -843,12 +897,6 @@ ZEND_API zend_long ZEND_FASTCALL zval_get_long_func(zval *op) /* {{{ */
}
/* }}} */
-static zend_long ZEND_FASTCALL _zval_get_long_func_noisy(zval *op) /* {{{ */
-{
- return _zval_get_long_func_ex(op, 0);
-}
-/* }}} */
-
ZEND_API double ZEND_FASTCALL zval_get_double_func(zval *op) /* {{{ */
{
try_again:
@@ -1343,7 +1391,7 @@ ZEND_API int ZEND_FASTCALL mod_function(zval *result, zval *op1, zval *op2) /* {
{
zend_long op1_lval, op2_lval;
- convert_op1_op2_long(op1, op1_lval, op2, op2_lval, result, ZEND_MOD);
+ convert_op1_op2_long(op1, op1_lval, op2, op2_lval, result, ZEND_MOD, "%");
if (op2_lval == 0) {
/* modulus by zero */
@@ -1482,7 +1530,8 @@ try_again:
if (result != op1) {
ZVAL_UNDEF(result);
}
- zend_throw_error(NULL, "Unsupported operand types");
+ zend_type_error("Cannot perform bitwise not on %s",
+ zend_get_type_by_const(Z_TYPE_P(op1)));
return FAILURE;
}
}
@@ -1534,9 +1583,11 @@ ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op
}
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
+ zend_bool failed;
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_OR);
- op1_lval = _zval_get_long_func_noisy(op1);
- if (UNEXPECTED(EG(exception))) {
+ op1_lval = zendi_try_get_long(op1, &failed);
+ if (UNEXPECTED(failed)) {
+ zend_binop_error("|", op1, op2);
if (result != op1) {
ZVAL_UNDEF(result);
}
@@ -1546,9 +1597,11 @@ ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op
op1_lval = Z_LVAL_P(op1);
}
if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
+ zend_bool failed;
ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_OR);
- op2_lval = _zval_get_long_func_noisy(op2);
- if (UNEXPECTED(EG(exception))) {
+ op2_lval = zendi_try_get_long(op2, &failed);
+ if (UNEXPECTED(failed)) {
+ zend_binop_error("|", op1, op2);
if (result != op1) {
ZVAL_UNDEF(result);
}
@@ -1612,9 +1665,11 @@ ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *o
}
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
+ zend_bool failed;
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_AND);
- op1_lval = _zval_get_long_func_noisy(op1);
- if (UNEXPECTED(EG(exception))) {
+ op1_lval = zendi_try_get_long(op1, &failed);
+ if (UNEXPECTED(failed)) {
+ zend_binop_error("&", op1, op2);
if (result != op1) {
ZVAL_UNDEF(result);
}
@@ -1624,9 +1679,11 @@ ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *o
op1_lval = Z_LVAL_P(op1);
}
if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
+ zend_bool failed;
ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_AND);
- op2_lval = _zval_get_long_func_noisy(op2);
- if (UNEXPECTED(EG(exception))) {
+ op2_lval = zendi_try_get_long(op2, &failed);
+ if (UNEXPECTED(failed)) {
+ zend_binop_error("&", op1, op2);
if (result != op1) {
ZVAL_UNDEF(result);
}
@@ -1690,9 +1747,11 @@ ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *o
}
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
+ zend_bool failed;
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_XOR);
- op1_lval = _zval_get_long_func_noisy(op1);
- if (UNEXPECTED(EG(exception))) {
+ op1_lval = zendi_try_get_long(op1, &failed);
+ if (UNEXPECTED(failed)) {
+ zend_binop_error("^", op1, op2);
if (result != op1) {
ZVAL_UNDEF(result);
}
@@ -1702,9 +1761,11 @@ ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *o
op1_lval = Z_LVAL_P(op1);
}
if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
+ zend_bool failed;
ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_XOR);
- op2_lval = _zval_get_long_func_noisy(op2);
- if (UNEXPECTED(EG(exception))) {
+ op2_lval = zendi_try_get_long(op2, &failed);
+ if (UNEXPECTED(failed)) {
+ zend_binop_error("^", op1, op2);
if (result != op1) {
ZVAL_UNDEF(result);
}
@@ -1726,7 +1787,7 @@ ZEND_API int ZEND_FASTCALL shift_left_function(zval *result, zval *op1, zval *op
{
zend_long op1_lval, op2_lval;
- convert_op1_op2_long(op1, op1_lval, op2, op2_lval, result, ZEND_SL);
+ convert_op1_op2_long(op1, op1_lval, op2, op2_lval, result, ZEND_SL, "<<");
/* prevent wrapping quirkiness on some processors where << 64 + x == << x */
if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
@@ -1763,7 +1824,7 @@ ZEND_API int ZEND_FASTCALL shift_right_function(zval *result, zval *op1, zval *o
{
zend_long op1_lval, op2_lval;
- convert_op1_op2_long(op1, op1_lval, op2, op2_lval, result, ZEND_SR);
+ convert_op1_op2_long(op1, op1_lval, op2, op2_lval, result, ZEND_SR, ">>");
/* prevent wrapping quirkiness on some processors where >> 64 + x == >> x */
if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
@@ -2359,22 +2420,27 @@ try_again:
}
}
break;
+ case IS_FALSE:
+ case IS_TRUE:
+ /* Do nothing. */
+ break;
+ case IS_REFERENCE:
+ op1 = Z_REFVAL_P(op1);
+ goto try_again;
case IS_OBJECT:
if (Z_OBJ_HANDLER_P(op1, do_operation)) {
zval op2;
- int res;
-
ZVAL_LONG(&op2, 1);
- res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_ADD, op1, op1, &op2);
-
- return res;
+ if (Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_ADD, op1, op1, &op2) == SUCCESS) {
+ return SUCCESS;
+ }
}
+ /* break missing intentionally */
+ case IS_RESOURCE:
+ case IS_ARRAY:
+ zend_type_error("Cannot increment %s", zend_get_type_by_const(Z_TYPE_P(op1)));
return FAILURE;
- case IS_REFERENCE:
- op1 = Z_REFVAL_P(op1);
- goto try_again;
- default:
- return FAILURE;
+ EMPTY_SWITCH_DEFAULT_CASE()
}
return SUCCESS;
}
@@ -2415,22 +2481,28 @@ try_again:
break;
}
break;
+ case IS_NULL:
+ case IS_FALSE:
+ case IS_TRUE:
+ /* Do nothing. */
+ break;
+ case IS_REFERENCE:
+ op1 = Z_REFVAL_P(op1);
+ goto try_again;
case IS_OBJECT:
if (Z_OBJ_HANDLER_P(op1, do_operation)) {
zval op2;
- int res;
-
ZVAL_LONG(&op2, 1);
- res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_SUB, op1, op1, &op2);
-
- return res;
+ if (Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_SUB, op1, op1, &op2) == SUCCESS) {
+ return SUCCESS;
+ }
}
+ /* break missing intentionally */
+ case IS_RESOURCE:
+ case IS_ARRAY:
+ zend_type_error("Cannot decrement %s", zend_get_type_by_const(Z_TYPE_P(op1)));
return FAILURE;
- case IS_REFERENCE:
- op1 = Z_REFVAL_P(op1);
- goto try_again;
- default:
- return FAILURE;
+ EMPTY_SWITCH_DEFAULT_CASE()
}
return SUCCESS;
diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c
index af8a3996de..d74904f84f 100644
--- a/ext/opcache/Optimizer/zend_inference.c
+++ b/ext/opcache/Optimizer/zend_inference.c
@@ -4354,8 +4354,8 @@ int zend_may_throw(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_
&& (t2 & MAY_BE_ANY) == MAY_BE_ARRAY) {
return 0;
}
- return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
- (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
+ return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) ||
+ (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
case ZEND_DIV:
case ZEND_MOD:
if (!OP2_HAS_RANGE() ||
@@ -4367,12 +4367,12 @@ int zend_may_throw(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_
case ZEND_SUB:
case ZEND_MUL:
case ZEND_POW:
- return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
- (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
+ return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) ||
+ (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
case ZEND_SL:
case ZEND_SR:
- return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
- (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
+ return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) ||
+ (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) ||
!OP2_HAS_RANGE() ||
OP2_MIN_RANGE() < 0;
case ZEND_CONCAT:
@@ -4386,15 +4386,16 @@ int zend_may_throw(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_
&& (t2 & MAY_BE_ANY) == MAY_BE_STRING) {
return 0;
}
- return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
- (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
+ return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) ||
+ (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
case ZEND_BW_NOT:
return (t1 & (MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
- case ZEND_BOOL_NOT:
case ZEND_PRE_INC:
case ZEND_POST_INC:
case ZEND_PRE_DEC:
case ZEND_POST_DEC:
+ return (t1 & (MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
+ case ZEND_BOOL_NOT:
case ZEND_JMPZ:
case ZEND_JMPNZ:
case ZEND_JMPZNZ:
@@ -4422,8 +4423,8 @@ int zend_may_throw(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_
&& (t2 & MAY_BE_ANY) == MAY_BE_ARRAY) {
return 0;
}
- return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
- (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
+ return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) ||
+ (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
} else if (opline->extended_value == ZEND_DIV ||
opline->extended_value == ZEND_MOD) {
if (!OP2_HAS_RANGE() ||
@@ -4431,17 +4432,17 @@ int zend_may_throw(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_
/* Division by zero */
return 1;
}
- return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
- (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
+ return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) ||
+ (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
} else if (opline->extended_value == ZEND_SUB ||
opline->extended_value == ZEND_MUL ||
opline->extended_value == ZEND_POW) {
- return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
- (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
+ return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) ||
+ (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
} else if (opline->extended_value == ZEND_SL ||
opline->extended_value == ZEND_SR) {
- return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
- (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
+ return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) ||
+ (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) ||
!OP2_HAS_RANGE() ||
OP2_MIN_RANGE() < 0;
} else if (opline->extended_value == ZEND_CONCAT) {
@@ -4454,8 +4455,8 @@ int zend_may_throw(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_
&& (t2 & MAY_BE_ANY) == MAY_BE_STRING) {
return 0;
}
- return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
- (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
+ return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) ||
+ (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
}
return 1;
case ZEND_ASSIGN:
diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c
index d357f72a2e..586823c52e 100644
--- a/ext/opcache/jit/zend_jit.c
+++ b/ext/opcache/jit/zend_jit.c
@@ -2212,7 +2212,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
op1_def_info, OP1_DEF_REG_ADDR(),
res_use_info, res_info,
res_addr,
- (op1_def_info & MAY_BE_LONG) && (op1_def_info & MAY_BE_DOUBLE) && zend_may_overflow(opline, op_array, ssa))) {
+ (op1_def_info & MAY_BE_LONG) && (op1_def_info & MAY_BE_DOUBLE) && zend_may_overflow(opline, op_array, ssa),
+ zend_may_throw(opline, ssa_op, op_array, ssa))) {
goto jit_failure;
}
goto done;
diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c
index a3a956cfbe..a9170811ee 100644
--- a/ext/opcache/jit/zend_jit_trace.c
+++ b/ext/opcache/jit/zend_jit_trace.c
@@ -2729,7 +2729,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
op1_def_info, OP1_DEF_REG_ADDR(),
res_use_info, res_info,
res_addr,
- (op1_def_info & MAY_BE_LONG) && (op1_def_info & (MAY_BE_DOUBLE|MAY_BE_GUARD)) && zend_may_overflow_ex(opline, ssa_op, op_array, ssa))) {
+ (op1_def_info & MAY_BE_LONG) && (op1_def_info & (MAY_BE_DOUBLE|MAY_BE_GUARD)) && zend_may_overflow_ex(opline, ssa_op, op_array, ssa),
+ zend_may_throw(opline, ssa_op, op_array, ssa))) {
goto jit_failure;
}
if ((op1_def_info & (MAY_BE_ANY|MAY_BE_GUARD)) == (MAY_BE_LONG|MAY_BE_GUARD)) {
diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index 11377f051e..c1cd2a6a91 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -3422,7 +3422,7 @@ static int zend_jit_update_regs(dasm_State **Dst, zend_jit_addr src, zend_jit_ad
return 1;
}
-static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op1_def_info, zend_jit_addr op1_def_addr, uint32_t res_use_info, uint32_t res_info, zend_jit_addr res_addr, int may_overflow)
+static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op1_def_info, zend_jit_addr op1_def_addr, uint32_t res_use_info, uint32_t res_info, zend_jit_addr res_addr, int may_overflow, int may_throw)
{
if (op1_info & ((MAY_BE_UNDEF|MAY_BE_ANY)-MAY_BE_LONG)) {
| IF_NOT_ZVAL_TYPE op1_addr, IS_LONG, >2
@@ -3562,6 +3562,9 @@ static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, const zend_
| EXT_CALL decrement_function, r0
}
}
+ if (may_throw) {
+ zend_jit_check_exception(Dst);
+ }
} else {
zend_reg tmp_reg;
diff --git a/ext/standard/tests/math/pow_variation1.phpt b/ext/standard/tests/math/pow_variation1.phpt
index fc2c9aa1a2..f205c18a83 100644
--- a/ext/standard/tests/math/pow_variation1.phpt
+++ b/ext/standard/tests/math/pow_variation1.phpt
@@ -174,9 +174,7 @@ Warning: A non-numeric value encountered in %s on line %d
int(0)
-- Iteration 23 --
-
-Notice: Object of class classA could not be converted to number in %s on line %d
-int(1)
+Unsupported operand types: object ** int
-- Iteration 24 --
int(0)
diff --git a/ext/standard/tests/math/pow_variation1_64bit.phpt b/ext/standard/tests/math/pow_variation1_64bit.phpt
index 75b9f576db..05cb9151ae 100644
--- a/ext/standard/tests/math/pow_variation1_64bit.phpt
+++ b/ext/standard/tests/math/pow_variation1_64bit.phpt
@@ -174,9 +174,7 @@ Warning: A non-numeric value encountered in %s on line %d
int(0)
-- Iteration 23 --
-
-Notice: Object of class classA could not be converted to number in %s on line %d
-int(1)
+Unsupported operand types: object ** int
-- Iteration 24 --
int(0)
diff --git a/ext/standard/tests/math/pow_variation2.phpt b/ext/standard/tests/math/pow_variation2.phpt
index 8af96ef8d6..5d106ed9d2 100644
--- a/ext/standard/tests/math/pow_variation2.phpt
+++ b/ext/standard/tests/math/pow_variation2.phpt
@@ -170,9 +170,7 @@ Warning: A non-numeric value encountered in %s on line %d
float(1)
-- Iteration 23 --
-
-Notice: Object of class classA could not be converted to number in %s on line %d
-float(20.3)
+Unsupported operand types: float ** object
-- Iteration 24 --
float(1)
diff --git a/scripts/dev/bless_tests.php b/scripts/dev/bless_tests.php
index b772f00cc1..8532e9386d 100755
--- a/scripts/dev/bless_tests.php
+++ b/scripts/dev/bless_tests.php
@@ -106,7 +106,8 @@ function generateMinimallyDifferingOutput(string $out, string $oldExpect) {
function insertOutput(string $phpt, string $out): string {
return preg_replace_callback('/--EXPECTF?--.*$/s', function($matches) use($out) {
- $F = strpos($out, '%') !== false ? 'F' : '';
+ $hasWildcard = preg_match('/%[resSaAwidxfc]/', $out);
+ $F = $hasWildcard ? 'F' : '';
return "--EXPECT$F--\n" . $out . "\n";
}, $phpt);
}