sometimes the stash doesn't exist at all
Jesse Luehrs [Thu, 29 Mar 2012 07:50:35 +0000 (02:50 -0500)]
for instance, when it has been deleted

Changes
mop.c
t/bugs/delete_sub_stash.t [new file with mode: 0644]

diff --git a/Changes b/Changes
index 35de91a..8e5bed8 100644 (file)
--- a/Changes
+++ b/Changes
@@ -38,6 +38,9 @@ for, noteworthy changes.
     Eval::Closure (which should hopefully be fixed soon). Based on code and bug
     report from Carlos Lima. RT #74650.
 
+  * Fix a segfault when adding a method to a class which was defined in a
+    package which was deleted. (doy)
+
 2.0402 Sat, Feb 04, 2012
 
   [OTHER]
diff --git a/mop.c b/mop.c
index 6cb77f0..23ca98a 100644 (file)
--- a/mop.c
+++ b/mop.c
@@ -95,12 +95,14 @@ mop_get_code_info (SV *coderef, char **pkg, char **name)
     */
 
     if ( isGV_with_GP(CvGV(coderef)) ) {
-        GV *gv   = CvGV(coderef);
-        *pkg     = HvNAME( GvSTASH(gv) ? GvSTASH(gv) : CvSTASH(coderef) );
-        *name    = GvNAME( CvGV(coderef) );
+        GV *gv    = CvGV(coderef);
+        HV *stash = GvSTASH(gv) ? GvSTASH(gv) : CvSTASH(coderef);
+
+        *pkg  = stash ? HvNAME(stash) : "__UNKNOWN__";
+        *name = GvNAME( CvGV(coderef) );
     } else {
-        *pkg     = "__UNKNOWN__";
-        *name    = "__ANON__";
+        *pkg  = "__UNKNOWN__";
+        *name = "__ANON__";
     }
 
     return 1;
diff --git a/t/bugs/delete_sub_stash.t b/t/bugs/delete_sub_stash.t
new file mode 100644 (file)
index 0000000..b4f99a0
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More;
+
+use Moose ();
+
+{
+    package Foo;
+    sub bar { 'BAR' }
+}
+
+my $method = \&Foo::bar;
+
+{
+    no strict 'refs';
+    delete ${'::'}{'Foo::'};
+}
+
+my $meta = Moose::Meta::Class->create('Bar');
+$meta->add_method(bar => $method);
+is(Bar->bar, 'BAR');
+
+done_testing;