summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2016-11-28 08:03:49 +0000
committerDavid Mitchell <davem@iabyn.com>2016-11-28 08:09:56 +0000
commit7332835e5da7b7a793ef814a84e53003be1d0138 (patch)
tree13ec718d8fd948831c7139b55d480cae85e4d9ac /pp_ctl.c
parent32458de9a4322bd2e66c525d33720a42df7e0b56 (diff)
downloadperl-7332835e5da7b7a793ef814a84e53003be1d0138.tar.gz
crash on explicit return from s///e
RT #130188 In sub f { my $x = 'a'; $x =~ s/./return;/e; } the 'return' triggers popping any contexts above the subroutine context: in this case, a CXt_SUBST context. In this case, Perl_dounwind() calls cx_popblock() for the bottom-most popped context, to restore any saved vars. However, CXt_SUBST is the one context type which *doesn't* use 'struct block' as part of its context struct union, so you can't cx_popblock() a CXt_SUBST context. This commit makes it skip the cx_popblock() in this case. Bug was introduced by me with v5.23.7-235-gfc6e609.
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 89a7521f60..ec0ad7d317 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1530,6 +1530,12 @@ Perl_dounwind(pTHX_ I32 cxix)
switch (CxTYPE(cx)) {
case CXt_SUBST:
CX_POPSUBST(cx);
+ /* CXt_SUBST is not a block context type, so skip the
+ * cx_popblock(cx) below */
+ if (cxstack_ix == cxix + 1) {
+ cxstack_ix--;
+ return;
+ }
break;
case CXt_SUB:
cx_popsub(cx);