This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Stop array assignment from leaking on croak
authorFather Chrysostomos <sprout@cpan.org>
Sat, 22 Sep 2012 19:06:45 +0000 (12:06 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 23 Sep 2012 00:10:43 +0000 (17:10 -0700)
This made a to-do test in sort.t pass, but adventitiously, so I modi-
fied it to fail again.

pp_hot.c
t/op/sort.t
t/op/svleak.t

index 6057614..a8d762b 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -982,15 +982,14 @@ PP(pp_aassign)
            while (relem <= lastrelem) {        /* gobble up all the rest */
                SV **didstore;
                assert(*relem);
-               sv = newSV(0);
+               sv = sv_newmortal();
                sv_setsv(sv, *relem);
                *(relem++) = sv;
                didstore = av_store(ary,i++,sv);
+               if (didstore) SvREFCNT_inc_simple_void_NN(sv);
                if (magic) {
                    if (SvSMAGICAL(sv))
                        mg_set(sv);
-                   if (!didstore)
-                       sv_2mortal(sv);
                }
                TAINT_NOT;
            }
index 6dedeeb..0371f4f 100644 (file)
@@ -770,7 +770,8 @@ cmp_ok($answer,'eq','good','sort subr called from other package');
 
 {
     local $TODO = "sort should make sure elements are not freed in the sort block";
-    eval { @nomodify_x=(1..8); our @copy = sort { @nomodify_x = (0) } (@nomodify_x, 3); };
+    eval { @nomodify_x=(1..8);
+          our @copy = sort { undef @nomodify_x; 1 } (@nomodify_x, 3); };
     is($@, "");
 }
 
index 6ed0408..d975cf1 100644 (file)
@@ -15,7 +15,7 @@ BEGIN {
 
 use Config;
 
-plan tests => 30;
+plan tests => 31;
 
 # 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
@@ -200,7 +200,8 @@ leak(2, 0, sub {
     undef $h;
 }, 'tied hash iteration does not leak');
 
-# Hash assignment was leaking when assigning explosive scalars
+# List assignment was leaking when assigning explosive scalars to
+# aggregates.
 package sty {
     sub TIESCALAR { bless [] }
     sub FETCH    { die }
@@ -211,4 +212,8 @@ leak(2, 0, sub {
     eval {%a = (0, $x)}; # value
     eval {%a = ($x,$x)}; # both
 }, 'hash assignment does not leak');
+leak(2, 0, sub {
+    tie my $x, sty;
+    eval {@a = ($x)};
+}, 'array assignment does not leak');