This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Restore the package name to overload errors; fix crash
authorFather Chrysostomos <sprout@cpan.org>
Sat, 1 Oct 2011 01:27:58 +0000 (18:27 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 1 Oct 2011 03:16:31 +0000 (20:16 -0700)
Commit bfcb351493b (which was backported to 5.8.8) caused these error
messages always to mention the overload package, instead of the pack-
age involved:

Can't resolve method "foo" overloading "+" in package "baz"
Stub found while resolving method "foo" overloading "+" in package "baz"

This commit fixes that.  A compiler warning alerted me to the possi-
bility of HvNAME being null, so I wrote a small test for that, found
that it crashed, and incorporated the fix for the crash into the same
commit (since it’s the same line of code).

gv.c
lib/overload.t

diff --git a/gv.c b/gv.c
index 19059bc..b5c3590 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -2056,9 +2056,10 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing)
            gv = Perl_gv_fetchmeth(aTHX_ stash, cooky, l, -1);
         cv = 0;
         if (gv && (cv = GvCV(gv))) {
-           const char *hvname;
-           if (GvNAMELEN(CvGV(cv)) == 3 && strEQ(GvNAME(CvGV(cv)), "nil")
-               && strEQ(hvname = HvNAME_get(GvSTASH(CvGV(cv))), "overload")) {
+           if(GvNAMELEN(CvGV(cv)) == 3 && strEQ(GvNAME(CvGV(cv)), "nil")){
+             const char * const hvname = HvNAME_get(GvSTASH(CvGV(cv)));
+             if (hvname && HEK_LEN(HvNAME_HEK(GvSTASH(CvGV(cv)))) == 8
+              && strEQ(hvname, "overload")) {
                /* This is a hack to support autoloading..., while
                   knowing *which* methods were declared as overloaded. */
                /* GvSV contains the name of the method. */
@@ -2067,7 +2068,7 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing)
 
                DEBUG_o( Perl_deb(aTHX_ "Resolving method \"%"SVf256\
                        "\" for overloaded \"%s\" in package \"%.256s\"\n",
-                            (void*)GvSV(gv), cp, hvname) );
+                            (void*)GvSV(gv), cp, HvNAME(stash)) );
                if (!gvsv || !SvPOK(gvsv)
                    || !(ngv = gv_fetchmethod_autoload(stash, SvPVX_const(gvsv),
                                                       FALSE)))
@@ -2082,10 +2083,11 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing)
                                    "in package \"%.256s\"",
                                   (GvCVGEN(gv) ? "Stub found while resolving"
                                    : "Can't resolve"),
-                                  name, cp, hvname);
+                                  name, cp, HvNAME(stash));
                    }
                }
                cv = GvCV(gv = ngv);
+             }
            }
            DEBUG_o( Perl_deb(aTHX_ "Overloading \"%s\" in package \"%.256s\" via \"%.256s::%.256s\"\n",
                         cp, HvNAME_get(stash), HvNAME_get(GvSTASH(CvGV(cv))),
index 605429e..2efc5aa 100644 (file)
@@ -48,7 +48,7 @@ package main;
 
 $| = 1;
 BEGIN { require './test.pl' }
-plan tests => 4982;
+plan tests => 4983;
 
 use Scalar::Util qw(tainted);
 
@@ -2173,7 +2173,7 @@ fresh_perl_is
     use overload '+' => 'justice';
     eval {bless[]};
     ::like $@, qr/^Can't resolve method "justice" overloading "\+" in p(?x:
-                  )ackage "overload" at /,
+                  )ackage "Justus" at /,
       'Error message when explicitly named overload method does not exist';
 
     package JustUs;
@@ -2182,8 +2182,16 @@ fresh_perl_is
     "JustUs"->${\"(+"};
     eval {bless []};
     ::like $@, qr/^Stub found while resolving method "\?{3}" overloadin(?x:
-                  )g "\+" in package "overload" at /,
+                  )g "\+" in package "JustUs" at /,
       'Error message when sub stub is encountered';
 }
 
+{ # undefining the overload stash -- KEEP THIS TEST LAST
+    package ant;
+    use overload '+' => 'onion';
+    $_ = \&overload::nil;
+    undef %overload::;
+    ::ok(1, 'no crash when undefining %overload::');
+}
+
 # EOF