summaryrefslogtreecommitdiff
path: root/pad.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-09-14 22:08:19 -0700
committerFather Chrysostomos <sprout@cpan.org>2012-09-14 22:29:47 -0700
commitcbacc9aa064469dbad90cdce51a3e7abbdf202be (patch)
tree0d7b9b54a5835f238c8439e291501b8ff77b30ff /pad.c
parent37b0b3b2e3fecf62fbb5a9c784ad24707e8d3581 (diff)
downloadperl-cbacc9aa064469dbad90cdce51a3e7abbdf202be.tar.gz
[perl #114888] Localise PL_comppad_name in cv_clone
In 9ef8d56 I made closures share their pad name lists, and not just the names themselves, for speed (no need to SvREFCNT_inc each name and copy the list). To make that work, I had to set PL_comppad_name in cv_clone, before the pad_new call. But I failed to move the PL_comppad_name localisa- tion from pad_new to cv_clone. So cv_clone would merrily clobber the previous value of PL_comppad_name *before* localising it. This only manifested itself in source filters. Most of the time, pp_anoncode is called at run time when either no code is being com- piled (PL_comppad_name is only used at compile time) or inside a BEGIN block which itself localises PL_comppad_name. But inside a Filter::Util::Call source filter there was no buffer like that to protect it. This meant that pad name creation (my $x) would create the name in the PL_comppad_name belonging to the last-cloned sub. A subsequent name lookup ($x) would look in the correct place, as it uses the moral equivalent of PadlistNAMES(CvPADLIST(PL_compcv)), not PL_comppad_name. So it would not find it, resulting in a global variable or a stricture violation.
Diffstat (limited to 'pad.c')
-rw-r--r--pad.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/pad.c b/pad.c
index fd75d4252b..711fd21b97 100644
--- a/pad.c
+++ b/pad.c
@@ -247,8 +247,8 @@ Perl_pad_new(pTHX_ int flags)
if (flags & padnew_SAVE) {
SAVECOMPPAD();
- SAVESPTR(PL_comppad_name);
if (! (flags & padnew_CLONE)) {
+ SAVESPTR(PL_comppad_name);
SAVEI32(PL_padix);
SAVEI32(PL_comppad_name_fill);
SAVEI32(PL_min_intro_pending);
@@ -2004,6 +2004,7 @@ Perl_cv_clone(pTHX_ CV *proto)
if (SvMAGIC(proto))
mg_copy((SV *)proto, (SV *)cv, 0, 0);
+ SAVESPTR(PL_comppad_name);
PL_comppad_name = protopad_name;
CvPADLIST(cv) = pad_new(padnew_CLONE|padnew_SAVE);
CvPADLIST(cv)->xpadl_id = protopadlist->xpadl_id;