summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1999-07-18 03:51:03 +0000
committerGurusamy Sarathy <gsar@cpan.org>1999-07-18 03:51:03 +0000
commit2c15bef39460c09b2a7846a30a4fc1fc1c4f93e4 (patch)
tree956621b9bd6ef82607bc2044a25afda197257cef
parent2aa1486d5d3f3b27276656f9b9ef842d3a21a386 (diff)
downloadperl-2c15bef39460c09b2a7846a30a4fc1fc1c4f93e4.tar.gz
remove spurious newSTATEOP() that causes goto to enter one too many
contexts when jumping between if and elsif blocks p4raw-id: //depot/perl@3692
-rw-r--r--perly.c3
-rw-r--r--perly.y3
-rw-r--r--pp_ctl.c19
-rwxr-xr-xt/op/goto.t23
4 files changed, 35 insertions, 13 deletions
diff --git a/perly.c b/perly.c
index b92de4eb21..0feca48bed 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 f1de7c751e..2594c087f7 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 60d778b5a1..f94bd54b89 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 8096aff0f2..7a5de5fea5 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: