This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #78194] Make sort copy PADTMPs
authorFather Chrysostomos <sprout@cpan.org>
Thu, 27 Jun 2013 21:37:14 +0000 (14:37 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 26 Jul 2013 06:48:01 +0000 (23:48 -0700)
Copy PADTMPs (op return values) when there is a sort block/sub that is
not optimised away and we are not sorting in place, so that \$a == \$a
will return true.

Many ops return the same scalar each time, for efficiency; refgen (\)
knows about that and copies them, to hide the implementation detail,
but other ops (sort in this case) need to do the same thing.

pp_sort.c
t/op/sort.t

index a67ad4e..08aa2d5 100644 (file)
--- a/pp_sort.c
+++ b/pp_sort.c
@@ -1483,6 +1483,7 @@ PP(pp_sort)
     OP* const nextop = PL_op->op_next;
     I32 overloading = 0;
     bool hasargs = FALSE;
+    bool copytmps;
     I32 is_xsub = 0;
     I32 sorting_av = 0;
     const U8 priv = PL_op->op_private;
@@ -1604,8 +1605,11 @@ PP(pp_sort)
     /* shuffle stack down, removing optional initial cv (p1!=p2), plus
      * any nulls; also stringify or converting to integer or number as
      * required any args */
+    copytmps = !sorting_av && PL_sortcop;
     for (i=max; i > 0 ; i--) {
        if ((*p1 = *p2++)) {                    /* Weed out nulls. */
+           if (copytmps && SvPADTMP(*p1) && !IS_PADGV(*p1))
+               *p1 = sv_mortalcopy(*p1);
            SvTEMP_off(*p1);
            if (!PL_sortcop) {
                if (priv & OPpSORT_NUMERIC) {
index 1461daf..9eb3525 100644 (file)
@@ -1008,7 +1008,6 @@ $#a = -1;
 () = [sort { $a = 10; $b = 10; 0 } $#a, $#a];
 is $#a, 10, 'sort block modifying $a and $b';
 
-$::TODO = ' ';
 () = sort {
     is \$a, \$a, '[perl #78194] op return values passed to sort'; 0
 } "${\''}", "${\''}";