From: Robin Houston <robin@cpan.org>
Date: Wed, 14 Mar 2001 01:52:51 +0000 (+0000)
Subject: Re: [ID 20010309.004] my-variables lose values while goto'ing within a for(;;)-loop
X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=9c5794fe8bd5803990d11472f5ebcdba0e7877cc;p=p5sagit%2Fp5-mst-13.2.git

Re: [ID 20010309.004] my-variables lose values while goto'ing within a for(;;)-loop
Message-ID: <20010314015251.B16112@puffinry.freeserve.co.uk>

Fix for 2000313.004.

p4raw-id: //depot/perl@9140
---

diff --git a/pp_ctl.c b/pp_ctl.c
index ede5aba..46e7ef0 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2463,8 +2463,11 @@ PP(pp_goto)
 	    cx = &cxstack[ix];
 	    switch (CxTYPE(cx)) {
 	    case CXt_EVAL:
-		gotoprobe = PL_eval_root; /* XXX not good for nested eval */
-		break;
+                if (CxREALEVAL(cx)) {
+		    gotoprobe = PL_eval_root; /* XXX not good for nested eval */
+		    break;
+                }
+                /* else fall through */
 	    case CXt_LOOP:
 		gotoprobe = cx->blk_oldcop->op_sibling;
 		break;
@@ -3506,7 +3509,6 @@ PP(pp_entertry)
     push_return(cLOGOP->op_other->op_next);
     PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), SP);
     PUSHEVAL(cx, 0, 0);
-    PL_eval_root = PL_op;		/* Only needed so that goto works right. */
 
     PL_in_eval = EVAL_INEVAL;
     sv_setpv(ERRSV,"");
diff --git a/t/op/goto.t b/t/op/goto.t
index 246184c..6f9e349 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..19\n";
+print "1..21\n";
 
 while ($?) {
     $foo = 1;
@@ -106,6 +106,29 @@ FORL2: for($y="ok 19\n"; 1;) {
   goto FORL2;
 }
 
+# Does goto work correctly within a try block?
+#  (BUG ID 20000313.004)
+
+my $ok = 0;
+eval {
+  my $variable = 1;
+  goto LABEL20;
+  LABEL20: $ok = 1 if $variable;
+};
+print ($ok&&!$@ ? "ok 20\n" : "not ok 20\n");
+
+# And within an eval-string?
+
+
+$ok = 0;
+eval q{
+  my $variable = 1;
+  goto LABEL21;
+  LABEL21: $ok = 1 if $variable;
+};
+print ($ok&&!$@ ? "ok 21\n" : "not ok 21\n");
+
+
 exit;
 
 bypass: