remove spurious newSTATEOP() that causes goto to enter one too many
Gurusamy Sarathy [Sun, 18 Jul 1999 03:51:03 +0000 (03:51 +0000)]
contexts when jumping between if and elsif blocks

p4raw-id: //depot/perl@3692

perly.c
perly.y
pp_ctl.c
t/op/goto.t

diff --git a/perly.c b/perly.c
index b92de4e..0feca48 100644 (file)
--- 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 (file)
--- 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; }
        ;
 
index 60d778b..f94bd54 100644 (file)
--- 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;
 }
 
index 8096aff..7a5de5f 100755 (executable)
@@ -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: