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