Fix assertion failures with anon subs
authorFather Chrysostomos <sprout@cpan.org>
Tue, 13 Nov 2012 22:52:09 +0000 (14:52 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 13 Nov 2012 22:54:21 +0000 (14:54 -0800)
In commit 9ffcdca1f50, I did not take into account that the newATTRSUB’s
caller makes sure that the CV is freed if it is an anonymous sub.  So I
only needed to free the sub explicitly after a syntax error for a named
sub.

By returning 0 for anonymous subs as well, I ended up causing assertion
failures.  Why I wasn’t getting them before I don’t know, as I was using
a debugging build.

op.c
t/op/svleak.t

index b2801c7..d7bf037 100644 (file)
--- a/op.c
+++ b/op.c
@@ -4650,7 +4650,7 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, bool isreg, I32 floor)
 
                /* attach the anon CV to the pad so that
                 * pad_fixup_inner_anons() can find it */
-               if (cv) (void)pad_add_anon(cv, o->op_type);
+               (void)pad_add_anon(cv, o->op_type);
                SvREFCNT_inc_simple_void(cv);
            }
            else {
@@ -7370,7 +7370,8 @@ Perl_newATTRSUB_flags(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs,
 
     if (ec) {
        op_free(block);
-       SvREFCNT_dec(PL_compcv);
+       if (name) SvREFCNT_dec(PL_compcv);
+       else cv = PL_compcv;
        PL_compcv = 0;
        if (name && block) {
            const char *s = strrchr(name, ':');
@@ -8175,9 +8176,6 @@ Perl_ck_anoncode(pTHX_ OP *o)
 {
     PERL_ARGS_ASSERT_CK_ANONCODE;
 
-    /* After errors, we won’t have any sub. */
-    if (!cSVOPo->op_sv) return o;
-
     cSVOPo->op_targ = pad_add_anon((CV*)cSVOPo->op_sv, o->op_type);
     if (!PL_madskills)
        cSVOPo->op_sv = NULL;
index b89d6d0..95e1a3a 100644 (file)
@@ -15,7 +15,7 @@ BEGIN {
 
 use Config;
 
-plan tests => 66;
+plan tests => 67;
 
 # 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
@@ -197,6 +197,7 @@ SKIP: {
 
 eleak(2, 0, '+sub:a{}', 'anon subs with invalid attributes');
 eleak(2, 0, 'no warnings; sub a{1 1}', 'sub with syntax error');
+eleak(2, 0, 'no warnings; sub {1 1}', 'anon sub with syntax error');
 
 # Syntax errors
 eleak(2, 0, '"${<<END}"