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