[perl #120694] Fix ->SUPER::foo and AUTOLOAD
authorFather Chrysostomos <sprout@cpan.org>
Thu, 5 Dec 2013 00:00:48 +0000 (16:00 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 5 Dec 2013 05:20:51 +0000 (21:20 -0800)
Commit aae438050a20 (5.17.4) broke ->SUPER::foo with AUTOLOAD by look-
ing up AUTOLOAD from the current package, rather than the current
package‚Äôs superclass.

Instead of keeping track of whether it was doing a SUPER lookup via a
::SUPER prefix on the package name, that commit changed method lookup
to pass a GV_SUPER flag around (to fix another bug) and to pass the
current stash, rather than __PACKAGE__::SUPER.  But it did not update
gv_autoload_pvn to pass that flag through to gv_fetchmeth_pvn when
actually looking up the method.

gv.c
t/op/method.t

index 569537b..686f206 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -1122,7 +1122,8 @@ Perl_gv_autoload_pvn(pTHX_ HV *stash, const char *name, STRLEN len, U32 flags)
            packname = sv_2mortal(newSVhek(HvNAME_HEK(stash)));
        if (flags & GV_SUPER) sv_catpvs(packname, "::SUPER");
     }
-    if (!(gv = gv_fetchmeth_pvn(stash, S_autoload, S_autolen, FALSE, is_utf8)))
+    if (!(gv = gv_fetchmeth_pvn(stash, S_autoload, S_autolen, FALSE,
+                               is_utf8 | (flags & GV_SUPER))))
        return NULL;
     cv = GvCV(gv);
 
index d206fc7..059b44f 100644 (file)
@@ -13,7 +13,7 @@ BEGIN {
 use strict;
 no warnings 'once';
 
-plan(tests => 146);
+plan(tests => 147);
 
 @A::ISA = 'B';
 @B::ISA = 'C';
@@ -268,6 +268,27 @@ sub OtherSouper::method { "Isidore Ropen, Draft Manager" }
         'SUPER inside moved package respects method changes';
 }
 
+package foo120694 {
+    BEGIN { our @ISA = qw(bar120694) }
+
+    sub AUTOLOAD {
+        my $self = shift;
+        local our $recursive = $recursive;
+        return "recursive" if $recursive++;
+        return if our $AUTOLOAD eq 'DESTROY';
+        $AUTOLOAD = "SUPER:" . substr $AUTOLOAD, rindex($AUTOLOAD, ':');
+        return $self->$AUTOLOAD(@_);
+    }
+}
+package bar120694 {
+    sub AUTOLOAD {
+        return "xyzzy";
+    }
+}
+is bless( [] => "foo120694" )->plugh, 'xyzzy',
+    '->SUPER::method autoloading uses parent of current pkg';
+
+
 # failed method call or UNIVERSAL::can() should not autovivify packages
 is( $::{"Foo::"} || "none", "none");  # sanity check 1
 is( $::{"Foo::"} || "none", "none");  # sanity check 2