summaryrefslogtreecommitdiff
path: root/t/cmd
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-09-03 21:26:37 -0700
committerFather Chrysostomos <sprout@cpan.org>2012-09-15 22:45:07 -0700
commit1f122f9b83a0a767aa3a264b32482be38722715d (patch)
tree66e91e46cb294c3d0b7b8f7311c43fcb28e09d12 /t/cmd
parent8d88fe29d7f8e580970ac5a994ba499606884c4c (diff)
downloadperl-1f122f9b83a0a767aa3a264b32482be38722715d.tar.gz
CvOUTSIDE should be strong for lexsub declared in inner pack sub
PadnameOUTER (SvFAKE) entries in pads of clonable subs contain the offset in the parent pad where the closed-over entry is to be found. The pad itself does not reference the outer lexical until the sub is cloned at run time. newMYSUB had to account for that by following CvOUTSIDE for PadnameOUTER entries, to account for cases like this: my sub foo; my sub bar { sub foo {} } The sub foo{} definition would have to find the my sub foo declaration from outside and store the sub there. That code was not accounting for named package subs, which close over variables at compile time, so they don’t need (and don’t) store a par- ent offset. So outcv would point to bar in this case: my sub foo; sub bar { sub foo {} } If outcv matched CvOUTSIDE(foo), then CvOUTSIDE was made weak. That does not help in cases like this: undef *bar; { my sub foo; sub bar { sub foo {} } } If foo has a weak CvOUTSIDE pointer, then it will still point to bar after bar is freed, which does not help when the sub is cloned and tries to look at CvROOT(CvOUTSIDE). If the pad name is marked PadnameOUTER, even if it has no parent pad index, newMYSUB needs to leave the CvOUTSIDE pointer strongc. Also, pad_fixup_inner_anons did not account for subs with strong CvOUTSIDE pointers whose CvOUTSIDE point to the sub whose pad is being iterated through.
Diffstat (limited to 't/cmd')
-rw-r--r--t/cmd/lexsub.t9
1 files changed, 8 insertions, 1 deletions
diff --git a/t/cmd/lexsub.t b/t/cmd/lexsub.t
index 293f70f226..72ad6c7219 100644
--- a/t/cmd/lexsub.t
+++ b/t/cmd/lexsub.t
@@ -8,7 +8,7 @@ BEGIN {
*bar::like = *like;
}
no warnings 'deprecated';
-plan 111;
+plan 112;
# -------------------- our -------------------- #
@@ -537,3 +537,10 @@ sub not_lexical5 {
}
is not_lexical4, 234,
'my sub defined in predeclared pkg sub but declared outside';
+
+undef *not_lexical6;
+{
+ my sub foo;
+ sub not_lexical6 { sub foo { } }
+ pass 'no crash when cloning a mysub declared inside an undef pack sub';
+}