summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorZefram <zefram@fysh.org>2017-01-23 02:25:50 +0000
committerZefram <zefram@fysh.org>2017-01-23 22:25:42 +0000
commit3c157b3cf0631c69ffa5aa2d55b9199bf93b22a9 (patch)
treed7f916b738c0777c551896e40c7fb6a96830a56e /pp_ctl.c
parent7cb258c16018b4c963dd48cee7578d26045ff04c (diff)
downloadperl-3c157b3cf0631c69ffa5aa2d55b9199bf93b22a9.tar.gz
permit goto at top level of multicalled sub
A multicalled sub is reckoned to be a pseudo block, out of which it is not permissible to goto. However, the test for a pseudo block was being applied too early, preventing not just escape from a multicalled sub but also a goto at the top level within the sub. This is a bug similar, but not identical, to [perl #113938]. Now the test is deferred, permitting goto at the sub's top level but still forbidding goto out of it.
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 2ced82dc07..f48f3013ce 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2946,6 +2946,7 @@ PP(pp_goto)
OP *gotoprobe = NULL;
bool leaving_eval = FALSE;
bool in_block = FALSE;
+ bool pseudo_block = FALSE;
PERL_CONTEXT *last_eval_cx = NULL;
/* find label */
@@ -2984,11 +2985,9 @@ PP(pp_goto)
gotoprobe = PL_main_root;
break;
case CXt_SUB:
- if (CvDEPTH(cx->blk_sub.cv) && !CxMULTICALL(cx)) {
- gotoprobe = CvROOT(cx->blk_sub.cv);
- break;
- }
- /* FALLTHROUGH */
+ gotoprobe = CvROOT(cx->blk_sub.cv);
+ pseudo_block = cBOOL(CxMULTICALL(cx));
+ break;
case CXt_FORMAT:
case CXt_NULL:
DIE(aTHX_ "Can't \"goto\" out of a pseudo block");
@@ -3017,6 +3016,8 @@ PP(pp_goto)
break;
}
}
+ if (pseudo_block)
+ DIE(aTHX_ "Can't \"goto\" out of a pseudo block");
PL_lastgotoprobe = gotoprobe;
}
if (!retop)