Skip to content

Commit 6acbffb

Browse files
committed
Fixed crash when invoking trampoline functions with default.
Added many more test cases for default expressions.
1 parent f0bdbfd commit 6acbffb

File tree

4 files changed

+141
-3
lines changed

4 files changed

+141
-3
lines changed

Zend/tests/default_expression/default_expressions.phpt

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Tests an exhaustive list of valid expressions containing the default keyword
55

66
function F($V = 2) { return $V; }
77

8+
echo "Numeric binary operators (LHS)\n";
89
var_dump(F(default + 1));
910
var_dump(F(default - 1));
1011
var_dump(F(default * 2));
@@ -16,7 +17,9 @@ var_dump(F(default ^ 2));
1617
var_dump(F(default << 1));
1718
var_dump(F(default >> 1));
1819
var_dump(F(default ** 2));
19-
echo PHP_EOL;
20+
var_dump(F(default <=> 2));
21+
22+
echo "\nNumeric binary operators (RHS)\n";
2023
var_dump(F(1 + default));
2124
var_dump(F(1 - default));
2225
var_dump(F(2 * default));
@@ -28,8 +31,65 @@ var_dump(F(2 ^ default));
2831
var_dump(F(1 << default));
2932
var_dump(F(1 >> default));
3033
var_dump(F(2 ** default));
34+
var_dump(F(2 <=> default));
35+
36+
echo "\nBoolean binary operators\n";
37+
var_dump(F(default === 2));
38+
var_dump(F(default !== 2));
39+
var_dump(F(default == '2'));
40+
var_dump(F(default != '2'));
41+
var_dump(F(default >= 1));
42+
var_dump(F(default <= 1));
43+
var_dump(F(default > 1));
44+
var_dump(F(default < 1));
45+
var_dump(F(default && 0));
46+
var_dump(F(default || 0));
47+
var_dump(F(default and 0));
48+
var_dump(F(default or 0));
49+
var_dump(F(default xor 0));
50+
51+
echo "\nUnary operators\n";
52+
var_dump(F(+default));
53+
var_dump(F(-default));
54+
var_dump(F(!default));
55+
var_dump(F(~default));
56+
57+
echo "\nConditional expressions\n";
58+
var_dump(F(default ? 1 : 0));
59+
var_dump(F(1 ? default : 0));
60+
var_dump(F(1 ? 1 : default));
61+
var_dump(F(default ?: 0));
62+
var_dump(F(0 ?: default));
63+
var_dump(F(default ?? 0));
64+
var_dump(F(null ?? default));
65+
66+
echo "\nCasts\n";
67+
var_dump(F((int)default));
68+
var_dump(F((double)default));
69+
var_dump(F((string)default));
70+
var_dump(F((array)default));
71+
var_dump(F((object)default));
72+
var_dump(F((bool)default));
73+
74+
echo "\nInternal functions\n";
75+
var_dump(F(empty(default)));
76+
// eval() makes no sense.
77+
// exit() makes no sense.
78+
// TODO?
79+
// include()
80+
// include_once()
81+
// require()
82+
// require_once()
83+
84+
echo "\nMatch tier\n";
85+
var_dump(F(match(default) { default => default }));
86+
var_dump(F(match(default) { 2 => 3 }));
87+
88+
echo "\nPrint tier\n";
89+
var_dump(F(print default));
3190
?>
3291
--EXPECT--
92+
Numeric binary operators (LHS)
3393
int(3)
3494
int(1)
3595
int(4)
@@ -41,7 +101,9 @@ int(0)
41101
int(4)
42102
int(1)
43103
int(4)
104+
int(0)
44105

106+
Numeric binary operators (RHS)
45107
int(3)
46108
int(-1)
47109
int(4)
@@ -53,3 +115,58 @@ int(0)
53115
int(4)
54116
int(0)
55117
int(4)
118+
int(0)
119+
120+
Boolean binary operators
121+
bool(true)
122+
bool(false)
123+
bool(true)
124+
bool(false)
125+
bool(true)
126+
bool(false)
127+
bool(true)
128+
bool(false)
129+
bool(false)
130+
bool(true)
131+
bool(false)
132+
bool(true)
133+
bool(true)
134+
135+
Unary operators
136+
int(2)
137+
int(-2)
138+
bool(false)
139+
int(-3)
140+
141+
Conditional expressions
142+
int(1)
143+
int(2)
144+
int(1)
145+
int(2)
146+
int(2)
147+
int(2)
148+
int(2)
149+
150+
Casts
151+
int(2)
152+
float(2)
153+
string(1) "2"
154+
array(1) {
155+
[0]=>
156+
int(2)
157+
}
158+
object(stdClass)#1 (1) {
159+
["scalar"]=>
160+
int(2)
161+
}
162+
bool(true)
163+
164+
Internal functions
165+
bool(false)
166+
167+
Match tier
168+
int(2)
169+
int(3)
170+
171+
Print tier
172+
2int(1)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Tests passing default to a trampoline function
3+
--FILE--
4+
<?php
5+
6+
(fn ($P = 1) => $P)->__invoke(default);
7+
?>
8+
--EXPECTF--
9+
Fatal error: Uncaught Exception: Unable to fetch default value in %s:%d
10+
Stack trace:
11+
%a

Zend/zend_vm_def.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9838,7 +9838,12 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_DEFAULT_ARG, UNUSED|NUM, UNUSED)
98389838
param.arg_info = &called_func->common.arg_info[param.offset];
98399839

98409840
zval default_value;
9841-
reflection_get_parameter_default(&default_value, &param);
9841+
if (reflection_get_parameter_default(&default_value, &param) == FAILURE) {
9842+
if (!EG(exception)) {
9843+
zend_throw_exception(NULL, "Unable to fetch default value", 0);
9844+
}
9845+
HANDLE_EXCEPTION();
9846+
}
98429847

98439848
// Evaluate AST value, e.g. new class.
98449849
if (Z_TYPE(default_value) == IS_CONSTANT_AST

Zend/zend_vm_execute.h

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)