diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-06-16 06:02:23 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-06-16 20:17:52 -0700 |
commit | ad37a74e7dc5e204efc84791373a791f142ac7b4 (patch) | |
tree | 26f705e25b49e91c10c0ca0dff9b7c8368c0d041 | |
parent | 7393165ef277e989fdf63df19ea17698bf83d8db (diff) | |
download | perl-ad37a74e7dc5e204efc84791373a791f142ac7b4.tar.gz |
Stop lvalue subs from copying read-only scalars
They were only doing so in reference context (subroutine args,
for(...)).
Explicit return already worked, but only because I didn’t write it
well. I’m in the process of trying to merge the two.
-rw-r--r-- | pp_hot.c | 4 | ||||
-rw-r--r-- | t/op/sub_lval.t | 13 |
2 files changed, 13 insertions, 4 deletions
@@ -2693,9 +2693,7 @@ PP(pp_leavesublv) for (mark = newsp + 1; mark <= SP; mark++) { if (SvTEMP(*mark)) NOOP; - else if (SvFLAGS(*mark) & SVs_PADTMP - || (SvFLAGS(*mark) & (SVf_READONLY|SVf_FAKE)) - == SVf_READONLY) + else if (SvFLAGS(*mark) & SVs_PADTMP) *mark = sv_mortalcopy(*mark); else { /* Can be a localized value subject to deletion. */ diff --git a/t/op/sub_lval.t b/t/op/sub_lval.t index 321f5461f2..e4518ffbc9 100644 --- a/t/op/sub_lval.t +++ b/t/op/sub_lval.t @@ -3,7 +3,7 @@ BEGIN { @INC = '../lib'; require './test.pl'; } -plan tests=>156; +plan tests=>158; sub a : lvalue { my $a = 34; ${\(bless \$a)} } # Return a temporary sub b : lvalue { ${\shift} } @@ -802,3 +802,14 @@ for my $sub ( is +(&$sub)[0], 72, "sub returning pad var in list context$suffix"; } continue { $suffix = ' (explicit return)' } + +# Returning read-only values in reference context +$suffix = ''; +for ( + sub :lvalue { $] }->(), + sub :lvalue { return $] }->() +) { + is \$_, \$], 'read-only values are returned in reference context' + .$suffix # (they used to be copied) +} +continue { $suffix = ' (explicit return)' } |