[perl #81944] Non-lvalue subs do not copy return values
authorFather Chrysostomos <sprout@cpan.org>
Thu, 16 Jun 2011 13:27:50 +0000 (06:27 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 17 Jun 2011 03:17:52 +0000 (20:17 -0700)
commit3ed94dc04bd73c956fbfa66348a55f94c8a2268b
tree0b97f0066f7f723345414b177a96044984551633
parentad37a74e7dc5e204efc84791373a791f142ac7b4
[perl #81944] Non-lvalue subs do not copy return values

return and leavesub see if they can cheat by not copying anything
marked TEMP, since presumably nothing else is using it.  That means
the return values of delete() and shift() are not copied.  Since @_
aliases to the caller’s variables, sometimes what is returned *is*
used elsewhere and still marked TEMP.  So cases like sub { return
delete $_[0] } ->($x) end up returning $x unchanged, instead of
copying it.

As mentioned in the ticket, the solution is to copy only if the refer-
ence count is 1.

This also allows me to simplify the lvalue-returning code without
spreading this bug further.  (pp_leavesublv currently avoids calling
sv_2mortal, in order not to set the TEMP flag.)
pp_ctl.c
pp_hot.c
t/op/sub.t