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