summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorDave Mitchell <davem@fdisolutions.com>2004-02-24 23:25:52 +0000
committerDave Mitchell <davem@fdisolutions.com>2004-02-24 23:25:52 +0000
commit0a76ff6528f0ab52947d4f1b9664310ce137b9a0 (patch)
treeb27eddc8355704f3edb3a55a9eb8c4f11dc0707a /pp_ctl.c
parent1bca678fff053a0e59f0fc9898b8d61aeda6473e (diff)
downloadperl-0a76ff6528f0ab52947d4f1b9664310ce137b9a0.tar.gz
[perl #26959] fix memory leak in @_ = ...; goto &sub
p4raw-id: //depot/perl@22373
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 26fb164a6b..3c632e2f5c 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2182,6 +2182,7 @@ PP(pp_goto)
char *label;
int do_dump = (PL_op->op_type == OP_DUMP);
static char must_have_label[] = "goto must have label";
+ AV *oldav = Nullav;
label = 0;
if (PL_op->op_flags & OPf_STACKED) {
@@ -2242,7 +2243,7 @@ PP(pp_goto)
GvAV(PL_defgv) = cx->blk_sub.savearray;
/* abandon @_ if it got reified */
if (AvREAL(av)) {
- (void)sv_2mortal((SV*)av); /* delay until return */
+ oldav = av; /* delay until return */
av = newAV();
av_extend(av, items-1);
AvFLAGS(av) = AVf_REIFY;
@@ -2268,6 +2269,9 @@ PP(pp_goto)
/* Now do some callish stuff. */
SAVETMPS;
+ /* For reified @_, delay freeing till return from new sub */
+ if (oldav)
+ SAVEFREESV((SV*)oldav);
SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */
if (CvXSUB(cv)) {
#ifdef PERL_XSUB_OLDSTYLE