]> granicus.if.org Git - php/commitdiff
Make numeric operations on resources, arrays and objects type errors
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 1 Apr 2020 08:25:22 +0000 (10:25 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 5 May 2020 14:11:13 +0000 (16:11 +0200)
RFC: https://wiki.php.net/rfc/arithmetic_operator_type_checks

Closes GH-5331.

24 files changed:
UPGRADING
Zend/tests/add_003.phpt
Zend/tests/bug54305.phpt
Zend/tests/bug73337.phpt
Zend/tests/compound_assign_failure.phpt
Zend/tests/decrement_001.phpt
Zend/tests/decrement_001_64bit.phpt
Zend/tests/gc_038.phpt
Zend/tests/increment_001.phpt
Zend/tests/mod_001.phpt
Zend/tests/not_002.phpt
Zend/tests/operator_unsupported_types.phpt [new file with mode: 0644]
Zend/tests/throw/001.phpt
Zend/tests/xor_001.phpt
Zend/zend_compile.c
Zend/zend_operators.c
ext/opcache/Optimizer/zend_inference.c
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_x86.dasc
ext/standard/tests/math/pow_variation1.phpt
ext/standard/tests/math/pow_variation1_64bit.phpt
ext/standard/tests/math/pow_variation2.phpt
scripts/dev/bless_tests.php

index 233f78fdae7ccfd879d27b9edaa38db1b69e5acd..1066d016ff63ebf66a5d1e692f2b64a029330736 100644 (file)
--- 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
index 0f03f550e02827eab09842a68a229598c0cbeb65..69edb7cb1ec0e04c12a06aefc6c98f277b136209 100644 (file)
@@ -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}
index 8e85d2be58ec101cec082c4854ec780e01afe66b..a443d480ec569a4c62838a8d4598dfc517145c62 100644 (file)
@@ -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
index 53ce963c529fa981124b98436c54fdd08b4ca52d..a338aa605c7814c36a079a790cff3240f9a65391 100644 (file)
@@ -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
index 1780725d93dcece49b88050a400ecb98810d8a5b..0dc9af85f253080865da69bc6574e43e24276c3e 100644 (file)
@@ -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);
 
 ?>
index 22d95b16ac6678bcfac53abe8b8ab661ef0a2ec6..5983c4eaa185bcc98b8c1e6eb34704888d77beb3 100644 (file)
@@ -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)
index 2b2100932a3c195bfe2795c36bc5ecfecb9a7a84..a96d8cbd0712f5cb5aae2459994a910bddd30f4f 100644 (file)
@@ -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)
index d3219531d61526797cd24ca0888735c5d7e7071d..91f22bf154b30f4ff4595bc185ef53abc5d3e2bd 100644 (file)
@@ -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
index 92f32bb657a2d43afd51f6337e817ffbe84fcda8..a834c5c51d5451f1123467dc553ac51545bf34aa 100644 (file)
@@ -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)
index a393a4364486a196f38a5d93280efbb190fed396..5c543a26192c23781f3206f6c867d4c48c01a06b 100644 (file)
@@ -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
index 38691a1a510ea9b38c33a408bde129e8d7656a01..3282053b6b9d0b74b0c25781e50cd92de0a9ceeb 100644 (file)
@@ -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 (file)
index 0000000..9004897
--- /dev/null
@@ -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
index 072d9f45b54e10d1fe8d06fec5793ce093537050..deb8743ab5667ff98cfbc38d73bdd73cc4ddedaf 100644 (file)
@@ -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();"
index 1a6d0fb6333c351c297eaae5f39e98a7088fd7dd..9678af16b5f717fed763a544ecdeb5003c67445b 100644 (file)
@@ -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
index bc214fa39aa6bb7dd813477c3c293791e9b07525..8e620b277915ee44edcf25b5cccf93a770ee9870 100644 (file)
@@ -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,
index 7737667940cca806a0ba09aa047015d4260eb00c..012e95d3b2593f9be0d6237015dcb469a1469e33 100644 (file)
@@ -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;
index af8a3996de2d3ccca314160c1acced52724a8f8b..d74904f84fa7fe370e318d7de198e9465a9b3d22 100644 (file)
@@ -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:
index d357f72a2e769a7ed5fec489f4681eb089fb762f..586823c52eec25790e6065c1ec7f94e724890075 100644 (file)
@@ -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;
index a3a956cfbed416c4f4caaed781c45a7d3c25e51a..a9170811ee9aa2447764c7fc7bb7efff6a9a47fa 100644 (file)
@@ -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)) {
index 11377f051e2a4045ae83ee08be6df7fd09d01165..c1cd2a6a914ccaca8e305d823ab3b9c9d62f66a2 100644 (file)
@@ -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;
 
index fc2c9aa1a23c0c9a66ef8d6598cfe010536fd8ac..f205c18a8364aacb2a3d54453f44d01e02c66f08 100644 (file)
@@ -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)
index 75b9f576db6526c466e11a80c4e794c82786efa9..05cb9151ae1f70bd5443ad1e24dfe355128441b5 100644 (file)
@@ -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)
index 8af96ef8d6d09df565a06d7faebf4cdb9025b43c..5d106ed9d2e7b979f5f351500cfaf7795cec4d2c 100644 (file)
@@ -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)
index b772f00cc1964b073f0a9a9ef9c4af5a6142e3a6..8532e9386d21096543ac407d2fa7ab1bbbd963a8 100755 (executable)
@@ -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);
 }