diff options
author | Zefram <zefram@fysh.org> | 2017-01-23 02:25:50 +0000 |
---|---|---|
committer | Zefram <zefram@fysh.org> | 2017-01-23 22:25:42 +0000 |
commit | 3c157b3cf0631c69ffa5aa2d55b9199bf93b22a9 (patch) | |
tree | d7f916b738c0777c551896e40c7fb6a96830a56e /pp_ctl.c | |
parent | 7cb258c16018b4c963dd48cee7578d26045ff04c (diff) | |
download | perl-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.c | 11 |
1 files changed, 6 insertions, 5 deletions
@@ -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) |