292b33
From 13f27cb3dee86772eeed5d7d9b47746395ee603c Mon Sep 17 00:00:00 2001
292b33
From: Father Chrysostomos <sprout@cpan.org>
292b33
Date: Wed, 19 Sep 2012 21:53:51 -0700
292b33
Subject: [PATCH] Stop my vars with attrs from leaking
292b33
MIME-Version: 1.0
292b33
Content-Type: text/plain; charset=UTF-8
292b33
Content-Transfer-Encoding: 8bit
292b33
292b33
Ported to 5.16.1:
292b33
292b33
commit 9fa29fa7929b4167c5491b792c5cc7e4365a2839
292b33
Author: Father Chrysostomos <sprout@cpan.org>
292b33
Date:   Wed Sep 19 21:53:51 2012 -0700
292b33
292b33
    [perl #114764] Stop my vars with attrs from leaking
292b33
292b33
S_apply_attrs was creating a SV containing a stash name, that was
292b33
later to be put in a const op, which would take care of freeing it.
292b33
But it didn’t free it for a my variable, because the branch where that
292b33
const op was created didn’t apply.  So move the creation of that SV
292b33
inside the branch that uses it, otherwise it leaks.  This leak was the
292b33
result of commit 95f0a2f1ffc6.
292b33
---
292b33
 op.c          | 4 ++--
292b33
 t/op/svleak.t | 5 ++++-
292b33
 2 files changed, 6 insertions(+), 3 deletions(-)
292b33
292b33
diff --git a/op.c b/op.c
292b33
index 24d5ecb..017580d 100644
292b33
--- a/op.c
292b33
+++ b/op.c
292b33
@@ -2279,13 +2279,11 @@ STATIC void
292b33
 S_apply_attrs(pTHX_ HV *stash, SV *target, OP *attrs, bool for_my)
292b33
 {
292b33
     dVAR;
292b33
-    SV *stashsv;
292b33
 
292b33
     PERL_ARGS_ASSERT_APPLY_ATTRS;
292b33
 
292b33
     /* fake up C<use attributes $pkg,$rv,@attrs> */
292b33
     ENTER;		/* need to protect against side-effects of 'use' */
292b33
-    stashsv = stash ? newSVhek(HvNAME_HEK(stash)) : &PL_sv_no;
292b33
 
292b33
 #define ATTRSMODULE "attributes"
292b33
 #define ATTRSMODULE_PM "attributes.pm"
292b33
@@ -2300,6 +2298,8 @@ S_apply_attrs(pTHX_ HV *stash, SV *target, OP *attrs, bool for_my)
292b33
 			     newSVpvs(ATTRSMODULE), NULL);
292b33
     }
292b33
     else {
292b33
+	SV * const stashsv =
292b33
+	    stash ? newSVhek(HvNAME_HEK(stash)) : &PL_sv_no;
292b33
 	Perl_load_module(aTHX_ PERL_LOADMOD_IMPORT_OPS,
292b33
 			 newSVpvs(ATTRSMODULE),
292b33
 			 NULL,
292b33
diff --git a/t/op/svleak.t b/t/op/svleak.t
292b33
index df10953..6cfee2e 100644
292b33
--- a/t/op/svleak.t
292b33
+++ b/t/op/svleak.t
292b33
@@ -13,7 +13,7 @@ BEGIN {
292b33
 	or skip_all("XS::APItest not available");
292b33
 }
292b33
 
292b33
-plan tests => 21;
292b33
+plan tests => 22;
292b33
 
292b33
 # run some code N times. If the number of SVs at the end of loop N is
292b33
 # greater than (N-1)*delta at the end of loop 1, we've got a leak
292b33
@@ -160,3 +160,6 @@ leak(2, 0,
292b33
 }
292b33
 
292b33
 leak(2,0,sub { !$^V }, '[perl #109762] version object in boolean context');
292b33
+
292b33
+# [perl #114764] Attributes leak scalars
292b33
+leak(2, 0, sub { eval 'my $x : shared' }, 'my $x :shared used to leak');
292b33
-- 
292b33
1.7.11.4
292b33