oldsave = PL_scopestack[cx->blk_oldscopesp - 1];
LEAVE_SCOPE(oldsave);
- if (CxTYPE(cx) == CXt_SUB) {
- CvDEPTH(cx->blk_sub.cv) = cx->blk_sub.olddepth;
- SvREFCNT_dec_NN(cx->blk_sub.cv);
- }
-
/* A destructor called during LEAVE_SCOPE could have undefined
* our precious cv. See bug #99850. */
if (!CvROOT(cv) && !CvXSUB(cv)) {
DIE(aTHX_ "Goto undefined subroutine");
}
+ if (CxTYPE(cx) == CXt_SUB) {
+ CvDEPTH(cx->blk_sub.cv) = cx->blk_sub.olddepth;
+ SvREFCNT_dec_NN(cx->blk_sub.cv);
+ }
+
/* Now do some callish stuff. */
SAVETMPS;
SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */
use warnings;
use strict;
-plan tests => 96;
+plan tests => 97;
our $TODO;
my $deprecated = 0;
like $@, qr/^Goto undefined subroutine &_99850::reftype at /,
'goto &foo undefining &foo on sub cleanup';
+# When croaking after discovering that the new CV you're about to goto is
+# undef, make sure that the old CV isn't doubly freed.
+
+package Do_undef {
+ my $count;
+
+ # creating a new closure here encourages any prematurely freed
+ # CV to be reallocated
+ sub DESTROY { undef &undef_sub; my $x = sub { $count } }
+
+ sub f {
+ $count++;
+ my $guard = bless []; # trigger DESTROY during goto
+ *undef_sub = sub {};
+ goto &undef_sub
+ }
+
+ for (1..10) {
+ eval { f() };
+ }
+ ::is($count, 10, "goto undef_sub safe");
+}
+
+
# bug #22181 - this used to coredump or make $x undefined, due to
# erroneous popping of the inner BLOCK context