blead segfaults on local *@; eval {1} because ERRSV assumes that
Nicholas Clark [Thu, 31 May 2007 08:25:57 +0000 (08:25 +0000)]
GvSV(PL_errgv) is always non-NULL. That stopped being the case with
change 25009 (ish) - when we stopped automatically creating a(n unused)
SV at GV creation time.

p4raw-id: //depot/perl@31313

scope.c
t/op/local.t

diff --git a/scope.c b/scope.c
index 964a3b9..c9700b3 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -261,6 +261,14 @@ Perl_save_gp(pTHX_ GV *gv, I32 empty)
            gp->gp_io = newIO();
            IoFLAGS(gp->gp_io) |= IOf_ARGV|IOf_START;
        }
+#ifdef PERL_DONT_CREATE_GVSV
+       if (gv == PL_errgv) {
+           /* We could scatter this logic everywhere by changing the
+              definition of ERRSV from GvSV() to GvSVn(), but it seems more
+              efficient to do this check once here.  */
+           gp->gp_sv = newSV(0);
+       }
+#endif
        GvGP(gv) = gp;
     }
     else {
index e95615e..8bfea00 100755 (executable)
@@ -5,7 +5,7 @@ BEGIN {
     @INC = qw(. ../lib);
     require './test.pl';
 }
-plan tests => 120;
+plan tests => 122;
 
 my $list_assignment_supported = 1;
 
@@ -453,3 +453,12 @@ sub f { ok(0 == $[); }
     ok(! exists($h{'k2'}));
     is($h{'k1'},111);
 }
+
+# Keep this test last, as it can SEGV
+{
+    local *@;
+    pass("Localised *@");
+    eval {1};
+    pass("Can eval with *@ localised");
+}
+