1
0
mirror of https://github.com/php/php-src.git synced 2026-04-30 03:33:17 +02:00
Files
archived-php-src/Zend/tests/compound_assign_failure.phpt
T
Nikita Popov f182309e87 Refactor operator implementations
Instead of looping, use straight-line code with the following
layout:

1. Try to apply the base operation on the dereferenced operands.
2. Try overloaded object operations.
3. Try to convert operands to number, else error out.
4. Apply the base operation on the converted operands.

This makes the code easier to reason about and fixes some edge-case
bugs:

1. We should only try invoking operator overloading once prior to
   type conversion. Previously it was invoked both before and after
   type conversion.
2. We should not modify any values if an exception is thrown.
   Previously we sometimes modified the LHS of a compound assignment
   operator.
3. If conversion of the first operand fails, we no longer try to
   convert the second operand. I think the previous behavior here
   was fine as well, but this still seems a more typical.

This will also make some followup changes I have in mind simpler.
2020-03-31 20:49:39 +02:00

252 lines
3.6 KiB
PHP

--TEST--
Behavior of failing compound assignment
--INI--
opcache.optimization_level=0
--FILE--
<?php
try {
$a = 1;
$a %= 0;
} catch (Error $e) { var_dump($a); }
try {
$a = 1;
$a >>= -1;
} catch (Error $e) { var_dump($a); }
try {
$a = 1;
$a <<= -1;
} catch (Error $e) { var_dump($a); }
set_error_handler(function($type, $msg) { throw new Exception($msg); });
try {
$a = [];
$a .= "foo";
} catch (Throwable $e) { var_dump($a); }
try {
$a = "foo";
$a .= [];
} catch (Throwable $e) { var_dump($a); }
$x = new stdClass;
try { $x += 1; }
catch (Exception $e) {}
var_dump($x);
$x = 1;
try { $x += new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = "foo";
try { $x += new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = new stdClass;
try { $x -= 1; }
catch (Exception $e) {}
var_dump($x);
$x = 1;
try { $x -= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = "foo";
try { $x -= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = new stdClass;
try { $x *= 1; }
catch (Exception $e) {}
var_dump($x);
$x = 1;
try { $x *= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = "foo";
try { $x *= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = new stdClass;
try { $x /= 1; }
catch (Exception $e) {}
var_dump($x);
$x = 1;
try { $x /= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = "foo";
try { $x /= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = new stdClass;
try { $x %= 1; }
catch (Exception $e) {}
var_dump($x);
$x = 1;
try { $x %= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = "foo";
try { $x %= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = new stdClass;
try { $x **= 1; }
catch (Exception $e) {}
var_dump($x);
$x = 1;
try { $x **= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = "foo";
try { $x **= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = new stdClass;
try { $x ^= 1; }
catch (Exception $e) {}
var_dump($x);
$x = 1;
try { $x ^= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = "foo";
try { $x ^= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = new stdClass;
try { $x &= 1; }
catch (Exception $e) {}
var_dump($x);
$x = 1;
try { $x &= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = "foo";
try { $x &= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = new stdClass;
try { $x |= 1; }
catch (Exception $e) {}
var_dump($x);
$x = 1;
try { $x |= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = "foo";
try { $x |= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = new stdClass;
try { $x <<= 1; }
catch (Exception $e) {}
var_dump($x);
$x = 1;
try { $x <<= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = "foo";
try { $x <<= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = new stdClass;
try { $x >>= 1; }
catch (Exception $e) {}
var_dump($x);
$x = 1;
try { $x >>= new stdClass; }
catch (Exception $e) {}
var_dump($x);
$x = "foo";
try { $x >>= new stdClass; }
catch (Exception $e) {}
var_dump($x);
?>
--EXPECTF--
int(1)
int(1)
int(1)
array(0) {
}
string(3) "foo"
object(stdClass)#%d (0) {
}
int(1)
string(3) "foo"
object(stdClass)#%d (0) {
}
int(1)
string(3) "foo"
object(stdClass)#%d (0) {
}
int(1)
string(3) "foo"
object(stdClass)#%d (0) {
}
int(1)
string(3) "foo"
object(stdClass)#%d (0) {
}
int(1)
string(3) "foo"
object(stdClass)#%d (0) {
}
int(1)
string(3) "foo"
object(stdClass)#%d (0) {
}
int(1)
string(3) "foo"
object(stdClass)#%d (0) {
}
int(1)
string(3) "foo"
object(stdClass)#%d (0) {
}
int(1)
string(3) "foo"
object(stdClass)#%d (0) {
}
int(1)
string(3) "foo"
object(stdClass)#%d (0) {
}
int(1)
string(3) "foo"