summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2010-05-02 20:23:29 +0100
committerNicholas Clark <nick@ccl4.org>2010-05-02 20:23:29 +0100
commit61e5f455dc8214c9c23deb700f3fcf67b180afa5 (patch)
tree22b0dfab532bd36c00564e38b9415ed0e08bd456 /pp_hot.c
parent86e10ae19d90298873ec725d677f8d6e69375b31 (diff)
downloadperl-61e5f455dc8214c9c23deb700f3fcf67b180afa5.tar.gz
Better fix for RT #2140 (list assignment with duplicated temporaries)
4c8f17b905f2 (change 7867) took the approach of a special case in sv_setsv() when PL_op indicated that the current OP was OP_AASSIGN. The problem is in one part of pp_aassign, where it was using sv_mortalcopy() on values that were correctly marked as temporaries, but also still needed later. Hence a more targetted solution is to avoid that call, and to instead use API calls that will not steal temporaries.
Diffstat (limited to 'pp_hot.c')
-rw-r--r--pp_hot.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/pp_hot.c b/pp_hot.c
index aa038d3469..95a682270c 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1004,7 +1004,17 @@ PP(pp_aassign)
for (relem = firstrelem; relem <= lastrelem; relem++) {
if ((sv = *relem)) {
TAINT_NOT; /* Each item is independent */
- *relem = sv_mortalcopy(sv);
+
+ /* Dear TODO test in t/op/sort.t, I love you.
+ (It's relying on a panic, not a "semi-panic" from newSVsv()
+ and then an assertion failure below.) */
+ if (SvIS_FREED(sv)) {
+ Perl_croak(aTHX_ "panic: attempt to copy freed scalar %p",
+ (void*)sv);
+ }
+ /* Specifically *not* sv_mortalcopy(), as that will steal TEMPs,
+ and we need a second copy of a temp here. */
+ *relem = sv_2mortal(newSVsv(sv));
}
}
}