diff options
author | Nicholas Clark <nick@ccl4.org> | 2010-05-02 20:23:29 +0100 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2010-05-02 20:23:29 +0100 |
commit | 61e5f455dc8214c9c23deb700f3fcf67b180afa5 (patch) | |
tree | 22b0dfab532bd36c00564e38b9415ed0e08bd456 /pp_hot.c | |
parent | 86e10ae19d90298873ec725d677f8d6e69375b31 (diff) | |
download | perl-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.c | 12 |
1 files changed, 11 insertions, 1 deletions
@@ -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)); } } } |