From: Dave Mitchell Date: Sat, 23 Oct 2004 21:50:19 +0000 (+0000) Subject: [perl #32039] Chained goto &sub drops data too early. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=b1464ded1acfef257a05adfafdd413fb0659a7e5;p=p5sagit%2Fp5-mst-13.2.git [perl #32039] Chained goto &sub drops data too early. Change 22373 to stop a memory leak in goto &foo intead caused the elements of @_ to be freed too early. This revised fix just transfers the reifiedness of the old @_ to the new @_ p4raw-id: //depot/perl@23418 --- diff --git a/pp_ctl.c b/pp_ctl.c index 2c18cf5..4b894fc 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -2248,7 +2248,6 @@ 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) { @@ -2263,6 +2262,7 @@ PP(pp_goto) SV** mark; I32 items = 0; I32 oldsave; + bool reified = 0; retry: if (!CvROOT(cv) && !CvXSUB(cv)) { @@ -2304,16 +2304,16 @@ PP(pp_goto) Copy(AvARRAY(av), SP + 1, items, SV*); SvREFCNT_dec(GvAV(PL_defgv)); GvAV(PL_defgv) = cx->blk_sub.savearray; + CLEAR_ARGARRAY(av); /* abandon @_ if it got reified */ if (AvREAL(av)) { - oldav = av; /* delay until return */ + reified = 1; + SvREFCNT_dec(av); av = newAV(); av_extend(av, items-1); AvFLAGS(av) = AVf_REIFY; PAD_SVl(0) = (SV*)(cx->blk_sub.argarray = av); } - else - CLEAR_ARGARRAY(av); } else if (CvXSUB(cv)) { /* put GvAV(defgv) back onto stack */ AV* av; @@ -2332,11 +2332,13 @@ 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)) { + if (reified) { + I32 index; + for (index=0; index