78f1eb
From 40258daf9899686d934c460ba3630431312d7694 Mon Sep 17 00:00:00 2001
78f1eb
From: Tony Cook <tony@develop-help.com>
78f1eb
Date: Wed, 15 May 2019 15:59:49 +1000
78f1eb
Subject: [PATCH] (perl #134072) allow \&foo = \&bar to work in main::
78f1eb
MIME-Version: 1.0
78f1eb
Content-Type: text/plain; charset=UTF-8
78f1eb
Content-Transfer-Encoding: 8bit
78f1eb
78f1eb
subs in main:: are stored as a RV referring to a CV as a space
78f1eb
optimization, but the pp_refassign code expected to find a glob,
78f1eb
which made the assignment a no-op.
78f1eb
78f1eb
Fix this by upgrading the reference to a glob in the refassign check
78f1eb
function.
78f1eb
78f1eb
Note that this would be an issue in other packages if 1e2cfe157ca
78f1eb
was reverted (allowing the space savings in other packages too.)
78f1eb
78f1eb
Signed-off-by: Petr Písař <ppisar@redhat.com>
78f1eb
---
78f1eb
 op.c         |  9 +++++++++
78f1eb
 t/op/lvref.t | 15 ++++++++++++++-
78f1eb
 2 files changed, 23 insertions(+), 1 deletion(-)
78f1eb
78f1eb
diff --git a/op.c b/op.c
78f1eb
index f63eeadc36..6ad192307f 100644
78f1eb
--- a/op.c
78f1eb
+++ b/op.c
78f1eb
@@ -12462,7 +12462,16 @@ Perl_ck_refassign(pTHX_ OP *o)
78f1eb
 	OP * const kid = cUNOPx(kidparent)->op_first;
78f1eb
 	o->op_private |= OPpLVREF_CV;
78f1eb
 	if (kid->op_type == OP_GV) {
78f1eb
+            SV *sv = (SV*)cGVOPx_gv(kid);
78f1eb
 	    varop = kidparent;
78f1eb
+            if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVCV) {
78f1eb
+                /* a CVREF here confuses pp_refassign, so make sure
78f1eb
+                   it gets a GV */
78f1eb
+                CV *const cv = (CV*)SvRV(sv);
78f1eb
+                SV *name_sv = sv_2mortal(newSVhek(CvNAME_HEK(cv)));
78f1eb
+                (void)gv_init_sv((GV*)sv, CvSTASH(cv), name_sv, 0);
78f1eb
+                assert(SvTYPE(sv) == SVt_PVGV);
78f1eb
+            }
78f1eb
 	    goto detach_and_stack;
78f1eb
 	}
78f1eb
 	if (kid->op_type != OP_PADCV)	goto bad;
78f1eb
diff --git a/t/op/lvref.t b/t/op/lvref.t
78f1eb
index 3d5e952fb0..3991a53780 100644
78f1eb
--- a/t/op/lvref.t
78f1eb
+++ b/t/op/lvref.t
78f1eb
@@ -1,10 +1,11 @@
78f1eb
+#!perl
78f1eb
 BEGIN {
78f1eb
     chdir 't';
78f1eb
     require './test.pl';
78f1eb
     set_up_inc("../lib");
78f1eb
 }
78f1eb
 
78f1eb
-plan 164;
78f1eb
+plan 167;
78f1eb
 
78f1eb
 eval '\$x = \$y';
78f1eb
 like $@, qr/^Experimental aliasing via reference not enabled/,
78f1eb
@@ -291,6 +292,18 @@ package CodeTest {
78f1eb
   my sub bs;
78f1eb
   \(&cs) = expect_list_cx;
78f1eb
   is \&cs, \&ThatSub, '\(&statesub)';
78f1eb
+
78f1eb
+  package main {
78f1eb
+    # this is only a problem in main:: due to 1e2cfe157ca
78f1eb
+    sub sx { "x" }
78f1eb
+    sub sy { "y" }
78f1eb
+    is sx(), "x", "check original";
78f1eb
+    my $temp = \&sx;
78f1eb
+    \&sx = \&sy;
78f1eb
+    is sx(), "y", "aliased";
78f1eb
+    \&sx = $temp;
78f1eb
+    is sx(), "x", "and restored";
78f1eb
+  }
78f1eb
 }
78f1eb
 
78f1eb
 # Mixed List Assignments
78f1eb
-- 
78f1eb
2.20.1
78f1eb