Skip to content

Commit 5bc1e22

Browse files
committed
Make numeric operations on resources, arrays and objects type errors
RFC: https://wiki.php.net/rfc/arithmetic_operator_type_checks Closes GH-5331.
1 parent 31fb6a0 commit 5bc1e22

24 files changed

+1816
-187
lines changed

UPGRADING

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,14 @@ PHP 8.0 UPGRADE NOTES
181181
. Disabled functions are now treated exactly like non-existent functions.
182182
Calling a disabled function will report it as unknown, and redefining a
183183
disabled function is now possible.
184-
. data: wrappers are no longer writable, what matches the documented behavior.
184+
. data: stream wrappers are no longer writable, which matches the documented
185+
behavior.
186+
. The arithmetic and bitwise operators
187+
+, -, *, /, **, %, <<, >>, &, |, ^, ~, ++, --
188+
will now consistently throw a TypeError when one of the operands is an
189+
array, resource or non-overloaded object. The only exception to this is the
190+
array + array merge operation, which remains supported.
191+
RFC: https://wiki.php.net/rfc/arithmetic_operator_type_checks
185192

186193
- COM:
187194
. Removed the ability to import case-insensitive constants from type

Zend/tests/add_003.phpt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,8 @@ var_dump($c);
2020
echo "Done\n";
2121
?>
2222
--EXPECTF--
23-
Notice: Object of class stdClass could not be converted to number in %sadd_003.php on line %d
24-
2523
Exception: Unsupported operand types: object + array
2624

27-
Notice: Object of class stdClass could not be converted to number in %s on line %d
28-
2925
Fatal error: Uncaught TypeError: Unsupported operand types: object + array in %s:%d
3026
Stack trace:
3127
#0 {main}

