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