Stop "\N{...}" from leaking after errors
authorFather Chrysostomos <sprout@cpan.org>
Wed, 5 Dec 2012 07:13:56 +0000 (23:13 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Wed, 5 Dec 2012 17:36:10 +0000 (09:36 -0800)
After a syntax error, S_new_constant in toke.c was not mortalising as
promised.

In this case, it doesn’t need to mortalise the variable.  It can sim-
ply free it.

t/op/svleak.t
toke.c

index 3c15119..75067b1 100644 (file)
@@ -15,7 +15,7 @@ BEGIN {
 
 use Config;
 
 
 use Config;
 
-plan tests => 107;
+plan tests => 108;
 
 # 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
 
 # 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
@@ -270,6 +270,7 @@ eleak(2, 0, 'no warnings; 2 2;BEGIN{}',
 }
 eleak(2, 0, "\"\$\0\356\"", 'qq containing $ <null> something');
 eleak(2, 0, 'END OF TERMS AND CONDITIONS', 'END followed by words');
 }
 eleak(2, 0, "\"\$\0\356\"", 'qq containing $ <null> something');
 eleak(2, 0, 'END OF TERMS AND CONDITIONS', 'END followed by words');
+eleak(2, 0, "+ + +;qq|\\N{a}|"x10,'qq"\N{a}" after errors');
 eleak(2, 0, "qq|\\c|;"x10,     '"too many errors" from qq"\c"');
 $::TODO = 'still leaks';
 eleak(2, 0, "qq|\\N{%}|"x10,   '"too many errors" from qq"\N{%}"');
 eleak(2, 0, "qq|\\c|;"x10,     '"too many errors" from qq"\c"');
 $::TODO = 'still leaks';
 eleak(2, 0, "qq|\\N{%}|"x10,   '"too many errors" from qq"\N{%}"');
diff --git a/toke.c b/toke.c
index df3e9a8..86bb994 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -9011,7 +9011,7 @@ S_checkcomma(pTHX_ const char *s, const char *name, const char *what)
     }
 }
 
     }
 }
 
-/* Either returns sv, or mortalizes sv and returns a new SV*.
+/* Either returns sv, or mortalizes/frees sv and returns a new SV*.
    Best used as sv=new_constant(..., sv, ...).
    If s, pv are NULL, calls subroutine with one argument,
    and <type> is used with error messages only.
    Best used as sv=new_constant(..., sv, ...).
    If s, pv are NULL, calls subroutine with one argument,
    and <type> is used with error messages only.
@@ -9033,7 +9033,10 @@ S_new_constant(pTHX_ const char *s, STRLEN len, const char *key, STRLEN keylen,
 
     /* charnames doesn't work well if there have been errors found */
     if (PL_error_count > 0 && strEQ(key,"charnames"))
 
     /* charnames doesn't work well if there have been errors found */
     if (PL_error_count > 0 && strEQ(key,"charnames"))
+    {
+       SvREFCNT_dec_NN(sv);
        return &PL_sv_undef;
        return &PL_sv_undef;
+    }
 
     if (!table
        || ! (PL_hints & HINT_LOCALIZE_HH)
 
     if (!table
        || ! (PL_hints & HINT_LOCALIZE_HH)