dcb3b7
From 59ef97c7af81ab6faba749d88b558a55da41c249 Mon Sep 17 00:00:00 2001
dcb3b7
From: Zefram <zefram@fysh.org>
dcb3b7
Date: Sun, 22 Jan 2017 07:26:34 +0000
dcb3b7
Subject: [PATCH] fix special-case recreation of *::
dcb3b7
MIME-Version: 1.0
dcb3b7
Content-Type: text/plain; charset=UTF-8
dcb3b7
Content-Transfer-Encoding: 8bit
dcb3b7
dcb3b7
Ported to 5.24.1:
dcb3b7
dcb3b7
commit 120921acd4cf27bb932a725a8cf5c957652b22eb
dcb3b7
Author: Zefram <zefram@fysh.org>
dcb3b7
Date:   Sun Jan 22 07:26:34 2017 +0000
dcb3b7
dcb3b7
    fix special-case recreation of *::
dcb3b7
dcb3b7
    If *:: is called for then as a special case it is looked up as
dcb3b7
    $::{"main::"}.  If $::{"main::"} has been deleted, then that hash entry
dcb3b7
    is recreated.  But formerly it was only recreated as an undef scalar,
dcb3b7
    which broke things relying on glob lookup returning a glob.  Now in
dcb3b7
    that special case the recreated hash entry is initialised as a glob,
dcb3b7
    and populated with the customary recursive reference to the main stash.
dcb3b7
    Fixes [perl #129869].
dcb3b7
dcb3b7
Signed-off-by: Petr Písař <ppisar@redhat.com>
dcb3b7
---
dcb3b7
 gv.c         | 11 +++++++++--
dcb3b7
 t/op/stash.t |  9 ++++++++-
dcb3b7
 2 files changed, 17 insertions(+), 3 deletions(-)
dcb3b7
dcb3b7
diff --git a/gv.c b/gv.c
dcb3b7
index c89a3e7..3fda9b9 100644
dcb3b7
--- a/gv.c
dcb3b7
+++ b/gv.c
dcb3b7
@@ -1642,8 +1642,15 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name,
dcb3b7
                 name_cursor++;
dcb3b7
             *name = name_cursor+1;
dcb3b7
             if (*name == name_end) {
dcb3b7
-                if (!*gv)
dcb3b7
-                    *gv = MUTABLE_GV(*hv_fetchs(PL_defstash, "main::", TRUE));
dcb3b7
+                if (!*gv) {
dcb3b7
+		    *gv = MUTABLE_GV(*hv_fetchs(PL_defstash, "main::", TRUE));
dcb3b7
+		    if (SvTYPE(*gv) != SVt_PVGV) {
dcb3b7
+			gv_init_pvn(*gv, PL_defstash, "main::", 6,
dcb3b7
+				    GV_ADDMULTI);
dcb3b7
+			GvHV(*gv) =
dcb3b7
+			    MUTABLE_HV(SvREFCNT_inc_simple(PL_defstash));
dcb3b7
+		    }
dcb3b7
+		}
dcb3b7
                 return TRUE;
dcb3b7
             }
dcb3b7
         }
dcb3b7
diff --git a/t/op/stash.t b/t/op/stash.t
dcb3b7
index 7ac379b..d6fded4 100644
dcb3b7
--- a/t/op/stash.t
dcb3b7
+++ b/t/op/stash.t
dcb3b7
@@ -7,7 +7,7 @@ BEGIN {
dcb3b7
 
dcb3b7
 BEGIN { require "./test.pl"; }
dcb3b7
 
dcb3b7
-plan( tests => 54 );
dcb3b7
+plan( tests => 55 );
dcb3b7
 
dcb3b7
 # Used to segfault (bug #15479)
dcb3b7
 fresh_perl_like(
dcb3b7
@@ -355,3 +355,10 @@ is runperl(
dcb3b7
    ),
dcb3b7
    "ok\n",
dcb3b7
    "[perl #128238] non-stashes in stashes";
dcb3b7
+
dcb3b7
+is runperl(
dcb3b7
+    prog => '%:: = (); print *{q|::|}, qq|\n|',
dcb3b7
+    stderr => 1,
dcb3b7
+   ),
dcb3b7
+   "*main::main::\n",
dcb3b7
+   "[perl #129869] lookup %:: by name after clearing %::";
dcb3b7
-- 
dcb3b7
2.7.4
dcb3b7