From: Adrian M. Enache Date: Sat, 8 Feb 2003 21:05:14 +0000 (+0200) Subject: Re: trying to fix #20154, #20357 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=33d34e4c563f3e0b3627fb43d2e2a2ef278a273a;p=p5sagit%2Fp5-mst-13.2.git Re: trying to fix #20154, #20357 Message-ID: <20030208190514.GA866@ratsnest.hole> (fixes #19061 as well) p4raw-id: //depot/perl@18703 --- diff --git a/pp_ctl.c b/pp_ctl.c index 73d1365..5699b7c 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -2015,6 +2015,7 @@ S_dofindlabel(pTHX_ OP *o, char *label, OP **opstack, OP **oplimit) if (o->op_type == OP_LEAVE || o->op_type == OP_SCOPE || o->op_type == OP_LEAVELOOP || + o->op_type == OP_LEAVESUB || o->op_type == OP_LEAVETRY) { *ops++ = cUNOPo->op_first; @@ -2273,6 +2274,7 @@ PP(pp_goto) if (label && *label) { OP *gotoprobe = 0; bool leaving_eval = FALSE; + bool in_block = FALSE; PERL_CONTEXT *last_eval_cx = 0; /* find label */ @@ -2298,9 +2300,10 @@ PP(pp_goto) case CXt_SUBST: continue; case CXt_BLOCK: - if (ix) + if (ix) { gotoprobe = cx->blk_oldcop->op_sibling; - else + in_block = TRUE; + } else gotoprobe = PL_main_root; break; case CXt_SUB: @@ -2357,7 +2360,8 @@ PP(pp_goto) if (*enterops && enterops[1]) { OP *oldop = PL_op; - for (ix = 1; enterops[ix]; ix++) { + ix = enterops[1]->op_type == OP_ENTER && in_block ? 2 : 1; + for (; enterops[ix]; ix++) { PL_op = enterops[ix]; /* Eventually we may want to stack the needed arguments * for each op. For now, we punt on the hard ones. */ diff --git a/t/op/goto.t b/t/op/goto.t index a0b4d55..122c624 100755 --- a/t/op/goto.t +++ b/t/op/goto.t @@ -2,7 +2,7 @@ # "This IS structured code. It's just randomly structured." -print "1..22\n"; +print "1..27\n"; while ($?) { $foo = 1; @@ -144,6 +144,39 @@ $ok = 0 if $@; } print ($ok ? "ok 22\n" : "not ok 22\n"); +{ + my $false = 0; + + $ok = 0; + { goto A; A: $ok = 1 } continue { } + print "not " unless $ok; + print "ok 23 - #20357 goto inside /{ } continue { }/ loop\n"; + + $ok = 0; + { do { goto A; A: $ok = 1 } while $false } + print "not " unless $ok; + print "ok 24 - #20154 goto inside /do { } while ()/ loop\n"; + + $ok = 0; + foreach(1) { goto A; A: $ok = 1 } continue { }; + print "not " unless $ok; + print "ok 25 - goto inside /foreach () { } continue { }/ loop\n"; + + $ok = 0; + sub a { + A: { if ($false) { redo A; B: $ok = 1; redo A; } } + goto B unless $r++ + } + a(); + print "not " unless $ok; + print "ok 26 - #19061 loop label wiped away by goto\n"; + + $ok = 0; + for ($p=1;$p && goto A;$p=0) { A: $ok = 1 } + print "not " unless $ok; + print "ok 27 - weird case of goto and for(;;) loop\n"; +} + exit; bypass: