diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 4fe06dbea52c4..5dd6d5ea6d8b8 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6303,6 +6303,11 @@ static void zend_compile_switch(zend_ast *ast) /* {{{ */ continue; } + if (case_ast->attr == ZEND_ALT_CASE_SYNTAX) { + CG(zend_lineno) = case_ast->lineno; + zend_error(E_DEPRECATED, "Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead"); + } + zend_compile_expr(&cond_node, cond_ast); if (expr_node.op_type == IS_CONST diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 7ac0a2b8b2c44..bea28378d03c2 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -1126,6 +1126,7 @@ ZEND_API zend_string *zend_type_to_string(zend_type type); ((ZEND_TYPE_FULL_MASK((arg_info)->type) & _ZEND_IS_TENTATIVE_BIT) != 0) #define ZEND_DIM_IS (1 << 0) /* isset fetch needed for null coalesce. Set in zend_compile.c for ZEND_AST_DIM nested within ZEND_AST_COALESCE. */ +#define ZEND_ALT_CASE_SYNTAX (1 << 1) /* deprecated switch case terminated by semicolon */ /* Attributes for ${} encaps var in strings (ZEND_AST_DIM or ZEND_AST_VAR node) */ /* ZEND_AST_VAR nodes can have any of the ZEND_ENCAPS_VAR_* flags */ diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 07ea669ae8e6c..b43713f3af91b 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -713,15 +713,14 @@ switch_case_list: case_list: %empty { $$ = zend_ast_create_list(0, ZEND_AST_SWITCH_LIST); } - | case_list T_CASE expr case_separator inner_statement_list + | case_list T_CASE expr ':' inner_statement_list { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, $3, $5)); } - | case_list T_DEFAULT case_separator inner_statement_list + | case_list T_CASE expr ';' inner_statement_list + { $$ = zend_ast_list_add($1, zend_ast_create_ex(ZEND_AST_SWITCH_CASE, ZEND_ALT_CASE_SYNTAX, $3, $5)); } + | case_list T_DEFAULT ':' inner_statement_list { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, NULL, $4)); } -; - -case_separator: - ':' - | ';' + | case_list T_DEFAULT ';' inner_statement_list + { $$ = zend_ast_list_add($1, zend_ast_create_ex(ZEND_AST_SWITCH_CASE, ZEND_ALT_CASE_SYNTAX, NULL, $4)); } ; diff --git a/ext/opcache/tests/issue0057.phpt b/ext/opcache/tests/issue0057.phpt index 20c2f2a10558a..ac73859b0d36e 100644 --- a/ext/opcache/tests/issue0057.phpt +++ b/ext/opcache/tests/issue0057.phpt @@ -15,9 +15,9 @@ class ZException extends Exception { function dummy($query) { try { switch ($query) { - case 1; + case 1: break; - case 2; + case 2: break; default: throw new Exception('exception'); diff --git a/tests/lang/033.phpt b/tests/lang/033.phpt index e6254d687b07c..41424e40489d6 100644 --- a/tests/lang/033.phpt +++ b/tests/lang/033.phpt @@ -37,7 +37,8 @@ switch ($a): break; endswitch; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead in %s If: 11 While: 12346789 For: 0123401234 diff --git a/tests/lang/bug26696.phpt b/tests/lang/bug26696.phpt index 1d10297b12c3d..de0dc90ca0d42 100644 --- a/tests/lang/bug26696.phpt +++ b/tests/lang/bug26696.phpt @@ -15,7 +15,7 @@ for ($i = 0; $i < $len; $i++) { $str = '*'; switch ($str[0]) { - case '*'; + case '*': echo "OK\n"; break; default: