Skip to content

Commit 6059148

Browse files
committed
toke.c: explicitly diagnose 'catch (my $e)'
Previously, this would produce Can't redeclare "my" in "our" at -e line 1, near "(my" Fixes #23222.
1 parent e11c762 commit 6059148

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

pod/perldiag.pod

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,10 +1485,23 @@ missing. You need to figure out where your CRTL misplaced its environ
14851485
or define F<PERL_ENV_TABLES> (see L<perlvms>) so that environ is not
14861486
searched.
14871487

1488+
=item Can't redeclare catch variable as "%s"
1489+
1490+
(F) A C<my>, C<our> or C<state> keyword was used with the exception variable in
1491+
a C<catch> block:
1492+
1493+
try { ... }
1494+
catch (my $e) { ... }
1495+
# or catch (our $e) { ... }
1496+
# or catch (state $e) { ... }
1497+
1498+
This is not valid syntax. C<catch> takes a bare variable name, which is
1499+
automatically lexically declared.
1500+
14881501
=item Can't redeclare "%s" in "%s"
14891502

1490-
(F) A "my", "our" or "state" declaration was found within another declaration,
1491-
such as C<my ($x, my($y), $z)> or C<our (my $x)>.
1503+
(F) A C<my>, C<our> or C<state> declaration was found within another
1504+
declaration, such as C<my ($x, my($y), $z)> or C<our (my $x)>.
14921505

14931506
=item Can't "redo" outside a loop block
14941507

toke.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7186,17 +7186,37 @@ yyl_do(pTHX_ char *s, I32 orig_keyword)
71867186
OPERATOR(KW_DO);
71877187
}
71887188

7189+
static const char *
7190+
declarator_name(I32 k) {
7191+
switch (k) {
7192+
case KEY_my: return "my";
7193+
case KEY_state: return "state";
7194+
case KEY_our: return "our";
7195+
case KEY_field: return "field";
7196+
case KEY_catch: return "catch";
7197+
default: return "???";
7198+
}
7199+
}
7200+
71897201
static int
71907202
yyl_my(pTHX_ char *s, I32 my)
71917203
{
7204+
assert(my == KEY_my || my == KEY_state || my == KEY_our);
71927205
if (PL_in_my) {
71937206
PL_bufptr = s;
7194-
yyerror(form(
7195-
"Can't redeclare \"%s\" in \"%s\"",
7196-
my == KEY_my ? "my" :
7197-
my == KEY_state ? "state" : "our",
7198-
PL_in_my == KEY_my ? "my" :
7199-
PL_in_my == KEY_state ? "state" : "our"));
7207+
if (PL_in_my == KEY_catch) {
7208+
yyerror(form(
7209+
"Can't redeclare catch variable as \"%s\"",
7210+
declarator_name(my)
7211+
));
7212+
} else {
7213+
assert(PL_in_my == KEY_my || PL_in_my == KEY_state || PL_in_my == KEY_our);
7214+
yyerror(form(
7215+
"Can't redeclare \"%s\" in \"%s\"",
7216+
declarator_name(my),
7217+
declarator_name(PL_in_my)
7218+
));
7219+
}
72007220
}
72017221
PL_in_my = (U16)my;
72027222
s = skipspace(s);

0 commit comments

Comments
 (0)