diff options
author | Dave Mitchell <davem@fdisolutions.com> | 2005-05-07 12:57:06 +0000 |
---|---|---|
committer | Dave Mitchell <davem@fdisolutions.com> | 2005-05-07 12:57:06 +0000 |
commit | a034e688aeb372632feafc428b392a22393dec55 (patch) | |
tree | 00edd69325fa45e86f3a3a37b5ef01820d454559 /pp_ctl.c | |
parent | 5203fbcae61b42c66ba138a48162ecc0880db2c9 (diff) | |
download | perl-a034e688aeb372632feafc428b392a22393dec55.tar.gz |
while (my $x ...) { ...; redo } shouldn't undef $x.
In the presence of 'my' in the conditional of a while(), until(),
or for(;;) loop, add an extra scope to the body so that redo
doesn't undef the lexical
p4raw-id: //depot/perl@24412
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 11 |
1 files changed, 10 insertions, 1 deletions
@@ -2160,6 +2160,7 @@ PP(pp_redo) I32 cxix; register PERL_CONTEXT *cx; I32 oldsave; + OP* redo_op; if (PL_op->op_flags & OPf_SPECIAL) { cxix = dopoptoloop(cxstack_ix); @@ -2174,12 +2175,20 @@ PP(pp_redo) if (cxix < cxstack_ix) dounwind(cxix); + redo_op = cxstack[cxix].blk_loop.redo_op; + if (redo_op->op_type == OP_ENTER) { + /* pop one less context to avoid $x being freed in while (my $x..) */ + cxstack_ix++; + assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_BLOCK); + redo_op = redo_op->op_next; + } + TOPBLOCK(cx); oldsave = PL_scopestack[PL_scopestack_ix - 1]; LEAVE_SCOPE(oldsave); FREETMPS; PL_curcop = cx->blk_oldcop; - return cx->blk_loop.redo_op; + return redo_op; } STATIC OP * |