This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix CvGV assertion bug with sub redefinition
authorFather Chrysostomos <sprout@cpan.org>
Fri, 27 Jul 2012 17:11:25 +0000 (10:11 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 27 Jul 2012 17:24:44 +0000 (10:24 -0700)
commitf6894bc8d44272e8edc3e1c3719989f1b171de3f
tree7d13592443ce9c95cc3e808a8c556c22aafe7ec1
parentd40eae8f110fb9900e82648a2c44710def9f117d
Fix CvGV assertion bug with sub redefinition

*foo = \&baz;
*bar = *foo;
eval 'sub bar { print +(caller 0)[3], "\n" }';
bar();

Before 5.14, that produces:

main::foo

As of 5.14, it produces:

main::baz

Or, under debugging builds:

Assertion failed: (CvGV(cv) == gv), function Perl_newATTRSUB_flags, file op.c, line 7139.

commit 437388a93114b1acbfb3a173dfa7aa2138fd8283
Author: Nicholas Clark <nick@ccl4.org>
Date:   Thu Nov 18 14:54:44 2010 +0000

    Refactor newATTRSUB()'s logic for grafting a sub definition to an existing stub

    Previously it was using cv_undef() to (partially) free the target CV (the
    pre-existing stub), before donating it the padlist and outside pointers from
    the source CV (the definition, just compiled), and then freeing up the remains
    of the source CV.

    Instead, explicitly exchange padlist and outside pointers, explicitly assign
    other fields that need changing (file and stash), and assert that various
    CvFLAGS are as we expect them.

That commit adds some assertions, including:

+     assert(!CvCVGV_RC(cv));
+     assert(CvGV(cv) == gv);

Those assertions are not always true.  CvGV might be refcounted, and
it might not point to the same gv.

437388a93 also changed things such that the CVf_CVGV_RC flag is clob-
bered, so refcounting and backrefs get out of synch (tests for that
specific bug will be in a subsequent commit).  It also stopped sub
redefinition from setting CvGV.
op.c
t/op/sub.t