This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Stop anon sub compilation from clobbering __ANON__
authorFather Chrysostomos <sprout@cpan.org>
Sat, 30 Aug 2014 23:19:24 +0000 (16:19 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 31 Aug 2014 13:58:25 +0000 (06:58 -0700)
Anonymous subs point to *__ANON__ simply because internals expect
defined subroutines to have CvGV pointing somewhere.

So why does anonymous constant sub compilation wipe
*__ANON__{CODE} clean?

$ perl -e 'sub main::__ANON__ { 42 }; warn main::__ANON__; # sub(){3}'
42 at -e line 1.
$ perl -e 'sub main::__ANON__ { 42 }; warn main::__ANON__;  sub(){3}'
Undefined subroutine &main::__ANON__ called at -e line 1.

It doesn’t happen with non-constant subs:

$ perl -e 'sub main::__ANON__ { 42 }; warn main::__ANON__;  sub{3}'
42 at -e line 1.

This is actually a regression:

../perl.git/Porting/bisect.pl  --end=perl-5.8.8  --target=miniperl -e  'sub main::__ANON__ { 42 }; warn main::__ANON__;  sub(){3}'

beab0874143b7208922720fecefc4a224011fa25 is the first bad commit
commit beab0874143b7208922720fecefc4a224011fa25
Author: John Tobey <jtobey at john-edwin-tobey.org>
Date:   Fri Oct 20 18:03:27 2000 -0400

    Re: Creating const subs for constants.
    Message-Id: <m13mo0N-000FObC@feynman.localnet>

    p4raw-id: //depot/perl@7389

The new code path for constants did an unconditional
GvCV_set(gv, NULL), instead of checking whether there was a
name first.

op.c
t/op/anonsub.t

diff --git a/op.c b/op.c
index 70365f7..15c3c04 100644 (file)
--- a/op.c
+++ b/op.c
@@ -7767,7 +7767,7 @@ Perl_newATTRSUB_x(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs,
            CvISXSUB_on(cv);
        }
        else {
-           GvCV_set(gv, NULL);
+           if (name) GvCV_set(gv, NULL);
            cv = newCONSTSUB_flags(
                NULL, name, namlen, name_is_utf8 ? SVf_UTF8 : 0,
                const_sv
index 6b8745f..ceb8d09 100644 (file)
@@ -91,3 +91,10 @@ undef &{$x=sub{}};
 $x->();
 EXPECT
 Undefined subroutine called at - line 4.
+########
+# NAME anon constant clobbering __ANON__
+sub __ANON__ { "42\n" }
+print __ANON__;
+sub(){3};
+EXPECT
+42