Skip to content

Commit

Permalink
Forbid using 'goto' to jump into a 'defer' block because everything w…
Browse files Browse the repository at this point in the history
…ill break when it's done
  • Loading branch information
leonerd committed Nov 22, 2021
1 parent 46c7599 commit b9c1fd8
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
5 changes: 5 additions & 0 deletions pod/perldiag.pod
Expand Up @@ -1042,6 +1042,11 @@ error occurs in cases such as these:
goto G;
$x + do { G: $y }; # How is + supposed to get its first operand?

=item Can't "goto" into a defer block

(F) A "goto" statement was executed to jump into the scope of a defer
block. This is not permitted.

=item Can't "goto" into a "given" block

(F) A "goto" statement was executed to jump into the middle of a C<given>
Expand Down
5 changes: 4 additions & 1 deletion pp_ctl.c
Expand Up @@ -2794,8 +2794,11 @@ S_dofindlabel(pTHX_ OP *o, const char *label, STRLEN len, U32 flags, OP **opstac
first_kid_of_binary = TRUE;
ops--;
}
if ((o = dofindlabel(kid, label, len, flags, ops, oplimit)))
if ((o = dofindlabel(kid, label, len, flags, ops, oplimit))) {
if (kid->op_type == OP_PUSHDEFER)
Perl_croak(aTHX_ "Can't \"goto\" into a defer block");
return o;
}
if (first_kid_of_binary)
*ops++ = UNENTERABLE;
}
Expand Down
15 changes: 14 additions & 1 deletion t/op/defer.t
Expand Up @@ -6,7 +6,7 @@ BEGIN {
set_up_inc('../lib');
}

plan 29;
plan 30;

use feature 'defer';
no warnings 'experimental::defer';
Expand Down Expand Up @@ -278,6 +278,19 @@ no warnings 'experimental::defer';
'Cannot goto out of defer block');
}

{
my $sub = sub {
while(1) {
goto HERE;
defer { HERE: 1; }
}
};

my $e = defined eval { $sub->(); 1 } ? undef : $@;
like($e, qr/^Can't "goto" into a defer block /,
'Cannot goto into defer block');
}

{
my $subA = sub {
my $subB = sub {};
Expand Down

0 comments on commit b9c1fd8

Please sign in to comment.