summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-08-26 23:21:26 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-08-27 00:13:07 -0700
commit25375124d2a06f2525e94c98c36eea007026778e (patch)
tree1fb76629bd05b31c30dfcda892fbbfcd4288f17b /pp_ctl.c
parent31d073689e2b5fa63aa7d4f8aaf529f75eeb5d0e (diff)
downloadperl-25375124d2a06f2525e94c98c36eea007026778e.tar.gz
[perl #119311] Keep CvDEPTH and savestack in sync
when unwinding sub and format calls. The comments in the added test file explain what the problem is. The fix is to call LEAVE_SCOPE in POPSUB and POPFORMAT (to free their lexicals) before lowering CvDEPTH. If the context has already been popped via cxstack_ix--, then LEAVE_SCOPE could overwrite it, so accessing cx after LEAVE_SCOPE is unsafe. Hence the changes to POPSUB and POPFORMAT are a bit involved. Some callers of POPSUB do a temporary cxstack_ix++ first so they can access cx afterwards. Two cases needed to be changed to work that way.
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 262c930026..a5e293c7d4 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2460,8 +2460,8 @@ PP(pp_return)
}
break;
case CXt_FORMAT:
- POPFORMAT(cx);
retop = cx->blk_sub.retop;
+ POPFORMAT(cx);
break;
default:
DIE(aTHX_ "panic: return, type=%u", (unsigned) CxTYPE(cx));
@@ -2550,8 +2550,8 @@ PP(pp_leavesublv)
S_return_lvalues(aTHX_ newsp, SP, newsp, gimme, cx, newpm);
LEAVE;
- cxstack_ix--;
POPSUB(cx,sv); /* Stack values are safe: release CV and @_ ... */
+ cxstack_ix--;
PL_curpm = newpm; /* ... and pop $1 et al */
LEAVESUB(sv);