summaryrefslogtreecommitdiff
path: root/pp_sort.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-06-27 14:37:14 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-07-25 23:48:01 -0700
commit2b66f6d3f8ed213b634d0aabd64c764198e14656 (patch)
tree90334c14e171b0d87b006475c07a1b061ad54427 /pp_sort.c
parentda9e430b54f7fcb43be1674882e31b92f2aa8253 (diff)
downloadperl-2b66f6d3f8ed213b634d0aabd64c764198e14656.tar.gz
[perl #78194] Make sort copy PADTMPs
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.
Diffstat (limited to 'pp_sort.c')
-rw-r--r--pp_sort.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/pp_sort.c b/pp_sort.c
index a67ad4e335..08aa2d5e46 100644
--- 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) {