Skip to content

Commit 04ccf4c

Browse files
committed
Fixed match allowing multiple default conditions.
1 parent f401390 commit 04ccf4c

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Tests default as an expression in a match condition is not treated as a default match arm
3+
--FILE--
4+
<?php
5+
6+
$F = fn ($V = 1) => $V;
7+
var_dump($F(
8+
match (default) {
9+
default + 1 => 2,
10+
default => default,
11+
}
12+
));
13+
?>
14+
--EXPECT--
15+
int(1)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Tests declaring multiple default match arms is still prohibited in an argument context
3+
--FILE--
4+
<?php
5+
6+
function F($V = 1) {}
7+
F(
8+
match (0) {
9+
0,
10+
default => 1,
11+
default => 2,
12+
}
13+
);
14+
?>
15+
--EXPECTF--
16+
Fatal error: Match expressions may only contain one default arm in %s on line %d

Zend/zend_compile.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6375,6 +6375,18 @@ static void zend_compile_switch(zend_ast *ast) /* {{{ */
63756375
}
63766376
/* }}} */
63776377

6378+
static bool do_match_conditions_contain_default(zend_ast_list *conditions)
6379+
{
6380+
for (uint32_t i = 0; i < conditions->children; ++i) {
6381+
// Default as an expression is still allowed, so we don't need to recurse sub-lists.
6382+
if (conditions->child[i]->kind == ZEND_AST_DEFAULT) {
6383+
return true;
6384+
}
6385+
}
6386+
6387+
return false;
6388+
}
6389+
63786390
static uint32_t count_match_conds(zend_ast_list *arms)
63796391
{
63806392
uint32_t num_conds = 0;
@@ -6383,7 +6395,7 @@ static uint32_t count_match_conds(zend_ast_list *arms)
63836395
zend_ast *arm_ast = arms->child[i];
63846396
zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]);
63856397

6386-
if (conds->child[0]->kind == ZEND_AST_DEFAULT) {
6398+
if (do_match_conditions_contain_default(conds)) {
63876399
continue;
63886400
}
63896401

@@ -6398,7 +6410,7 @@ static bool can_match_use_jumptable(zend_ast_list *arms) {
63986410
zend_ast *arm_ast = arms->child[i];
63996411
zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]);
64006412

6401-
if (conds->child[0]->kind == ZEND_AST_DEFAULT) {
6413+
if (do_match_conditions_contain_default(conds)) {
64026414
/* Skip default arm */
64036415
continue;
64046416
}
@@ -6445,7 +6457,7 @@ static void zend_compile_match(znode *result, zend_ast *ast)
64456457
zend_ast *arm_ast = arms->child[i];
64466458
zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]);
64476459

6448-
if (conds->child[0]->kind == ZEND_AST_DEFAULT) {
6460+
if (do_match_conditions_contain_default(conds)) {
64496461
if (has_default_arm) {
64506462
CG(zend_lineno) = arm_ast->lineno;
64516463
zend_error_noreturn(E_COMPILE_ERROR,
@@ -6478,7 +6490,7 @@ static void zend_compile_match(znode *result, zend_ast *ast)
64786490
for (uint32_t j = 0; j < conds->children; j++) {
64796491
zend_ast *cond_ast = conds->child[j];
64806492

6481-
if (conds->child[0]->kind == ZEND_AST_DEFAULT) {
6493+
if (do_match_conditions_contain_default(conds)) {
64826494
break;
64836495
}
64846496

@@ -6535,7 +6547,7 @@ static void zend_compile_match(znode *result, zend_ast *ast)
65356547
zend_ast *body_ast = arm_ast->child[1];
65366548
zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]);
65376549

6538-
if (conds->child[0]->kind != ZEND_AST_DEFAULT) {
6550+
if (!do_match_conditions_contain_default(conds)) {
65396551
for (uint32_t j = 0; j < conds->children; j++) {
65406552
zend_ast *cond_ast = conds->child[j];
65416553

0 commit comments

Comments
 (0)