This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #77358] ISA warnings after aliasing packages
authorFather Chrysostomos <sprout@cpan.org>
Sun, 31 Oct 2010 01:19:56 +0000 (18:19 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 31 Oct 2010 01:19:56 +0000 (18:19 -0700)
commit8b9e80a3f70002d0c2fb6549a8fd594f358b9525
tree651ff37ff4aaa075555a6ab025b41229622874c3
parentd7fbb1de45aa77d305eccd94d8c07d7a1491fc45
[perl #77358] ISA warnings after aliasing packages

This commit makes mro_package_moved call mro_isa_changed_in on the
stash that has been assigned if it did not have an effective name
(HvENAME) before the assignment.

This is what was happening:

{package Right} # autovivify it
@thing::ISA = qw[Left];
*Left:: = delete $::{"Right::"};

When Right is deleted, it is not attached to the symbol table any
more, so it has no effective name. mro_isa_changed_in3 is called on
it, which resets the caches and then proceeds to cache a new isa linearisation. The new linearisation, of course, does not use the
name ‘Left’.

When Right is assigned over the top of Left, Right is given an
HvENAME of ‘Left’. Then mro_isa_changed_is3 is called on the
original Left, which, in turn, calls mro_isa_changed on its sub-
classes. So thing’s isa linearisation is calculated, which is just
‘thing’ + get_linear_isa(Left) (where ‘Left’ now refers to what was previously called Right). This ends up using the bad linearisation.

So the linearisation of a heretofore effectively nameless stash must
be recalculated, but after it has been given a name.

If it has an effective name already, then it appears elsewhere in the
symbol table, and its effective name does not change. (The name added
simply becomes an alternative to switch to should the HvENAME become
invalid.) So the existing isa cache is fine and we do not need to call
mro_isa_changed_in.

(That is a rather lengthy commit message, is it not?)
mro.c