summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pp_ctl.c2
-rwxr-xr-xt/op/goto.t10
2 files changed, 11 insertions, 1 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 5143391289..a35d600530 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2203,6 +2203,7 @@ PP(pp_goto)
}
/* First do some returnish stuff. */
+ SvREFCNT_inc(cv); /* avoid premature free during unwind */
FREETMPS;
cxix = dopoptosub(cxstack_ix);
if (cxix < 0)
@@ -2250,6 +2251,7 @@ PP(pp_goto)
/* Now do some callish stuff. */
SAVETMPS;
+ SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */
if (CvXSUB(cv)) {
#ifdef PERL_XSUB_OLDSTYLE
if (CvOLDSTYLE(cv)) {
diff --git a/t/op/goto.t b/t/op/goto.t
index 122c624324..5b30dc5f41 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..27\n";
+print "1..28\n";
while ($?) {
$foo = 1;
@@ -177,6 +177,14 @@ print ($ok ? "ok 22\n" : "not ok 22\n");
print "ok 27 - weird case of goto and for(;;) loop\n";
}
+# bug #9990 - don't prematurely free the CV we're &going to.
+
+sub f1 {
+ my $x;
+ goto sub { $x; print "ok 28 - don't prematurely free CV\n" }
+}
+f1();
+
exit;
bypass: