This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #114888] Localise PL_comppad_name in cv_clone
authorFather Chrysostomos <sprout@cpan.org>
Sat, 15 Sep 2012 05:08:19 +0000 (22:08 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 15 Sep 2012 05:29:47 +0000 (22:29 -0700)
commitcbacc9aa064469dbad90cdce51a3e7abbdf202be
tree0d7b9b54a5835f238c8439e291501b8ff77b30ff
parent37b0b3b2e3fecf62fbb5a9c784ad24707e8d3581
[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.
pad.c
t/op/closure.t