Skip to content

Commit 8cadc1f

Browse files
committed
Exercise statement in pp_ctl.c: S_unwind_loop()
Per suggestion by Dave Mitchell in GH #23948, including comment re pp_return(). Per review: Ensure that only one warning was generated in newly added test block. Also, improve two test descriptions.
1 parent 4f5c042 commit 8cadc1f

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

pp_ctl.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2886,6 +2886,8 @@ PP(pp_return)
28862886
if(CxTYPE(&cxstack[i]) == CXt_DEFER)
28872887
/* diag_listed_as: Can't "%s" out of a "defer" block */
28882888
/* diag_listed_as: Can't "%s" out of a "finally" block */
2889+
/* GH 23948: probably not reachable from test suite, but
2890+
* possibly from XS code; retain */
28892891
croak("Can't \"%s\" out of a \"%s\" block",
28902892
"return", S_defer_blockname(&cxstack[i]));
28912893
}

t/op/defer.t

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ BEGIN {
66
set_up_inc('../lib');
77
}
88

9-
plan 29;
9+
plan 32;
1010

1111
use feature 'defer';
1212
no warnings 'experimental::defer';
@@ -300,3 +300,28 @@ no warnings 'experimental::defer';
300300

301301
is($ok, "ok", 'eval{die} inside defer does not stop runloop');
302302
}
303+
304+
# [GH #23948]
305+
{
306+
use warnings;
307+
no warnings 'experimental';
308+
309+
my @warnings;
310+
local $SIG{__WARN__} = sub { push @warnings, "@_" };
311+
312+
my $err = '';
313+
for (1) {
314+
defer {
315+
eval 'last'; $err = $@; chomp $err;
316+
}
317+
}
318+
is(scalar @warnings, 1, "Got exactly one warning");
319+
like($warnings[0],
320+
qr/Exiting eval via last at/,
321+
"Got expected warning: exiting eval via last");
322+
like(
323+
$err,
324+
qr/Can't "last" out of a "defer" block at \(eval \d+\) line 1\./,
325+
"Got expected exception: last out of defer block");
326+
}
327+

0 commit comments

Comments
 (0)