From: Gurusamy Sarathy Date: Sun, 18 Jul 1999 03:51:03 +0000 (+0000) Subject: remove spurious newSTATEOP() that causes goto to enter one too many X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=2c15bef39460c09b2a7846a30a4fc1fc1c4f93e4;p=p5sagit%2Fp5-mst-13.2.git remove spurious newSTATEOP() that causes goto to enter one too many contexts when jumping between if and elsif blocks p4raw-id: //depot/perl@3692 --- diff --git a/perly.c b/perly.c index b92de4e..0feca48 100644 --- a/perly.c +++ b/perly.c @@ -1623,8 +1623,7 @@ break; case 23: #line 179 "perly.y" { PL_copline = yyvsp[-5].ival; - yyval.opval = newSTATEOP(0, Nullch, - newCONDOP(0, yyvsp[-3].opval, scope(yyvsp[-1].opval), yyvsp[0].opval)); + yyval.opval = newCONDOP(0, yyvsp[-3].opval, scope(yyvsp[-1].opval), yyvsp[0].opval); PL_hints |= HINT_BLOCK_SCOPE; } break; case 24: diff --git a/perly.y b/perly.y index f1de7c7..2594c08 100644 --- a/perly.y +++ b/perly.y @@ -174,8 +174,7 @@ else : /* NULL */ { $$ = scope($2); } | ELSIF '(' mexpr ')' mblock else { PL_copline = $1; - $$ = newSTATEOP(0, Nullch, - newCONDOP(0, $3, scope($5), $6)); + $$ = newCONDOP(0, $3, scope($5), $6); PL_hints |= HINT_BLOCK_SCOPE; } ; diff --git a/pp_ctl.c b/pp_ctl.c index 60d778b..f94bd54 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -1916,29 +1916,32 @@ S_dofindlabel(pTHX_ OP *o, char *label, OP **opstack, OP **oplimit) *ops++ = cUNOPo->op_first; if (ops >= oplimit) Perl_croak(aTHX_ too_deep); + *ops = 0; } - *ops = 0; if (o->op_flags & OPf_KIDS) { dTHR; /* First try all the kids at this level, since that's likeliest. */ for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) { - if ((kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) && - kCOP->cop_label && strEQ(kCOP->cop_label, label)) + if ((kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) + && kCOP->cop_label && strEQ(kCOP->cop_label, label)) + { return kid; + } } for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) { if (kid == PL_lastgotoprobe) continue; - if ((kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) && - (ops == opstack || - (ops[-1]->op_type != OP_NEXTSTATE && - ops[-1]->op_type != OP_DBSTATE))) + if ((kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) + && (ops == opstack || (ops[-1]->op_type != OP_NEXTSTATE + && ops[-1]->op_type != OP_DBSTATE))) + { *ops++ = kid; + *ops = 0; + } if (o = dofindlabel(kid, label, ops, oplimit)) return o; } } - *ops = 0; return 0; } diff --git a/t/op/goto.t b/t/op/goto.t index 8096aff..7a5de5f 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..13\n"; +print "1..16\n"; while ($?) { $foo = 1; @@ -55,6 +55,27 @@ exit; FINALE: print "ok 13\n"; + +# does goto LABEL handle block contexts correctly? + +my $cond = 1; +for (1) { + if ($cond == 1) { + $cond = 0; + goto OTHER; + } + elsif ($cond == 0) { + OTHER: + $cond = 2; + print "ok 14\n"; + goto THIRD; + } + else { + THIRD: + print "ok 15\n"; + } +} +print "ok 16\n"; exit; bypass: