Stop sub decl redef warnings from leaking CVs
authorFather Chrysostomos <sprout@cpan.org>
Sat, 24 Nov 2012 08:31:01 +0000 (00:31 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 24 Nov 2012 15:35:52 +0000 (07:35 -0800)
When newMYSUB and newATTRSUB are called, PL_compcv has an unclaimed
reference count, so any code that croaks must decrement the reference
count or make arrangements for such to happen.

This commit applies only to redefinition warnings triggered by sub
declarations, like ‘sub foo {}’ and ‘my sub foo {}’.

op.c
t/op/svleak.t

diff --git a/op.c b/op.c
index addf04b..8efc898 100644 (file)
--- a/op.c
+++ b/op.c
@@ -6954,7 +6954,10 @@ S_already_defined(pTHX_ CV *const cv, OP * const block, OP * const o,
             /* This ensures that warnings are reported at the first
                line of a redefinition, not the last.  */
            CopLINE_set(PL_curcop, PL_parser->copline);
+       /* protect against fatal warnings leaking compcv */
+       SAVEFREESV(PL_compcv);
        report_redefined_cv(namesv, cv, const_svp);
+       SvREFCNT_inc_simple_void_NN(PL_compcv);
        CopLINE_set(PL_curcop, oldline);
     }
 #ifdef PERL_MAD
index dee80ac..e3f6be4 100644 (file)
@@ -83,11 +83,11 @@ eleak(2, 0, "$f 'misc'; sub foo{} sub foo:lvalue",
 eleak(2, 0, "no warnings; use feature ':all'; $f 'misc';
              my sub foo{} sub foo:lvalue",
      'ignored mysub :lvalue with fatal warnings');
-$::TODO = 'still leaks';
 eleak(2, 0, "no warnings; use feature ':all'; $all
              my sub foo{} sub foo:lvalue{}",
      'fatal mysub redef warning');
 eleak(2, 0, "$all sub foo{} sub foo{}", 'fatal sub redef warning');
+$::TODO = 'still leaks';
 eleak(2, 0, "$all *x=sub {}",
      'fatal sub redef warning with sub-to-glob assignment');
 eleak(2, 0, "$all *x=sub() {1}",