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