summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorDave Mitchell <davem@fdisolutions.com>2005-05-07 12:57:06 +0000
committerDave Mitchell <davem@fdisolutions.com>2005-05-07 12:57:06 +0000
commita034e688aeb372632feafc428b392a22393dec55 (patch)
tree00edd69325fa45e86f3a3a37b5ef01820d454559 /pp_ctl.c
parent5203fbcae61b42c66ba138a48162ecc0880db2c9 (diff)
downloadperl-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.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 03a4171e51..b61769aacc 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -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 *