Stop newCONSTSUB from leaking the constant under fatal warnings
authorFather Chrysostomos <sprout@cpan.org>
Thu, 29 Nov 2012 21:07:02 +0000 (13:07 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 1 Dec 2012 02:02:35 +0000 (18:02 -0800)
op.c
t/op/svleak.t

index c95c8ea..18afb4b 100644 (file)
--- a/op.c
+++ b/op.c
@@ -7798,13 +7798,16 @@ Perl_newCONSTSUB_flags(pTHX_ HV *stash, const char *name, STRLEN len,
        PL_curstash = (HV *)SvREFCNT_inc_simple_NN(stash);
     }
 
+    /* Protect sv against leakage caused by fatal warnings. */
+    if (sv) SAVEFREESV(sv);
+
     /* file becomes the CvFILE. For an XS, it's usually static storage,
        and so doesn't get free()d.  (It's expected to be from the C pre-
        processor __FILE__ directive). But we need a dynamically allocated one,
        and we need it to get freed.  */
     cv = newXS_len_flags(name, len, const_sv_xsub, file ? file : "", "",
                         &sv, XS_DYNAMIC_FILENAME | flags);
-    CvXSUBANY(cv).any_ptr = sv;
+    CvXSUBANY(cv).any_ptr = SvREFCNT_inc_simple(sv);
     CvCONST_on(cv);
 
     LEAVE;
index a3c14b8..dfce9f2 100644 (file)
@@ -91,9 +91,9 @@ eleak(2, 0, "$all *x=sub {}",
      'fatal sub redef warning with sub-to-glob assignment');
 eleak(2, 0, "$all *x=sub() {1}",
      'fatal const sub redef warning with sub-to-glob assignment');
-$::TODO = 'still leaks';
 eleak(2, 0, "$all XS::APItest::newCONSTSUB(\\%main::=>name=>0=>1)",
-     'newXS sub redefinition with fatal warnings');
+     'newCONSTSUB sub redefinition with fatal warnings');
+$::TODO = 'still leaks';
 eleak(2, 0, "$f 'misc'; my\$a,my\$a", 'double my with fatal warnings');
 eleak(2, 0, "$f 'misc'; our\$a,our\$a", 'double our with fatal warnings');
 eleak(2, 0, "$f 'closure';