Skip to content

Commit 1e412f9

Browse files
committed
Catch exceptions without capturing them to variables
Work in progress, will be posted to RFC later.
1 parent 305b17e commit 1e412f9

File tree

4 files changed

+27
-8
lines changed

4 files changed

+27
-8
lines changed

Zend/tests/try/catch_novar.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
catch without capturing a variable
3+
--FILE--
4+
5+
6+
try {
7+
throw new Exception()
8+
} catch (Exception) {
9+
echo "caught!\n";
10+
}
11+
--EXPECT--
12+
caught!

Zend/zend_ast.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,8 +1992,10 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
19921992
case ZEND_AST_CATCH:
19931993
smart_str_appends(str, "} catch (");
19941994
zend_ast_export_catch_name_list(str, zend_ast_get_list(ast->child[0]), indent);
1995-
smart_str_appends(str, " $");
1996-
zend_ast_export_var(str, ast->child[1], 0, indent);
1995+
if (ast->child[1]) {
1996+
smart_str_appends(str, " $");
1997+
zend_ast_export_var(str, ast->child[1], 0, indent);
1998+
}
19971999
smart_str_appends(str, ") {\n");
19982000
zend_ast_export_stmt(str, ast->child[2], indent + 1);
19992001
zend_ast_export_indent(str, indent);

Zend/zend_compile.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5229,7 +5229,7 @@ void zend_compile_try(zend_ast *ast) /* {{{ */
52295229
zend_ast_list *classes = zend_ast_get_list(catch_ast->child[0]);
52305230
zend_ast *var_ast = catch_ast->child[1];
52315231
zend_ast *stmt_ast = catch_ast->child[2];
5232-
zend_string *var_name = zval_make_interned_string(zend_ast_get_zval(var_ast));
5232+
zend_string *var_name = var_ast ? zval_make_interned_string(zend_ast_get_zval(var_ast)) : NULL;
52335233
zend_bool is_last_catch = (i + 1 == catches->children);
52345234

52355235
uint32_t *jmp_multicatch = safe_emalloc(sizeof(uint32_t), classes->children - 1, 0);
@@ -5257,12 +5257,12 @@ void zend_compile_try(zend_ast *ast) /* {{{ */
52575257
zend_resolve_class_name_ast(class_ast));
52585258
opline->extended_value = zend_alloc_cache_slot();
52595259

5260-
if (zend_string_equals_literal(var_name, "this")) {
5260+
if (var_name && zend_string_equals_literal(var_name, "this")) {
52615261
zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
52625262
}
52635263

5264-
opline->result_type = IS_CV;
5265-
opline->result.var = lookup_cv(var_name);
5264+
opline->result_type = var_name ? IS_CV : IS_UNUSED;
5265+
opline->result.var = var_name ? lookup_cv(var_name) : -1;
52665266

52675267
if (is_last_catch && is_last_class) {
52685268
opline->extended_value |= ZEND_LAST_CATCH;

Zend/zend_language_parser.y

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
247247
%type encaps_var encaps_var_offset isset_variables
248248
%type top_statement_list use_declarations const_list inner_statement_list if_stmt
249249
%type alt_if_stmt for_exprs switch_case_list global_var_list static_var_list
250-
%type echo_expr_list unset_variables catch_name_list catch_list parameter_list class_statement_list
250+
%type echo_expr_list unset_variables catch_name_list catch_list optional_variable parameter_list class_statement_list
251251
%type implements_list case_list if_stmt_without_else
252252
%type non_empty_parameter_list argument_list non_empty_argument_list property_list
253253
%type class_const_list class_const_decl class_name_list trait_adaptations method_body non_empty_for_exprs
@@ -465,7 +465,7 @@ statement:
465465
catch_list:
466466
%empty
467467
{ $$ = zend_ast_create_list(0, ZEND_AST_CATCH_LIST); }
468-
| catch_list T_CATCH '(' catch_name_list T_VARIABLE ')' '{' inner_statement_list '}'
468+
| catch_list T_CATCH '(' catch_name_list optional_variable ')' '{' inner_statement_list '}'
469469
{ $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_CATCH, $4, $5, $8)); }
470470
;
471471

@@ -474,6 +474,11 @@ catch_name_list:
474474
| catch_name_list '|' class_name { $$ = zend_ast_list_add($1, $3); }
475475
;
476476

477+
optional_variable:
478+
%empty { $$ = NULL; }
479+
| T_VARIABLE { $$ = $1; }
480+
;
481+
477482
finally_statement:
478483
%empty { $$ = NULL; }
479484
| T_FINALLY '{' inner_statement_list '}' { $$ = $3; }

0 commit comments

Comments
 (0)