Zend/tests/bug54305.phpt

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,11 @@ class TestClass {
99
abstract class AbstractClass {
1010
}
1111
$methodWithArgs = new ReflectionMethod('TestClass', 'methodWithArgs');
12-
echo $methodWithArgs++;
13-
?>
14-
--EXPECTF--
15-
Method [ <user> public method methodWithArgs ] {
16-
@@ %sbug54305.php %d - %d
17-
18-
- Parameters [2] {
19-
Parameter #0 [ <required> $a ]
20-
Parameter #1 [ <required> $b ]
21-
}
12+
try {
13+
echo $methodWithArgs++;
14+
} catch (TypeError $e) {
15+
echo $e->getMessage(), "\n";
2216
}
17+
?>
18+
--EXPECT--
19+
Cannot increment object

Zend/tests/bug73337.phpt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,5 @@ Bug #73337 (try/catch not working with two exceptions inside a same operation)
55
class d { function __destruct() { throw new Exception; } }
66
try { new d + new d; } catch (Exception $e) { print "Exception properly caught\n"; }
77
?>
8-
--EXPECTF--
9-
Notice: Object of class d could not be converted to number in %sbug73337.php on line 3
10-
11-
Notice: Object of class d could not be converted to number in %sbug73337.php on line 3
8+
--EXPECT--
129
Exception properly caught

Zend/tests/compound_assign_failure.phpt

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -34,167 +34,167 @@ try {
3434

3535
$x = new stdClass;
3636
try { $x += 1; }
37-
catch (Exception $e) {}
37+
catch (Throwable $e) {}
3838
var_dump($x);
3939

4040
$x = 1;
4141
try { $x += new stdClass; }
42-
catch (Exception $e) {}
42+
catch (Throwable $e) {}
4343
var_dump($x);
4444

4545
$x = "foo";
4646
try { $x += new stdClass; }
47-
catch (Exception $e) {}
47+
catch (Throwable $e) {}
4848
var_dump($x);
4949

5050
$x = new stdClass;
5151
try { $x -= 1; }
52-
catch (Exception $e) {}
52+
catch (Throwable $e) {}
5353
var_dump($x);
5454

5555
$x = 1;
5656
try { $x -= new stdClass; }
57-
catch (Exception $e) {}
57+
catch (Throwable $e) {}
5858
var_dump($x);
5959

6060
$x = "foo";
6161
try { $x -= new stdClass; }
62-
catch (Exception $e) {}
62+
catch (Throwable $e) {}
6363
var_dump($x);
6464

6565
$x = new stdClass;
6666
try { $x *= 1; }
67-
catch (Exception $e) {}
67+
catch (Throwable $e) {}
6868
var_dump($x);
6969

7070
$x = 1;
7171
try { $x *= new stdClass; }
72-
catch (Exception $e) {}
72+
catch (Throwable $e) {}
7373
var_dump($x);
7474

7575
$x = "foo";
7676
try { $x *= new stdClass; }
77-
catch (Exception $e) {}
77+
catch (Throwable $e) {}
7878
var_dump($x);
7979

8080
$x = new stdClass;
8181
try { $x /= 1; }
82-
catch (Exception $e) {}
82+
catch (Throwable $e) {}
8383
var_dump($x);
8484

8585
$x = 1;
8686
try { $x /= new stdClass; }
87-
catch (Exception $e) {}
87+
catch (Throwable $e) {}
8888
var_dump($x);
8989

9090
$x = "foo";
9191
try { $x /= new stdClass; }
92-
catch (Exception $e) {}
92+
catch (Throwable $e) {}
9393
var_dump($x);
9494

9595
$x = new stdClass;
9696
try { $x %= 1; }
97-
catch (Exception $e) {}
97+
catch (Throwable $e) {}
9898
var_dump($x);
9999

100100
$x = 1;
101101
try { $x %= new stdClass; }
102-
catch (Exception $e) {}
102+
catch (Throwable $e) {}
103103
var_dump($x);
104104

105105
$x = "foo";
106106
try { $x %= new stdClass; }
107-
catch (Exception $e) {}
107+
catch (Throwable $e) {}
108108
var_dump($x);
109109

110110
$x = new stdClass;
111111
try { $x **= 1; }
112-
catch (Exception $e) {}
112+
catch (Throwable $e) {}
113113
var_dump($x);
114114

115115
$x = 1;
116116
try { $x **= new stdClass; }
117-
catch (Exception $e) {}
117+
catch (Throwable $e) {}
118118
var_dump($x);
119119

120120
$x = "foo";
121121
try { $x **= new stdClass; }
122-
catch (Exception $e) {}
122+
catch (Throwable $e) {}
123123
var_dump($x);
124124

125125
$x = new stdClass;
126126
try { $x ^= 1; }
127-
catch (Exception $e) {}
127+
catch (Throwable $e) {}
128128
var_dump($x);
129129

130130
$x = 1;
131131
try { $x ^= new stdClass; }
132-
catch (Exception $e) {}
132+
catch (Throwable $e) {}
133133
var_dump($x);
134134

135135
$x = "foo";
136136
try { $x ^= new stdClass; }
137-
catch (Exception $e) {}
137+
catch (Throwable $e) {}
138138
var_dump($x);
139139

140140
$x = new stdClass;
141141
try { $x &= 1; }
142-
catch (Exception $e) {}
142+
catch (Throwable $e) {}
143143
var_dump($x);
144144

145145
$x = 1;
146146
try { $x &= new stdClass; }
147-
catch (Exception $e) {}
147+
catch (Throwable $e) {}
148148
var_dump($x);
149149

150150
$x = "foo";
151151
try { $x &= new stdClass; }
152-
catch (Exception $e) {}
152+
catch (Throwable $e) {}
153153
var_dump($x);
154154

155155
$x = new stdClass;
156156
try { $x |= 1; }
157-
catch (Exception $e) {}
157+
catch (Throwable $e) {}
158158
var_dump($x);
159159

160160
$x = 1;
161161
try { $x |= new stdClass; }
162-
catch (Exception $e) {}
162+
catch (Throwable $e) {}
163163
var_dump($x);
164164

165165
$x = "foo";
166166
try { $x |= new stdClass; }
167-
catch (Exception $e) {}
167+
catch (Throwable $e) {}
168168
var_dump($x);
169169

170170
$x = new stdClass;
171171
try { $x <<= 1; }
172-
catch (Exception $e) {}
172+
catch (Throwable $e) {}
173173
var_dump($x);
174174

175175
$x = 1;
176176
try { $x <<= new stdClass; }
177-
catch (Exception $e) {}
177+
catch (Throwable $e) {}
178178
var_dump($x);
179179

180180
$x = "foo";
181181
try { $x <<= new stdClass; }
182-
catch (Exception $e) {}
182+
catch (Throwable $e) {}
183183
var_dump($x);
184184

185185
$x = new stdClass;
186186
try { $x >>= 1; }
187-
catch (Exception $e) {}
187+
catch (Throwable $e) {}
188188
var_dump($x);
189189

190190
$x = 1;
191191
try { $x >>= new stdClass; }
192-
catch (Exception $e) {}
192+
catch (Throwable $e) {}
193193
var_dump($x);
194194

195195
$x = "foo";
196196
try { $x >>= new stdClass; }
197-
catch (Exception $e) {}
197+
catch (Throwable $e) {}
198198
var_dump($x);
199199

200200
?>

Zend/tests/decrement_001.phpt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,18 @@ $a = array(
2626
);
2727

2828
foreach ($a as $var) {
29-
$var--;
29+
try {
30+
$var--;
31+
} catch (TypeError $e) {
32+
echo $e->getMessage(), "\n";
33+
}
3034
var_dump($var);
3135
}
3236

3337
echo "Done\n";
3438
?>
3539
--EXPECTF--
40+
Cannot decrement array
3641
array(3) {
3742
[0]=>
3843
int(1)
@@ -51,8 +56,10 @@ float(1.5)
5156
NULL
5257
bool(true)
5358
bool(false)
59+
Cannot decrement object
5460
object(stdClass)#%d (0) {
5561
}
62+
Cannot decrement array
5663
array(0) {
5764
}
5865
float(-2147483649)

Zend/tests/decrement_001_64bit.phpt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,18 @@ $a = array(
2626
);
2727

2828
foreach ($a as $var) {
29-
$var--;
29+
try {
30+
$var--;
31+
} catch (TypeError $e) {
32+
echo $e->getMessage(), "\n";
33+
}
3034
var_dump($var);
3135
}
3236

3337
echo "Done\n";
3438
?>
35-
--EXPECTF--
39+
--EXPECT--
40+
Cannot decrement array
3641
array(3) {
3742
[0]=>
3843
int(1)
@@ -51,8 +56,10 @@ float(1.5)
5156
NULL
5257
bool(true)
5358
bool(false)
54-
object(stdClass)#%d (0) {
59+
Cannot decrement object
60+
object(stdClass)#1 (0) {
5561
}
62+
Cannot decrement array
5663
array(0) {
5764
}
5865
float(-9.223372036854776E+18)

0 commit comments

Comments
 (0)