This commit stops CV anonymisation from autovivifying stashes to point
to (unless the stash is %__ANON__::).
If a stash has been deleted from its original position in the symbol
table, then its HvNAME will no longer indicate where to find it.
S_anonymise_cv_maybe in sv.c was using the HvNAME to look up (and
autovivify) the *__ANON__ glob in the stash, without taking into
account that it might not actually be looking in the right spot.
So now, after checking that the stash still has a name (HvNAME), it
uses the HvENAME to find it. If the HvENAME is null, which indicates
that the stash has been detached altogether, then %__ANON__:: is used,
as happens when HvNAME is null.
This solves a Class::Monadic failure introduced by commit
2d0d1eccfc
([perl #79208] %stash:: = () anonymises CVs), which was included
in 5.13.7.
Basically, it can be reduced to this:
}
/* if not, anonymise: */
- stash = GvSTASH(gv) ? HvNAME(GvSTASH(gv)) : NULL;
+ stash = GvSTASH(gv) && HvNAME(GvSTASH(gv))
+ ? HvENAME(GvSTASH(gv)) : NULL;
gvname = Perl_newSVpvf(aTHX_ "%s::__ANON__",
stash ? stash : "__ANON__");
anongv = gv_fetchsv(gvname, GV_ADDMULTI, SVt_PVCV);
BEGIN { require "./test.pl"; }
-plan( tests => 51 );
+plan( tests => 53 );
# Used to segfault (bug #15479)
fresh_perl_like(
is($st, q/__ANON__/, "...and an __ANON__ stash");
}
+ my $sub = do {
+ package six;
+ \&{"six"}
+ };
+ my $stash_glob = delete $::{"six::"};
+ # Now free the GV while the stash still exists (though detached)
+ delete $$stash_glob{"six"};
+ $gv = B::svref_2object($sub)->GV;
+ ok($gv->isa(q/B::GV/),
+ 'anonymised CV whose stash is detached still has a GV');
+ is $gv->STASH->NAME, '__ANON__',
+ 'CV anonymised when its stash is detached becomes __ANON__::__ANON__';
+
# CvSTASH should be null on a named sub if the stash has been deleted
{
package FOO;