This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #114764] Stop my vars with attrs from leaking
authorFather Chrysostomos <sprout@cpan.org>
Thu, 20 Sep 2012 04:53:51 +0000 (21:53 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 20 Sep 2012 04:53:51 +0000 (21:53 -0700)
S_apply_attrs was creating a SV containing a stash name, that was
later to be put in a const op, which would take care of freeing it.
But it didn’t free it for a my variable, because the branch where that
const op was created didn’t apply.  So move the creation of that SV
inside the branch that uses it, otherwise it leaks.  This leak was the
result of commit 95f0a2f1ffc6.

op.c
t/op/svleak.t

diff --git a/op.c b/op.c
index 5d81504..9a2f917 100644 (file)
--- a/op.c
+++ b/op.c
@@ -2453,13 +2453,11 @@ STATIC void
 S_apply_attrs(pTHX_ HV *stash, SV *target, OP *attrs, bool for_my)
 {
     dVAR;
-    SV *stashsv;
 
     PERL_ARGS_ASSERT_APPLY_ATTRS;
 
     /* fake up C<use attributes $pkg,$rv,@attrs> */
     ENTER;             /* need to protect against side-effects of 'use' */
-    stashsv = stash ? newSVhek(HvNAME_HEK(stash)) : &PL_sv_no;
 
 #define ATTRSMODULE "attributes"
 #define ATTRSMODULE_PM "attributes.pm"
@@ -2474,6 +2472,8 @@ S_apply_attrs(pTHX_ HV *stash, SV *target, OP *attrs, bool for_my)
                             newSVpvs(ATTRSMODULE), NULL);
     }
     else {
+       SV * const stashsv =
+           stash ? newSVhek(HvNAME_HEK(stash)) : &PL_sv_no;
        Perl_load_module(aTHX_ PERL_LOADMOD_IMPORT_OPS,
                         newSVpvs(ATTRSMODULE),
                         NULL,
index b588ffc..e6636b8 100644 (file)
@@ -15,7 +15,7 @@ BEGIN {
 
 use Config;
 
-plan tests => 27;
+plan tests => 28;
 
 # run some code N times. If the number of SVs at the end of loop N is
 # greater than (N-1)*delta at the end of loop 1, we've got a leak
@@ -183,3 +183,6 @@ SKIP: {
     leak(2, 0, sub { eval 'tr/9-0//' }, 'tr/9-0//');
     leak(2, 0, sub { eval 'tr/a-z-0//' }, 'tr/a-z-0//');
 }
+
+# [perl #114764] Attributes leak scalars
+leak(2, 0, sub { eval 'my $x : shared' }, 'my $x :shared used to leak');